diff options
author | vmaffione <[email protected]> | 2017-01-24 15:15:07 +0000 |
---|---|---|
committer | vmaffione <[email protected]> | 2017-01-24 15:15:07 +0000 |
commit | 2a085b29e2754500e87cbb1a90e89301671eabe8 (patch) | |
tree | 0f4cca29dd5bd4236122be280c53c6a34ced12fe /rhumba.py | |
parent | e184e2838cc2b65fe9afe1cf7649b01ce4dcf73f (diff) | |
parent | 97e601fdc5c03de7c643c855228b83419394f728 (diff) | |
download | rumba-2a085b29e2754500e87cbb1a90e89301671eabe8.tar.gz rumba-2a085b29e2754500e87cbb1a90e89301671eabe8.zip |
Merge branch 'master-sander' into 'master'
rhumba: Add emulab support
See merge request !3
Diffstat (limited to 'rhumba.py')
-rwxr-xr-x | rhumba.py | 175 |
1 files changed, 159 insertions, 16 deletions
@@ -1,26 +1,156 @@ # # A library to manage ARCFIRE experiments # +# Sander Vrijders <[email protected]> +# Vincenzo Maffione <[email protected]> +# +# 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 emulab_support as es +import jfed_support as js +import abc +import getpass + +# Represents generic testbed info +# +# @username [string] user name +# @password [string] password +# @proj_name [string] project name +# @exp_name [string] experiment name +# +class Testbed: + def __init__(self, exp_name, username, password, proj_name): + self.username = username + self.password = password + self.proj_name = proj_name + self.exp_name = exp_name + + @abc.abstractmethod + def create_experiment(self, nodes, links): + return + +# 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.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) + +# Represents an interface on a node +# +# @name [string] interface name +# @ip [int] IP address of that interface +# +class Interface: + def __init__(self, name = "", ip = ""): + self.name = name + self.ip = ip + +# Represents a link in the physical graph +# +# @name [string] Link name +# +class Link: + def __init__(self, name): + self.name = name + +# Represents a point-to-point link in the physical graph +# +# @name [string] DIF name +# +class P2PLink(Link): + def __init__(self, name, node_a, node_b, + int_a = Interface(), + int_b = Interface()): + Link.__init__(self, name) + self.node_a = node_a + self.node_b = node_b + self.int_a = int_a + self.int_b = int_b + +def get_links(nodes): + difs = set() + links = list() + for node in nodes: + for dif in node.difs: + if type(dif) is ShimEthDIF: + difs.add(dif) + + for dif in difs: + # Point-to-point link + if len(dif.members) == 2: + node_a = dif.members[0] + node_b = dif.members[1] + link = P2PLink(node_a.name + "-" + node_b.name, + node_a, node_b) + links.append(link) + + return links # Base class for DIFs # # @name [string] DIF name # class DIF: - def __init__(self, name): + def __init__(self, name, members = list()): self.name = name + self.members = members def __repr__(self): s = "DIF %s" % self.name return s + def add_member(self, node): + self.members.append(node) + + def del_member(self, node): + self.members.remove(node) + # Shim over Ethernet # # @link_speed [int] Speed of the Ethernet network, in Mbps # class ShimEthDIF(DIF): - def __init__(self, name, link_speed = 0): - DIF.__init__(self, name) + def __init__(self, name, members = list(), link_speed = 0): + DIF.__init__(self, name, members) self.link_speed = int(link_speed) if self.link_speed < 0: raise ValueError("link_speed must be a non-negative number") @@ -30,8 +160,8 @@ class ShimEthDIF(DIF): # @policies [dict] Policies of the normal DIF # class NormalDIF(DIF): - def __init__(self, name, policies = dict()): - DIF.__init__(self, name) + def __init__(self, name, members = list(), policies = dict()): + DIF.__init__(self, name, members) self.policies = policies def add_policy(self, comp, pol): @@ -54,12 +184,14 @@ class NormalDIF(DIF): # @bindings: Binding of names on the processing system # class Node: - def __init__(self, name, difs = set(), + def __init__(self, name, difs = list(), dif_registrations = dict(), registrations = dict(), bindings = dict()): self.name = name self.difs = difs + for dif in difs: + dif.add_member(self) self.dif_registrations = dif_registrations self.registrations = registrations self.bindings = bindings @@ -90,6 +222,14 @@ class Node: s += " ]\n" return s + def add_dif(self, dif): + self.difs.append(dif) + dif.add_member(self) + + def del_dif(self, dif): + self.difs.remove(dif) + dif.del_member(self) + def add_dif_registration(self, dif_a, dif_b): self.dif_registrations[dif_a].append(dif_b) @@ -114,9 +254,10 @@ class Node: # @nodes: Nodes in the experiment # class Experiment: - def __init__(self, name, nodes = set()): + def __init__(self, name, testbed, nodes = list()): self.name = name self.nodes = nodes + self.testbed = testbed def __repr__(self): s = "%s:" % self.name @@ -132,35 +273,37 @@ class Experiment: self.nodes.remove(node) def run(self): - print("[Experiment %s] start" % self.name) - print("[Experiment %s] end" % self.name) - + self.links = get_links(self.nodes) + self.testbed.create_experiment(self.nodes, self.links) # An experiment over the IRATI implementation class IRATIExperiment(Experiment): - def __init__(self, name, nodes = set()): - Experiment.__init__(self, name, nodes) + def __init__(self, name, testbed, nodes = list()): + Experiment.__init__(self, name, testbed, nodes) def run(self): print("[IRATI experiment %s] start" % self.name) + Experiment.run(self) print("[IRATI experiment %s] end" % self.name) # An experiment over the RLITE implementation class RLITEExperiment(Experiment): - def __init__(self, name, nodes = set()): - Experiment.__init__(self, name, nodes) + def __init__(self, name, testbed, nodes = list()): + Experiment.__init__(self, name, testbed, nodes) def run(self): print("[RLITE experiment %s] start" % self.name) + Experiment.run(self) print("[RLITE experiment %s] end" % self.name) # An experiment over the Ouroboros implementation class OuroborosExperiment(Experiment): - def __init__(self, name, nodes = set()): - Experiment.__init__(self, name, nodes) + def __init__(self, name, testbed, nodes = list()): + Experiment.__init__(self, name, testbed, nodes) def run(self): print("[Ouroboros experiment %s] start" % self.name) + Experiment.run(self) print("[Ouroboros experiment %s] end" % self.name) |