From 97e601fdc5c03de7c643c855228b83419394f728 Mon Sep 17 00:00:00 2001 From: Sander Vrijders Date: Tue, 24 Jan 2017 15:01:17 +0100 Subject: rhumba: Add jFed support This adds jFed support. You need to direct the python script to the jFed CLI jar when creating a jFedTestbed, as well as directing it to your certificate. The passphrase for this certificate will be asked upon starting. --- .gitignore | 5 ++- emulab_support.py | 28 +++++------- jfed_support.py | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.py | 7 +-- rhumba.py | 57 ++++++++---------------- 5 files changed, 163 insertions(+), 62 deletions(-) create mode 100644 jfed_support.py diff --git a/.gitignore b/.gitignore index d94c1e4..146de1b 100644 --- a/.gitignore +++ b/.gitignore @@ -89,4 +89,7 @@ ENV/ .ropeproject # emacs temporary files -*~ \ No newline at end of file +*~ + +*rspec +*.pem diff --git a/emulab_support.py b/emulab_support.py index 6c31cd6..6fe0055 100644 --- a/emulab_support.py +++ b/emulab_support.py @@ -30,14 +30,6 @@ import configparser import warnings warnings.filterwarnings("ignore") -tag = "emulab-support" - -def log_debug(message): - print(tag + "(DBG): " + message) - -def log_error(message): - print(tag + "(ERR): " + message) - def get_ssh_client(): ssh_client = paramiko.SSHClient() ssh_client.load_system_host_keys() @@ -90,14 +82,14 @@ def execute_command(testbed, hostname, command, time_out = 3): stdin, stdout, stderr = ssh_client.exec_command(command) err = str(stderr.read()).strip('b\'\"\\n') if err != "": - log_error(err) + print(err) output = str(stdout.read()).strip('b\'\"\\n') ssh_client.close() return output except Exception as e: - log_error(str(e)) + print(str(e)) return def copy_file_to_testbed(testbed, hostname, text, file_name): @@ -124,7 +116,7 @@ def copy_file_to_testbed(testbed, hostname, text, file_name): stdin, stdout, stderr = ssh_client.exec_command(cmd) err = str(stderr.read()).strip('b\'\"\\n') if err != "": - log_error(err) + print(err) sftp_client = ssh_client.open_sftp() remote_file = sftp_client.open(file_name, 'w') @@ -133,7 +125,7 @@ def copy_file_to_testbed(testbed, hostname, text, file_name): remote_file.close() except Exception as e: - log_error(str(e)) + print(str(e)) def get_experiment_list(testbed, project_name = None): ''' @@ -186,10 +178,10 @@ def create_experiment(testbed, nodes, links): try: if exp_name in exp_list[proj_name][proj_name]: - log_debug("Experiment already exists.") + print("Experiment already exists.") return except: - log_debug("First experiment to be created for that project.") + print("First experiment to be created for that project.") ns = generate_ns_script(testbed, nodes, links) dest_file_name = '/users/'+ testbed.username + \ @@ -203,7 +195,7 @@ def create_experiment(testbed, nodes, links): execute_command(testbed, ops_server(testbed), cmd, time_out = None) execute_command(testbed, ops_server(testbed),'rm ' + dest_file_name) - log_debug("New experiment succesfully created.") + print("New experiment succesfully created.") def generate_ns_script(testbed, nodes, p2plinks): ''' @@ -242,7 +234,7 @@ def wait_until_nodes_up(testbed): @param testbed: testbed info ''' - log_debug("Waiting until all nodes are up") + print("Waiting until all nodes are up") cmd = '/usr/testbed/bin/script_wrapper.py expinfo -e' + \ testbed.proj_name + \ @@ -258,7 +250,7 @@ def wait_until_nodes_up(testbed): res = execute_command(testbed, ops_server(testbed), cmd) if res == "active": active = True - log_debug("Still waiting") + print("Still waiting") time.sleep(5) def complete_experiment_graph(testbed, nodes, p2plinks): @@ -315,7 +307,7 @@ def setup_vlan(testbed, node_name, vlan_id, int_name): @param vlan_id: the VLAN id @param int_name: the name of the interface ''' - log_debug("Setting up VLAN on node " + node_name) + print("Setting up VLAN on node " + node_name) node_full_name = full_name(node_name, testbed) cmd = "sudo ip link add link " + \ diff --git a/jfed_support.py b/jfed_support.py new file mode 100644 index 0000000..aa933d8 --- /dev/null +++ b/jfed_support.py @@ -0,0 +1,128 @@ +# +# jFed support for Rhumba +# +# Sander Vrijders +# +# 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" + + 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/main.py b/main.py index 5da0cc9..49508e9 100755 --- a/main.py +++ b/main.py @@ -19,9 +19,10 @@ b = Node("b", difs = [e1, n1], dif_registrations = {n1 : [e1]}) -tb = EmulabTestbed(username = "sander", - exp_name = "test001", - url = "wall2.ilabt.iminds.be") +tb = jFedTestbed(exp_name = "letest", + username = "sander", + cert_file = "cert.pem", + jfed_jar = "jfed_cli/experimenter-cli.jar") exp = IRATIExperiment("paperino", tb, nodes = [a, b]) diff --git a/rhumba.py b/rhumba.py index 792965b..d8cb17c 100755 --- a/rhumba.py +++ b/rhumba.py @@ -20,7 +20,9 @@ # MA 02110-1301 USA import emulab_support as es +import jfed_support as js import abc +import getpass # Represents generic testbed info # @@ -30,8 +32,7 @@ import abc # @exp_name [string] experiment name # class Testbed: - def __init__(self, username = "", password = "", - proj_name = "", exp_name = ""): + def __init__(self, exp_name, username, password, proj_name): self.username = username self.password = password self.proj_name = proj_name @@ -41,58 +42,37 @@ class Testbed: def create_experiment(self, nodes, links): return - @abc.abstractmethod - def swap_exp_in(self): - return - - @abc.abstractmethod - def wait_until_nodes_up(self): - return - - @abc.abstractmethod - def complete_experiment_graph(self, nodes, links): - return - - @abc.abstractmethod - def execute_command(self, hostname, command, time_out = 3): - return - - @abc.abstractmethod - def copy_file_to_testbed(self, hostname, text, file_name): - return - # Represents an emulab testbed info # # @url [string] URL of the testbed # @image [string] specific image to use # class EmulabTestbed: - def __init__(self, username = "", password = "", - proj_name = "ARCFIRE", exp_name = "", - url = "wall1.ilabt.iminds.be", + def __init__(self, exp_name, username, password = "", + proj_name = "ARCFIRE", url = "wall1.ilabt.iminds.be", image = "UBUNTU14-64-STD"): - Testbed.__init__(self, username, password, - proj_name, exp_name) + 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) - - def swap_exp_in(self): es.swap_exp_in(self) - - def wait_until_nodes_up(self): es.wait_until_nodes_up(self) - - def complete_experiment_graph(self, nodes, links): es.complete_experiment_graph(self, nodes, links) - def execute_command(self, hostname, command, time_out = 3): - es.execute_command(self, hostname, command, time_out = 3) +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.cert_file = cert_file + self.jfed_jar = jfed_jar + self.exp_hours = exp_hours - def copy_file_to_testbed(self, hostname, text, file_name): - es.copy_file_to_testbed(self, hostname, text, file_name) + def create_experiment(self, nodes, links): + js.create_experiment(self, nodes, links) # Represents an interface on a node # @@ -295,9 +275,6 @@ class Experiment: def run(self): self.links = get_links(self.nodes) self.testbed.create_experiment(self.nodes, self.links) - self.testbed.swap_exp_in() - self.testbed.wait_until_nodes_up() - self.testbed.complete_experiment_graph(self.nodes, self.links) # An experiment over the IRATI implementation class IRATIExperiment(Experiment): -- cgit v1.2.3