diff options
author | Marco Capitani <m.capitani@nextworks.it> | 2017-04-14 09:45:04 +0200 |
---|---|---|
committer | Marco Capitani <m.capitani@nextworks.it> | 2017-04-14 09:45:04 +0200 |
commit | 1ccea182dbde7cc2b875f8a5e5434b0f7ba822cd (patch) | |
tree | 58ef3799038e8dd5cf60ba0277bd2fcf3fd0f377 /rumba/model.py | |
parent | af692809383b55ec3b9d7cb96e50b553ffbcd496 (diff) | |
parent | a2b315d257e595af10cf55abdcf026c7c0954020 (diff) | |
download | rumba-1ccea182dbde7cc2b875f8a5e5434b0f7ba822cd.tar.gz rumba-1ccea182dbde7cc2b875f8a5e5434b0f7ba822cd.zip |
QEMU: ifname compilation and vm port activation
Diffstat (limited to 'rumba/model.py')
-rw-r--r-- | rumba/model.py | 163 |
1 files changed, 31 insertions, 132 deletions
diff --git a/rumba/model.py b/rumba/model.py index 5f4f162..6f031ac 100644 --- a/rumba/model.py +++ b/rumba/model.py @@ -20,7 +20,7 @@ # MA 02110-1301 USA import abc -import re + # Represents generic testbed info # @@ -65,7 +65,7 @@ class DIF: return hash(self.name) def __eq__(self, other): - return other != None and self.name == other.name + return other is not None and self.name == other.name def __neq__(self, other): return not self == other @@ -79,6 +79,7 @@ class DIF: def get_ipcp_class(self): return IPCP + # Shim over UDP # class ShimUDPDIF(DIF): @@ -88,6 +89,7 @@ class ShimUDPDIF(DIF): def get_ipcp_class(self): return ShimUDPIPCP + # Shim over Ethernet # # @link_speed [int] Speed of the Ethernet network, in Mbps @@ -102,6 +104,7 @@ class ShimEthDIF(DIF): def get_ipcp_class(self): return ShimEthIPCP + # Normal DIF # # @policies [dict] Policies of the normal DIF @@ -125,6 +128,7 @@ class NormalDIF(DIF): s += "\n Component %s has policy %s" % (comp, pol) return s + # SSH Configuration # class SSHConfig: @@ -132,6 +136,7 @@ class SSHConfig: self.hostname = hostname self.port = port + # A node in the experiment # # @difs: DIFs the node will have an IPCP in @@ -164,7 +169,7 @@ class Node: def _undeclared_dif(self, dif): if dif not in self.difs: - raise Exception("Invalid registration: node %s is not declared "\ + raise Exception("Invalid registration: node %s is not declared " "to be part of DIF %s" % (self.name, dif.name)) def _validate(self): @@ -206,8 +211,8 @@ class Node: s += " ]\n" s += " Bindings: [ " - s += ", ".join(["'%s' => '%s'" % (ap, self.bindings[ap]) \ - for ap in self.bindings]) + s += ", ".join(["'%s' => '%s'" % (ap, self.bindings[ap]) + for ap in self.bindings]) s += " ]\n" return s @@ -216,7 +221,7 @@ class Node: return hash(self.name) def __eq__(self, other): - return other != None and self.name == other.name + return other is not None and self.name == other.name def __neq__(self, other): return not self == other @@ -255,6 +260,7 @@ class Node: del self.bindings[name] self._validate() + # Base class representing an IPC Process to be created in the experiment # # @name [string]: IPCP name @@ -277,28 +283,31 @@ class IPCP: (self.name, self.dif.name, ' '.join([dif.name for dif in self.registrations]), ',bootstrapper' if self.dif_bootstrapper else '' - ) + ) def __hash__(self): return hash((self.name, self.dif.name)) def __eq__(self, other): - return other != None and self.name == other.name \ + return other is not None and self.name == other.name \ and self.dif == other.dif def __neq__(self, other): return not self == other + class ShimEthIPCP(IPCP): def __init__(self, name, node, dif, ifname=None): IPCP.__init__(self, name, node, dif) self.ifname = ifname + class ShimUDPIPCP(IPCP): def __init__(self, name, node, dif): IPCP.__init__(self, name, node, dif) # TODO: add IP and port + # Base class for ARCFIRE experiments # # @name [string] Name of the experiment @@ -312,121 +321,11 @@ class Experiment: self.testbed = testbed self.enrollment_strategy = 'minimal' # 'full-mesh', 'manual' self.dif_ordering = [] - self.enrollments = [] # a list of per-DIF lists of enrollments + self.enrollments = [] # a list of per-DIF lists of enrollments # Generate missing information self.generate() - @classmethod - def from_config_file(cls, testbed, filename='demo.conf'): - """ - :type testbed: Testbed - :rtype: Experiment - :param testbed: the testbed for the experiment - :param filename: name of the .conf file - :return: an Experiment object - """ - - shims = {} - nodes = {} - difs = {} - with open(filename, 'r') as conf: - - line_cnt = 0 - - while 1: - line = conf.readline() - if line == '': - break - line_cnt += 1 - - line = line.replace('\n', '').strip() - - if line.startswith('#') or line == "": - continue - - m = re.match(r'\s*eth\s+([\w-]+)\s+(\d+)([GMK])bps\s+(\w.*)$', - line) - if m: - shim = m.group(1) - speed = int(m.group(2)) - speed_unit = m.group(3).lower() - vm_list = m.group(4).split() - - if shim in shims or shim in difs: - print('Error: Line %d: shim %s already defined' - % (line_cnt, shim)) - continue - - if speed_unit == 'K': - speed = speed // 1000 - if speed_unit == 'G': - speed = speed * 1000 - - shims[shim] = {'name': shim, 'speed': speed, 'type': 'eth'} - - for vm in vm_list: - nodes.setdefault(vm, {'name': vm, - 'difs': [], - 'dif_registrations': {}, - 'registrations': {}}) - nodes[vm]['difs'].append(shim) - continue - - m = re.match(r'\s*dif\s+([\w-]+)\s+([\w-]+)\s+(\w.*)$', line) - if m: - dif = m.group(1) - vm = m.group(2) - dif_list = m.group(3).split() - - if dif in shims: - print('Error: Line %d: dif %s already defined as shim' - % (line_cnt, dif)) - continue - - difs.setdefault(dif, {'name': dif}) - - if vm in nodes and dif in nodes[vm]['dif_registrations']: - print( - 'Error: Line %d: vm %s in dif %s already specified' - % (line_cnt, vm, dif)) - continue - - nodes.setdefault(vm, {'name': vm, - 'difs': [], - 'dif_registrations': {}, - 'registrations': {}}) - nodes[vm]['difs'].append(dif) - nodes[vm]['dif_registrations'][dif] = dif_list - # It is not defined yet, per check above. - - continue - - # No match, spit a warning - print('Warning: Line %d unrecognized and ignored' % line_cnt) - - # File parsed - - parsed_difs = {} - - for shim_name, shim in shims.items(): - parsed_difs[shim_name] = (ShimEthDIF(shim_name, - link_speed=shim['speed'])) - - for dif_name, dif in difs.items(): - parsed_difs[dif_name] = (NormalDIF(dif_name)) - - parsed_nodes = [] - for node, node_data in nodes.items(): - name = node_data['name'] - difs = [parsed_difs[x] for x in node_data['difs']] - dif_registrations = {parsed_difs[x]: [parsed_difs[y] for y in l] - for x, l - in node_data['dif_registrations'].items()} - parsed_nodes.append(Node(name, difs, dif_registrations)) - - return cls(testbed=testbed, nodes=parsed_nodes) - def __repr__(self): s = "" for n in self.nodes: @@ -470,8 +369,8 @@ class Experiment: difsdeps_inc_cnt[dif] = len(difsdeps_inc[dif]) del difsdeps_inc - #print(difsdeps_adj) - #print(difsdeps_inc_cnt) + # print(difsdeps_adj) + # print(difsdeps_inc_cnt) # Run Kahn's algorithm to compute topological # ordering on the DIFs graph. @@ -490,12 +389,12 @@ class Experiment: frontier.add(nxt) difsdeps_adj[cur] = set() - circular_set = [dif for dif in difsdeps_inc_cnt \ + circular_set = [dif for dif in difsdeps_inc_cnt if difsdeps_inc_cnt[dif] != 0] if len(circular_set): - raise Exception("Fatal error: The specified DIFs topology" \ - "has one or more" \ - "circular dependencies, involving the following" \ + raise Exception("Fatal error: The specified DIFs topology" + "has one or more" + "circular dependencies, involving the following" " DIFs: %s" % circular_set) print("DIF topological ordering: %s" % self.dif_ordering) @@ -516,8 +415,8 @@ class Experiment: for node in self.nodes: if dif in node.dif_registrations: - dif_graphs[dif][node] = [] # init for later use - if first is None: # pick any node for later use + dif_graphs[dif][node] = [] # init for later use + if first is None: # pick any node for later use first = node for lower_dif in node.dif_registrations[dif]: if lower_dif not in neighsets: @@ -578,11 +477,11 @@ class Experiment: print("Enrollments:") for el in self.enrollments: for e in el: - print(" [%s] %s --> %s through N-1-DIF %s" % \ - (e['dif'], - e['enrollee'].name, - e['enroller'].name, - e['lower_dif'])) + print(" [%s] %s --> %s through N-1-DIF %s" % + (e['dif'], + e['enrollee'].name, + e['enroller'].name, + e['lower_dif'])) def compute_ipcps(self): # For each node, compute the required IPCP instances, and associated |