aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--emulab_support.py224
-rwxr-xr-x[-rw-r--r--]example.py18
-rw-r--r--jfed_support.py134
-rwxr-xr-xrhumba.py48
-rw-r--r--rhumba_emulab.py246
-rw-r--r--rhumba_faketestbed.py31
-rw-r--r--rhumba_jfed.py149
7 files changed, 439 insertions, 411 deletions
diff --git a/emulab_support.py b/emulab_support.py
deleted file mode 100644
index 99a903c..0000000
--- a/emulab_support.py
+++ /dev/null
@@ -1,224 +0,0 @@
-#
-# Emulab support for Rhumba
-#
-# Sander Vrijders <sander.vrijders@intec.ugent.be>
-# Wouter Tavernier <wouter.tavernier@intec.ugent.be>
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301 USA
-
-import os
-import time
-import re
-from ast import literal_eval
-from ssh_support import *
-
-import warnings
-warnings.filterwarnings("ignore")
-
-def ops_server(testbed):
- '''
- Return server name of the ops-server (is testbed specific)
-
- @param testbed: testbed info
-
- @return: server name of the ops-server
- '''
- return 'ops.' + testbed.url
-
-def full_name(testbed, node_name):
- '''
- Return server name of a node
-
- @param node_name: name of the node
- @param testbed: testbed info
-
- @return: server name of the node
- '''
- return node_name + '.' + testbed.exp_name + '.' + \
- testbed.proj_name + '.' + testbed.url
-
-
-def get_experiment_list(testbed, project_name = None):
- '''
- Get list of made emulab experiments accessible with your credentials
-
- @param testbed: testbed info
- @param project_name: optional filter on project
-
- @return: list of created experiments (strings)
- '''
- cmd = '/usr/testbed/bin/sslxmlrpc_client.py -m experiment getlist'
- out = execute_command(testbed, ops_server(testbed), cmd)
-
- try:
- if project_name != None:
- return literal_eval(out)[project_name][project_name]
- else:
- return literal_eval(out)
- except:
- return { project_name: { project_name: [] }}
-
-def swap_exp_in(testbed):
- '''
- Swaps experiment in
-
- @param testbed: testbed info
- '''
- cmd = '/usr/testbed/bin/sslxmlrpc_client.py swapexp proj=' + \
- testbed.proj_name + \
- ' exp=' + \
- testbed.exp_name + \
- ' direction=in'
-
- output = execute_command(testbed, ops_server(testbed), cmd)
-
- return output
-
-def create_experiment(testbed, nodes, links):
- '''
- Creates an emulab experiment
-
- @param testbed: testbed info
- @param nodes: holds the nodes in the experiment
- @param links: holds the links in the experiment
- '''
- proj_name = testbed.proj_name
- exp_name = testbed.exp_name
-
- exp_list = get_experiment_list(testbed)
-
- try:
- if exp_name in exp_list[proj_name][proj_name]:
- print("Experiment already exists.")
- return
- except:
- print("First experiment to be created for that project.")
-
- ns = generate_ns_script(testbed, nodes, links)
- dest_file_name = '/users/'+ testbed.username + \
- '/temp_ns_file.%s.ns' % os.getpid()
- copy_file_to_testbed(testbed, ops_server(testbed), ns, dest_file_name)
-
- cmd = '/usr/testbed/bin/sslxmlrpc_client.py startexp ' + \
- 'batch=false wait=true proj="' + proj_name + \
- '" exp="' + exp_name + '" noswapin=true ' + \
- 'nsfilepath="' + dest_file_name + '"'
-
- execute_command(testbed, ops_server(testbed), cmd, time_out = None)
- execute_command(testbed, ops_server(testbed),'rm ' + dest_file_name)
- print("New experiment succesfully created.")
-
-def generate_ns_script(testbed, nodes, p2plinks):
- '''
- Generate ns script based on network graph.
- Enables to customize default node image.
-
- @param nodes: holds the nodes in the experiment
- @param links: holds the links in the experiment
- @param testbed: testbed info
-
- @return: ns2 script for Emulab experiment
- '''
-
- ns2_script = "# ns script generated by Rhumba\n"
- ns2_script += "set ns [new Simulator]\n"
- ns2_script += "source tb_compat.tcl\n"
-
- for node in nodes:
- ns2_script += "set " + node.name + " [$ns node]\n"
- ns2_script += "tb-set-node-os $" + node.name + " " + \
- testbed.image + "\n"
-
- for link in p2plinks:
- ns2_script += "set " + link.name + \
- " [$ns duplex-link $" + \
- link.node_a.name + " $" + \
- link.node_b.name + " 1000Mb 0ms DropTail]\n"
-
- ns2_script += "$ns run\n"
-
- return ns2_script
-
-def wait_until_nodes_up(testbed):
- '''
- Checks if nodes are up
-
- @param testbed: testbed info
- '''
- print("Waiting until all nodes are up")
-
- cmd = '/usr/testbed/bin/script_wrapper.py expinfo -e' + \
- testbed.proj_name + \
- ',' + \
- testbed.exp_name + \
- ' -a | grep State | cut -f2,2 -d " "'
-
- res = execute_command(testbed, ops_server(testbed), cmd)
- active = False
- if res == "active":
- active = True
- while active != True:
- res = execute_command(testbed, ops_server(testbed), cmd)
- if res == "active":
- active = True
- print("Still waiting")
- time.sleep(5)
-
-def complete_experiment_graph(testbed, nodes, p2plinks):
- '''
- Gets the interface (ethx) to link mapping
-
- @param testbed: testbed info
- @param nodes: holds the nodes in the experiment
- @param links: holds the links in the experiment
- '''
-
- node_full_name = full_name(testbed, nodes[0].name)
- cmd = 'cat /var/emulab/boot/topomap'
- topomap = execute_command(testbed, node_full_name, cmd)
- # Almost as ugly as yo momma
- index = topomap.rfind("# lans")
- topo_array = topomap[:index].split('\\n')[1:-1]
- # Array contains things like 'r2b1,link7:10.1.6.3 link6:10.1.5.3'
- for item in topo_array:
- item_array = re.split(',? ?', item)
- node_name = item_array[0]
- for item2 in item_array[1:]:
- item2 = item2.split(':')
- link_name = item2[0]
- link_ip = item2[1]
- for link in p2plinks:
- if link.name == link_name:
- if link.node_a.name == node_name:
- link.int_a.ip = link_ip
- elif link.node_b.name == node_name:
- link.int_b.ip = link_ip
-
- for node in nodes:
- cmd = 'cat /var/emulab/boot/ifmap'
- node_full_name = full_name(testbed, node.name)
- output = execute_command(testbed, node_full_name, cmd)
- output = re.split('\\\\n', output)
- for item in output:
- item = item.split()
- for link in p2plinks:
- if link.node_a.name == node.name and \
- link.int_a.ip == item[1]:
- link.int_a.name = item[0]
- elif link.node_b.name == node.name and \
- link.int_b.ip == item[1]:
- link.int_b.name = item[0]
- node.full_name = full_name(testbed, node.name)
diff --git a/example.py b/example.py
index 6013173..b13f0ce 100644..100755
--- a/example.py
+++ b/example.py
@@ -3,6 +3,13 @@
# An example script using rhumba.py
from rhumba import *
+
+# import testbed plugins
+import rhumba_emulab as emulab
+import rhumba_jfed as jfed
+import rhumba_faketestbed as fake
+
+# import prototype plugins
import rhumba_ouroboros as our
import rhumba_rlite as rl
import rhumba_irati as irati
@@ -22,12 +29,13 @@ b = Node("b",
difs = [e1, n1],
dif_registrations = {n1 : [e1]})
-tb = jFedTestbed(exp_name = "letest",
- username = "sander",
- cert_file = "cert.pem",
- jfed_jar = "jfed_cli/experimenter-cli.jar")
+tb = jfed.jFedTestbed(exp_name = "letest",
+ username = "sander",
+ cert_file = "cert.pem",
+ jfed_jar = "jfed_cli/experimenter-cli.jar")
+#tb = fake.FakeTestbed(exp_name = "x", username = "yy")
-exp = IRATIExperiment(tb, nodes = [a, b])
+exp = irati.IRATIExperiment(tb, nodes = [a, b])
print(exp)
diff --git a/jfed_support.py b/jfed_support.py
deleted file mode 100644
index c98277d..0000000
--- a/jfed_support.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#
-# jFed support for Rhumba
-#
-# Sander Vrijders <sander.vrijders@intec.ugent.be>
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-# MA 02110-1301 USA
-
-import subprocess
-import xml.dom.minidom as xml
-
-def create_rspec(testbed, nodes, links):
- testbed.rspec = testbed.exp_name + ".rspec"
-
- impl = xml.getDOMImplementation()
- doc = impl.createDocument(None, "rspec", None)
-
- top_el = doc.documentElement
- top_el.setAttribute("xmlns", "http://www.geni.net/resources/rspec/3")
- top_el.setAttribute("type", "request")
- top_el.setAttribute("xmlns:emulab", "http://www.protogeni.net/resources/" +
- "rspec/ext/emulab/1")
- top_el.setAttribute("xmlns:jfedBonfire", "http://jfed.iminds.be/rspec/" +
- "ext/jfed-bonfire/1")
- top_el.setAttribute("xmlns:delay", "http://www.protogeni.net/resources/" +
- "rspec/ext/delay/1")
- top_el.setAttribute("xmlns:jfed-command", "http://jfed.iminds.be/" +
- "rspec/ext/jfed-command/1")
- top_el.setAttribute("xmlns:client", "http://www.protogeni.net/resources/" +
- "rspec/ext/client/1")
- top_el.setAttribute("xmlns:jfed-ssh-keys", "http://jfed.iminds.be/rspec" +
- "/ext/jfed-ssh-keys/1")
- top_el.setAttribute("xmlns:jfed", "http://jfed.iminds.be/rspec/ext/jfed/1")
- top_el.setAttribute("xmlns:sharedvlan", "http://www.protogeni.net/" +
- "resources/rspec/ext/shared-vlan/1")
- top_el.setAttribute("xmlns:xsi", "http://www.w3.org/2001/" +
- "XMLSchema-instance")
- top_el.setAttribute("xsi:schemaLocation", "http://www.geni.net/" +
- "resources/rspec/3 http://www.geni.net/" +
- "resources/rspec/3/request.xsd")
-
- for node in nodes:
- el = doc.createElement("node")
- top_el.appendChild(el)
- el.setAttribute("client_id", node.name)
- el.setAttribute("exclusive", "true")
- el.setAttribute("component_manager_id", testbed.authority)
-
- el2 = doc.createElement("sliver_type")
- el.appendChild(el2)
- el2.setAttribute("name", "raw-pc")
-
- node.ifs = 0
- for link in links:
- if link.node_a == node or link.node_b == node:
- el3 = doc.createElement("interface")
- if link.node_a == node:
- link_id = link.int_a.id = node.name + ":if" + str(node.ifs)
- if link.node_b == node:
- link_id = link.int_b.id = node.name + ":if" + str(node.ifs)
-
- el3.setAttribute("client_id", link_id)
- node.ifs += 1
- el.appendChild(el3)
-
- for link in links:
- el = doc.createElement("link")
- top_el.appendChild(el)
- el.setAttribute("client_id", link.name)
-
- el2 = doc.createElement("component_manager_id")
- el2.setAttribute("name", testbed.authority)
- el.appendChild(el2)
-
- el3 = doc.createElement("interface_ref")
- el3.setAttribute("client_id", link.int_a.id)
- el.appendChild(el3)
-
- el4 = doc.createElement("interface_ref")
- el4.setAttribute("client_id", link.int_b.id)
- el.appendChild(el4)
-
- file = open(testbed.rspec, "w")
- file.write(doc.toprettyxml())
- file.close()
-
-def create_experiment(testbed, nodes, links):
- create_rspec(testbed, nodes, links)
- testbed.manifest = testbed.exp_name + ".rrspec"
-
- for node in nodes:
- auth_name_r = testbed.auth_name.replace(".", "-")
- node.full_name = node.name + "." + testbed.exp_name + "." + \
- testbed.proj_name + "." + auth_name_r + \
- "." + testbed.auth_name
-
- subprocess.call(["java", "-jar", testbed.jfed_jar, "create", "-S", \
- testbed.proj_name, "--rspec", \
- testbed.rspec, "-s", \
- testbed.exp_name, "-p", testbed.cert_file, "-k", \
- "usercert,userkeys,shareduserallkeys", "--create-slice",\
- "--manifest", testbed.manifest,
- "-P", testbed.password, \
- "-e", testbed.exp_hours])
-
- rspec = xml.parse(testbed.manifest)
- xml_nodes = rspec.getElementsByTagName("node")
-
- for xml_node in xml_nodes:
- n_name = xml_node.getAttribute("client_id")
- intfs = xml_node.getElementsByTagName("interface")
- for link in links:
- if link.node_a.name == n_name:
- interface = link.int_a
- if link.node_b.name == n_name:
- interface = link.int_b
- for intf in intfs:
- comp_id = intf.getAttribute("component_id")
- comp_arr = comp_id.split(":")
- interface.name = comp_arr[-1]
- xml_ip = intf.getElementsByTagName("ip")
- interface.ip = xml_ip[0].getAttribute("address")
diff --git a/rhumba.py b/rhumba.py
index 1ffd092..0346a8c 100755
--- a/rhumba.py
+++ b/rhumba.py
@@ -19,10 +19,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
-import emulab_support as es
-import jfed_support as js
import abc
-import getpass
# Represents generic testbed info
#
@@ -43,51 +40,6 @@ class Testbed:
raise Exception('create_experiment() not implemented')
-# Represents an emulab testbed info
-#
-# @url [string] URL of the testbed
-# @image [string] specific image to use
-#
-class EmulabTestbed:
- def __init__(self, exp_name, username, password = "",
- proj_name = "ARCFIRE", url = "wall1.ilabt.iminds.be",
- image = "UBUNTU14-64-STD"):
- Testbed.__init__(self, exp_name, username, password, proj_name)
- self.url = url
- self.image = image
-
- def create_experiment(self, nodes, links):
- es.create_experiment(self, nodes, links)
- es.swap_exp_in(self)
- es.wait_until_nodes_up(self)
- es.complete_experiment_graph(self, nodes, links)
-
-
-class jFedTestbed:
- def __init__(self, exp_name, username, cert_file, jfed_jar, exp_hours = "2",
- proj_name = "ARCFIRE", authority = "wall2.ilabt.iminds.be"):
- passwd = getpass.getpass(prompt = "Password for certificate file: ")
- Testbed.__init__(self, exp_name, username, passwd, proj_name)
- self.authority = "urn:publicid:IDN+" + authority + "+authority+cm"
- self.auth_name = authority
- self.cert_file = cert_file
- self.jfed_jar = jfed_jar
- self.exp_hours = exp_hours
-
- def create_experiment(self, nodes, links):
- js.create_experiment(self, nodes, links)
-
-
-# Fake testbed, useful for testing
-class FakeTestbed:
- def __init__(self, exp_name, username, proj_name = "ARCFIRE",
- password = ""):
- Testbed.__init__(self, exp_name, username, password, proj_name)
-
- def create_experiment(self, nodes, links):
- print("[Fake testbed] experiment swapped in")
-
-
# Represents an interface on a node
#
# @name [string] interface name
diff --git a/rhumba_emulab.py b/rhumba_emulab.py
new file mode 100644
index 0000000..db1c299
--- /dev/null
+++ b/rhumba_emulab.py
@@ -0,0 +1,246 @@
+#
+# Emulab support for Rhumba
+#
+# Sander Vrijders <sander.vrijders@intec.ugent.be>
+# Wouter Tavernier <wouter.tavernier@intec.ugent.be>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+import os
+import time
+import re
+from ast import literal_eval
+from ssh_support import *
+import rhumba
+
+import warnings
+warnings.filterwarnings("ignore")
+
+
+
+# Represents an emulab testbed info
+#
+# @url [string] URL of the testbed
+# @image [string] specific image to use
+#
+class EmulabTestbed(rhumba.Testbed):
+ def __init__(self, exp_name, username, password = "",
+ proj_name = "ARCFIRE", url = "wall1.ilabt.iminds.be",
+ image = "UBUNTU14-64-STD"):
+ rhumba.Testbed.__init__(self, exp_name, username, password, proj_name)
+ self.url = url
+ self.image = image
+
+ def ops_server(self):
+ '''
+ Return server name of the ops-server (is testbed specific)
+
+ @param self: testbed info
+
+ @return: server name of the ops-server
+ '''
+ return 'ops.' + self.url
+
+ def full_name(self, node_name):
+ '''
+ Return server name of a node
+
+ @param node_name: name of the node
+ @param self: testbed info
+
+ @return: server name of the node
+ '''
+ return node_name + '.' + self.exp_name + '.' + \
+ self.proj_name + '.' + self.url
+
+ def get_experiment_list(self, project_name = None):
+ '''
+ Get list of made emulab experiments accessible with your credentials
+
+ @param self: testbed info
+ @param project_name: optional filter on project
+
+ @return: list of created experiments (strings)
+ '''
+ cmd = '/usr/testbed/bin/sslxmlrpc_client.py -m experiment getlist'
+ out = execute_command(self, self.ops_server(), cmd)
+
+ try:
+ if project_name != None:
+ return literal_eval(out)[project_name][project_name]
+ else:
+ return literal_eval(out)
+ except:
+ return { project_name: { project_name: [] }}
+
+ def swap_exp_in(self):
+ '''
+ Swaps experiment in
+
+ @param self: testbed info
+ '''
+ cmd = '/usr/testbed/bin/sslxmlrpc_client.py swapexp proj=' + \
+ self.proj_name + \
+ ' exp=' + \
+ self.exp_name + \
+ ' direction=in'
+
+ output = execute_command(self, self.ops_server(), cmd)
+
+ return output
+
+ def _create_experiment(self, nodes, links):
+ '''
+ Creates an emulab experiment
+
+ @param self: testbed info
+ @param nodes: holds the nodes in the experiment
+ @param links: holds the links in the experiment
+ '''
+ proj_name = self.proj_name
+ exp_name = self.exp_name
+
+ exp_list = self.get_experiment_list()
+
+ try:
+ if exp_name in exp_list[proj_name][proj_name]:
+ print("Experiment already exists.")
+ return
+ except:
+ print("First experiment to be created for that project.")
+
+ ns = self.generate_ns_script(nodes, links)
+ dest_file_name = '/users/'+ self.username + \
+ '/temp_ns_file.%s.ns' % os.getpid()
+ copy_file_to_testbed(self, self.ops_server(), ns, dest_file_name)
+
+ cmd = '/usr/testbed/bin/sslxmlrpc_client.py startexp ' + \
+ 'batch=false wait=true proj="' + proj_name + \
+ '" exp="' + exp_name + '" noswapin=true ' + \
+ 'nsfilepath="' + dest_file_name + '"'
+
+ execute_command(self, self.ops_server(), cmd, time_out = None)
+ execute_command(self, self.ops_server(),'rm ' + dest_file_name)
+ print("New experiment succesfully created.")
+
+ def generate_ns_script(self, nodes, p2plinks):
+ '''
+ Generate ns script based on network graph.
+ Enables to customize default node image.
+
+ @param nodes: holds the nodes in the experiment
+ @param links: holds the links in the experiment
+ @param self: testbed info
+
+ @return: ns2 script for Emulab experiment
+ '''
+
+ ns2_script = "# ns script generated by Rhumba\n"
+ ns2_script += "set ns [new Simulator]\n"
+ ns2_script += "source tb_compat.tcl\n"
+
+ for node in nodes:
+ ns2_script += "set " + node.name + " [$ns node]\n"
+ ns2_script += "tb-set-node-os $" + node.name + " " + \
+ self.image + "\n"
+
+ for link in p2plinks:
+ ns2_script += "set " + link.name + \
+ " [$ns duplex-link $" + \
+ link.node_a.name + " $" + \
+ link.node_b.name + " 1000Mb 0ms DropTail]\n"
+
+ ns2_script += "$ns run\n"
+
+ return ns2_script
+
+ def wait_until_nodes_up(self):
+ '''
+ Checks if nodes are up
+
+ @param self: testbed info
+ '''
+ print("Waiting until all nodes are up")
+
+ cmd = '/usr/testbed/bin/script_wrapper.py expinfo -e' + \
+ self.proj_name + \
+ ',' + \
+ self.exp_name + \
+ ' -a | grep State | cut -f2,2 -d " "'
+
+ res = execute_command(self, self.ops_server(), cmd)
+ active = False
+ if res == "active":
+ active = True
+ while active != True:
+ res = execute_command(self, self.ops_server(), cmd)
+ if res == "active":
+ active = True
+ print("Still waiting")
+ time.sleep(5)
+
+ def complete_experiment_graph(self, nodes, p2plinks):
+ '''
+ Gets the interface (ethx) to link mapping
+
+ @param self: testbed info
+ @param nodes: holds the nodes in the experiment
+ @param links: holds the links in the experiment
+ '''
+
+ node_full_name = full_name(self, nodes[0].name)
+ cmd = 'cat /var/emulab/boot/topomap'
+ topomap = execute_command(self, node_full_name, cmd)
+ # Almost as ugly as yo momma
+ index = topomap.rfind("# lans")
+ topo_array = topomap[:index].split('\\n')[1:-1]
+ # Array contains things like 'r2b1,link7:10.1.6.3 link6:10.1.5.3'
+ for item in topo_array:
+ item_array = re.split(',? ?', item)
+ node_name = item_array[0]
+ for item2 in item_array[1:]:
+ item2 = item2.split(':')
+ link_name = item2[0]
+ link_ip = item2[1]
+ for link in p2plinks:
+ if link.name == link_name:
+ if link.node_a.name == node_name:
+ link.int_a.ip = link_ip
+ elif link.node_b.name == node_name:
+ link.int_b.ip = link_ip
+
+ for node in nodes:
+ cmd = 'cat /var/emulab/boot/ifmap'
+ node_full_name = full_name(self, node.name)
+ output = execute_command(self, node_full_name, cmd)
+ output = re.split('\\\\n', output)
+ for item in output:
+ item = item.split()
+ for link in p2plinks:
+ if link.node_a.name == node.name and \
+ link.int_a.ip == item[1]:
+ link.int_a.name = item[0]
+ elif link.node_b.name == node.name and \
+ link.int_b.ip == item[1]:
+ link.int_b.name = item[0]
+ node.full_name = self.full_name(node.name)
+
+ def create_experiment(self, nodes, links):
+ self._create_experiment(nodes, links)
+ self.swap_exp_in()
+ self.wait_until_nodes_up()
+ es.complete_experiment_graph(nodes, links)
+
diff --git a/rhumba_faketestbed.py b/rhumba_faketestbed.py
new file mode 100644
index 0000000..61e9070
--- /dev/null
+++ b/rhumba_faketestbed.py
@@ -0,0 +1,31 @@
+#
+# Fake testbed for Rhumba testing
+#
+# Vincenzo Maffione <v.maffione@nextworks.it>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+import rhumba
+
+# Fake testbed, useful for testing
+class FakeTestbed(rhumba.Testbed):
+ def __init__(self, exp_name, username, proj_name = "ARCFIRE",
+ password = ""):
+ rhumba.Testbed.__init__(self, exp_name, username, password, proj_name)
+
+ def create_experiment(self, nodes, links):
+ print("[Fake testbed] experiment swapped in")
+
diff --git a/rhumba_jfed.py b/rhumba_jfed.py
new file mode 100644
index 0000000..67012fa
--- /dev/null
+++ b/rhumba_jfed.py
@@ -0,0 +1,149 @@
+#
+# jFed support for Rhumba
+#
+# Sander Vrijders <sander.vrijders@intec.ugent.be>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301 USA
+
+import rhumba
+import subprocess
+import getpass
+import xml.dom.minidom as xml
+
+
+class jFedTestbed(rhumba.Testbed):
+ def __init__(self, exp_name, username, cert_file, jfed_jar, exp_hours = "2",
+ proj_name = "ARCFIRE", authority = "wall2.ilabt.iminds.be"):
+ passwd = getpass.getpass(prompt = "Password for certificate file: ")
+ rhumba.Testbed.__init__(self, exp_name, username, passwd, proj_name)
+ self.authority = "urn:publicid:IDN+" + authority + "+authority+cm"
+ self.auth_name = authority
+ self.cert_file = cert_file
+ self.jfed_jar = jfed_jar
+ self.exp_hours = exp_hours
+
+ def create_rspec(self, nodes, links):
+ self.rspec = self.exp_name + ".rspec"
+
+ impl = xml.getDOMImplementation()
+ doc = impl.createDocument(None, "rspec", None)
+
+ top_el = doc.documentElement
+ top_el.setAttribute("xmlns", "http://www.geni.net/resources/rspec/3")
+ top_el.setAttribute("type", "request")
+ top_el.setAttribute("xmlns:emulab", "http://www.protogeni.net/resources/" +
+ "rspec/ext/emulab/1")
+ top_el.setAttribute("xmlns:jfedBonfire", "http://jfed.iminds.be/rspec/" +
+ "ext/jfed-bonfire/1")
+ top_el.setAttribute("xmlns:delay", "http://www.protogeni.net/resources/" +
+ "rspec/ext/delay/1")
+ top_el.setAttribute("xmlns:jfed-command", "http://jfed.iminds.be/" +
+ "rspec/ext/jfed-command/1")
+ top_el.setAttribute("xmlns:client", "http://www.protogeni.net/resources/" +
+ "rspec/ext/client/1")
+ top_el.setAttribute("xmlns:jfed-ssh-keys", "http://jfed.iminds.be/rspec" +
+ "/ext/jfed-ssh-keys/1")
+ top_el.setAttribute("xmlns:jfed", "http://jfed.iminds.be/rspec/ext/jfed/1")
+ top_el.setAttribute("xmlns:sharedvlan", "http://www.protogeni.net/" +
+ "resources/rspec/ext/shared-vlan/1")
+ top_el.setAttribute("xmlns:xsi", "http://www.w3.org/2001/" +
+ "XMLSchema-instance")
+ top_el.setAttribute("xsi:schemaLocation", "http://www.geni.net/" +
+ "resources/rspec/3 http://www.geni.net/" +
+ "resources/rspec/3/request.xsd")
+
+ for node in nodes:
+ el = doc.createElement("node")
+ top_el.appendChild(el)
+ el.setAttribute("client_id", node.name)
+ el.setAttribute("exclusive", "true")
+ el.setAttribute("component_manager_id", self.authority)
+
+ el2 = doc.createElement("sliver_type")
+ el.appendChild(el2)
+ el2.setAttribute("name", "raw-pc")
+
+ node.ifs = 0
+ for link in links:
+ if link.node_a == node or link.node_b == node:
+ el3 = doc.createElement("interface")
+ if link.node_a == node:
+ link_id = link.int_a.id = node.name + ":if" + str(node.ifs)
+ if link.node_b == node:
+ link_id = link.int_b.id = node.name + ":if" + str(node.ifs)
+
+ el3.setAttribute("client_id", link_id)
+ node.ifs += 1
+ el.appendChild(el3)
+
+ for link in links:
+ el = doc.createElement("link")
+ top_el.appendChild(el)
+ el.setAttribute("client_id", link.name)
+
+ el2 = doc.createElement("component_manager_id")
+ el2.setAttribute("name", self.authority)
+ el.appendChild(el2)
+
+ el3 = doc.createElement("interface_ref")
+ el3.setAttribute("client_id", link.int_a.id)
+ el.appendChild(el3)
+
+ el4 = doc.createElement("interface_ref")
+ el4.setAttribute("client_id", link.int_b.id)
+ el.appendChild(el4)
+
+ file = open(self.rspec, "w")
+ file.write(doc.toprettyxml())
+ file.close()
+
+ def create_experiment(self, nodes, links):
+ self.create_rspec(nodes, links)
+ self.manifest = self.exp_name + ".rrspec"
+
+ for node in nodes:
+ auth_name_r = self.auth_name.replace(".", "-")
+ node.full_name = node.name + "." + self.exp_name + "." + \
+ self.proj_name + "." + auth_name_r + \
+ "." + self.auth_name
+
+ subprocess.call(["java", "-jar", self.jfed_jar, "create", "-S", \
+ self.proj_name, "--rspec", \
+ self.rspec, "-s", \
+ self.exp_name, "-p", self.cert_file, "-k", \
+ "usercert,userkeys,shareduserallkeys", "--create-slice",\
+ "--manifest", self.manifest,
+ "-P", self.password, \
+ "-e", self.exp_hours])
+
+ rspec = xml.parse(self.manifest)
+ xml_nodes = rspec.getElementsByTagName("node")
+
+ for xml_node in xml_nodes:
+ n_name = xml_node.getAttribute("client_id")
+ intfs = xml_node.getElementsByTagName("interface")
+ for link in links:
+ if link.node_a.name == n_name:
+ interface = link.int_a
+ if link.node_b.name == n_name:
+ interface = link.int_b
+ for intf in intfs:
+ comp_id = intf.getAttribute("component_id")
+ comp_arr = comp_id.split(":")
+ interface.name = comp_arr[-1]
+ xml_ip = intf.getElementsByTagName("ip")
+ interface.ip = xml_ip[0].getAttribute("address")
+