aboutsummaryrefslogtreecommitdiff
path: root/rumba/model.py
diff options
context:
space:
mode:
authorMarco Capitani <m.capitani@nextworks.it>2017-04-14 09:45:04 +0200
committerMarco Capitani <m.capitani@nextworks.it>2017-04-14 09:45:04 +0200
commit1ccea182dbde7cc2b875f8a5e5434b0f7ba822cd (patch)
tree58ef3799038e8dd5cf60ba0277bd2fcf3fd0f377 /rumba/model.py
parentaf692809383b55ec3b9d7cb96e50b553ffbcd496 (diff)
parenta2b315d257e595af10cf55abdcf026c7c0954020 (diff)
downloadrumba-1ccea182dbde7cc2b875f8a5e5434b0f7ba822cd.tar.gz
rumba-1ccea182dbde7cc2b875f8a5e5434b0f7ba822cd.zip
QEMU: ifname compilation and vm port activation
Diffstat (limited to 'rumba/model.py')
-rw-r--r--rumba/model.py163
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