aboutsummaryrefslogtreecommitdiff
path: root/rumba
diff options
context:
space:
mode:
authorMarco Capitani <m.capitani@nextworks.it>2017-06-21 17:09:16 +0200
committerMarco Capitani <m.capitani@nextworks.it>2017-06-21 17:09:16 +0200
commit44f5aa5af732fcfdbb6c0eb1655606469a64aee8 (patch)
tree39cd3d968454fbe1f41df716e2c7e94a5cfdb14d /rumba
parent26ed0d7231ce681e6f2041760ba69406ffb6ee86 (diff)
parent67288b3505dab7e9ea74fc87d139301e945b4a78 (diff)
downloadrumba-44f5aa5af732fcfdbb6c0eb1655606469a64aee8.tar.gz
rumba-44f5aa5af732fcfdbb6c0eb1655606469a64aee8.zip
Merge branch 'master' into storyboard-impl
Diffstat (limited to 'rumba')
-rw-r--r--rumba/log.py5
-rw-r--r--rumba/model.py133
-rw-r--r--rumba/prototypes/irati.py15
-rw-r--r--rumba/prototypes/irati_templates.py6
-rw-r--r--rumba/prototypes/ouroboros.py6
-rw-r--r--rumba/prototypes/rlite.py8
-rw-r--r--rumba/ssh_support.py2
-rw-r--r--rumba/testbeds/jfed.py14
-rw-r--r--rumba/testbeds/qemu.py11
9 files changed, 162 insertions, 38 deletions
diff --git a/rumba/log.py b/rumba/log.py
index 987f03a..c509532 100644
--- a/rumba/log.py
+++ b/rumba/log.py
@@ -47,9 +47,8 @@ class RumbaFormatter(logging.Formatter):
def __init__(self):
super(RumbaFormatter, self).__init__(
- fmt='{asctime} | {levelname:3.3} | '
- '{name:11.11} | {message}',
- style='{',
+ fmt='%(asctime)s | %(levelname)3.3s | '
+ '%(name)11.11s | %(message)s',
datefmt='%H:%M:%S')
def format(self, record):
diff --git a/rumba/model.py b/rumba/model.py
index 5215065..46a2351 100644
--- a/rumba/model.py
+++ b/rumba/model.py
@@ -126,25 +126,30 @@ class ShimEthDIF(DIF):
# Normal DIF
#
-# @policies [dict] Policies of the normal DIF
+# @policies [dict] Policies of the normal DIF. Format:
+# dict( componentName: str --> comp_policy:
+# dict( policy_name: str --> parameters:
+# dict( name: str --> value: str )))
#
class NormalDIF(DIF):
- def __init__(self, name, members=None, policies=None):
+ def __init__(self, name, members=None, policy=None):
DIF.__init__(self, name, members)
- if policies is None:
- policies = dict()
- self.policies = policies
+ if policy is None:
+ policy = Policy(self)
+ self.policy = policy
- def add_policy(self, comp, pol):
- self.policies[comp] = pol
+ def add_policy(self, comp, pol, **params):
+ self.policy.add_policy(comp, pol, **params)
- def del_policy(self, comp):
- del self.policies[comp]
+ def del_policy(self, comp=None, policy_name=None):
+ self.policy.del_policy(comp, policy_name)
def show(self):
s = DIF.__repr__(self)
- for comp, pol in self.policies.items():
- s += "\n Component %s has policy %s" % (comp, pol)
+ for comp, pol_dict in self.policy.get_policies().items():
+ for pol, params in pol_dict.items():
+ s += "\n Component %s has policy %s with params %s" \
+ % (comp, pol, params)
return s
@@ -161,10 +166,12 @@ class SSHConfig:
#
# @difs: DIFs the node will have an IPCP in
# @dif_registrations: Which DIF is registered in which DIF
+# @policies: dict of dif -> policy to apply for that dif in this node
+#
#
class Node:
def __init__(self, name, difs=None, dif_registrations=None,
- client=False):
+ client=False, policies=None):
self.name = name
if difs is None:
difs = list()
@@ -176,6 +183,12 @@ class Node:
self.dif_registrations = dif_registrations
self.ssh_config = SSHConfig(name)
self.ipcps = []
+ self.policies = dict()
+ if policies is None:
+ policies = dict()
+ for dif in self.difs:
+ if hasattr(dif, 'policy'): # check if the dif supports policies
+ self.policies[dif] = policies.get(dif, Policy(dif, self))
self.client = client
self._validate()
@@ -216,6 +229,8 @@ class Node:
s += ", ".join(rl)
s += " ]\n"
+ s += " Policies: [ "
+
return s
def __hash__(self):
@@ -230,11 +245,18 @@ class Node:
def add_dif(self, dif):
self.difs.append(dif)
dif.add_member(self)
+ if hasattr(dif, 'policy'):
+ self.policies[dif] = Policy(dif, self)
self._validate()
def del_dif(self, dif):
self.difs.remove(dif)
dif.del_member(self)
+ try:
+ del self.policies[dif]
+ except KeyError:
+ # It was not in there, so nothing to do
+ pass
self._validate()
def add_dif_registration(self, upper, lower):
@@ -245,6 +267,15 @@ class Node:
self.dif_registrations[upper].remove(lower)
self._validate()
+ def add_policy(self, dif, component_name, policy_name, **parameters):
+ self.policies[dif].add_policy(component_name, policy_name, **parameters)
+
+ def del_policy(self, dif, component_name=None, policy_name=None):
+ self.policies[dif].del_policy(component_name, policy_name)
+
+ def get_policy(self, dif):
+ return self.policies[dif]
+
# Base class representing an IPC Process to be created in the experiment
#
@@ -293,6 +324,84 @@ class ShimUDPIPCP(IPCP):
# TODO: add IP and port
+# Class representing DIF and Node policies
+#
+# @dif: the dif this policy is applied to.
+# @node: the node
+#
+class Policy(object):
+ def __init__(self, dif, node=None, policies=None):
+ self.dif = dif # type: NormalDIF
+ self.node = node
+ if policies is None:
+ self._dict = dict()
+ else:
+ self._dict = policies
+
+ def add_policy(self, component_name, policy_name, **parameters):
+ self._dict.setdefault(component_name, dict())[policy_name] = parameters
+
+ #
+ # Fetches effective policy info
+ #
+ def get_policies(self, component_name=None, policy_name=None):
+ policy = self._superimpose()
+ if component_name is None:
+ return policy._dict
+ elif policy_name is None:
+ return policy._dict[component_name]
+ else:
+ return policy._dict[component_name][policy_name]
+
+ def del_policy(self, component_name=None, policy_name=None):
+ if component_name is None:
+ self._dict = dict()
+ elif policy_name is None:
+ del self._dict[component_name]
+ else:
+ del self._dict[component_name][policy_name]
+
+ #
+ # Merges this policy into that of its dif, obtaining
+ # the effective policy acting on self.node.
+ #
+ def _superimpose(self):
+ if self.node is None:
+ return self
+ other = self.dif.policy
+ base = dict(other._dict)
+ base.update(self._dict)
+ return Policy(self.dif, self.node, base)
+
+ def __eq__(self, other):
+ if not isinstance(other, Policy):
+ return False
+ else:
+ return other.dif == self.dif \
+ and other.node == self.node \
+ and other._dict == self._dict
+
+ def __str__(self):
+ node_str = (" Node: " + self.node) if self.node is not None else ""
+ return "Policy[Dif: %(dif)s,%(node_str)s Dict: %(dict)s]" \
+ % {"dif": self.dif, "node_str": node_str, "dict": self._dict}
+
+ def __repr__(self):
+ node_str = (" Node: " + self.node) if self.node is not None else ""
+ s = "Policy[ Dif: %(dif)s,%(node_str)s" \
+ % {"dif": self.dif, "node_str": node_str}
+ comps = []
+ for component in self._dict:
+ for policy in self._dict[component]:
+ comps.append("\n Component %s has policy %s with params %s"
+ % (component,
+ policy,
+ self._dict[component][policy]))
+ s += ",".join(comps)
+ s += "\n]\n"
+ return s
+
+
# Base class for ARCFIRE experiments
#
# @name [string] Name of the experiment
diff --git a/rumba/prototypes/irati.py b/rumba/prototypes/irati.py
index 42afe3b..c01e413 100644
--- a/rumba/prototypes/irati.py
+++ b/rumba/prototypes/irati.py
@@ -355,11 +355,16 @@ class Experiment(mod.Experiment):
"apName": "%s.%s.IPCP" % (dif.name, node_name),
"apInstance": "1",
"address": 16 + node2id_map[node_name]})
- for path, ps in dif.policies.items():
- # if policy['nodes'] == [] or vmname in policy['nodes']:
- # TODO: manage per-node-policies
- irati_templates.translate_policy(
- difconfs[dif.name][node_name], path, ps, parms=[])
+ policy_dict = node.get_policy(dif).get_policies()
+ for component in policy_dict:
+ for policy_name in policy_dict[component]:
+ params = policy_dict[component][policy_name].items()
+ irati_templates.translate_policy(
+ difconfs[dif.name][node_name],
+ component,
+ policy_name,
+ params
+ )
# Dump the DIF Allocator map
with open(self.conf_dir('da.map'), 'w') as da_map_file:
diff --git a/rumba/prototypes/irati_templates.py b/rumba/prototypes/irati_templates.py
index b8d9788..7d06c96 100644
--- a/rumba/prototypes/irati_templates.py
+++ b/rumba/prototypes/irati_templates.py
@@ -11,7 +11,7 @@ ipcmconf_base = {
"consoleSocket": "%(varpath)s/var/run/ipcm-console.sock" % env_dict,
"pluginsPaths": [
"%(installpath)s/lib/rinad/ipcp" % env_dict,
- "/lib/modules/4.1.33-irati/extra"
+ "/lib/modules/4.9.28-irati/extra"
]
},
@@ -238,7 +238,7 @@ def ps_set(d, k, v, parms):
if d[k]["name"] == v and "parameters" in d[k]:
cur_names = [p["name"] for p in d[k]["parameters"]]
for p in parms:
- name, value = p.split('=')
+ name, value = p
if name in cur_names:
for i in range(len(d[k]["parameters"])):
if d[k]["parameters"][i]["name"] == name:
@@ -249,7 +249,7 @@ def ps_set(d, k, v, parms):
elif len(parms) > 0:
d[k]["parameters"] = [
- {'name': p.split('=')[0], 'value': p.split('=')[1]}
+ {'name': p[0], 'value': p[1]}
for p in parms]
d[k]["name"] = v
diff --git a/rumba/prototypes/ouroboros.py b/rumba/prototypes/ouroboros.py
index 9ac1425..43cb1d5 100644
--- a/rumba/prototypes/ouroboros.py
+++ b/rumba/prototypes/ouroboros.py
@@ -63,13 +63,13 @@ class Experiment(mod.Experiment):
else:
cmd = "irm i c n " + ipcp.name
- if type(ipcp.dif) is mod.ShimEthDIF:
+ if isinstance(ipcp.dif, mod.ShimEthDIF):
# NOTE: Here to test with fake testbed
if ipcp.ifname is None:
ipcp.ifname = "eth0"
cmd += " type shim-eth-llc if_name " + ipcp.ifname
cmd += " dif " + ipcp.dif.name
- elif type(ipcp.dif) is mod.NormalDIF:
+ elif isinstance(ipcp.dif, mod.NormalDIF):
cmd += " type normal"
if ipcp.dif_bootstrapper:
cmd += " dif " + ipcp.dif.name
@@ -83,7 +83,7 @@ class Experiment(mod.Experiment):
for dif_b in node.dif_registrations[ipcp.dif]:
cmd2 += " dif " + dif_b.name
cmds2.append(cmd2)
- elif type(ipcp.dif) is mod.ShimUDPDIF:
+ elif isinstance(ipcp.dif, mod.ShimUDPDIF):
# FIXME: Will fail, since we don't keep IPs yet
cmd += " type shim-udp"
cmd += " dif " + ipcp.dif.name
diff --git a/rumba/prototypes/rlite.py b/rumba/prototypes/rlite.py
index cc38255..abab080 100644
--- a/rumba/prototypes/rlite.py
+++ b/rumba/prototypes/rlite.py
@@ -70,11 +70,11 @@ class Experiment(mod.Experiment):
for ipcp in node.ipcps:
# Generate the command to create the IPCP
- if type(ipcp.dif) is mod.NormalDIF:
+ if isinstance(ipcp.dif, mod.NormalDIF):
ipcp_type = 'normal'
- elif type(ipcp.dif) is mod.ShimEthDIF:
+ elif isinstance(ipcp.dif, mod.ShimEthDIF):
ipcp_type = 'shim-eth'
- elif type(ipcp.dif) is mod.ShimUDPDIF:
+ elif isinstance(ipcp.dif, mod.ShimUDPDIF):
ipcp_type = 'shim-udp4'
else:
logger.warning(
@@ -87,7 +87,7 @@ class Experiment(mod.Experiment):
# Generate the command to configure the interface
# name for the shim-eth
- if type(ipcp.dif) is mod.ShimEthDIF:
+ if isinstance(ipcp.dif, mod.ShimEthDIF):
cmds.append("rlite-ctl ipcp-config %s netdev %s"
% (ipcp.name, ipcp.ifname))
diff --git a/rumba/ssh_support.py b/rumba/ssh_support.py
index a1e1ba4..b0970e1 100644
--- a/rumba/ssh_support.py
+++ b/rumba/ssh_support.py
@@ -40,7 +40,7 @@ def _print_stream(stream):
o_array = o.split('\\n')
for oi in o_array:
logger.debug(oi)
- return o
+ return o.rstrip()
def execute_proxy_commands(testbed, ssh_config, commands, time_out=3):
diff --git a/rumba/testbeds/jfed.py b/rumba/testbeds/jfed.py
index 83fbce7..e158048 100644
--- a/rumba/testbeds/jfed.py
+++ b/rumba/testbeds/jfed.py
@@ -22,6 +22,8 @@ import subprocess
import getpass
import xml.dom.minidom as xml
import os.path
+
+import time
import wget
import tarfile
@@ -173,6 +175,9 @@ class Testbed(mod.Testbed):
dir_path = os.path.dirname(os.path.abspath(__file__))
# Complete details of the nodes after swapin
+ logger.info("Sleeping for two seconds to avoid contacting jfed nodes "
+ "too soon.")
+ time.sleep(2)
for xml_node in xml_nodes:
n_name = xml_node.getAttribute("client_id")
intfs = xml_node.getElementsByTagName("interface")
@@ -215,8 +220,13 @@ class Testbed(mod.Testbed):
if isinstance(ipcp, mod.ShimEthIPCP):
if self.if_id[ipcp] == i_name:
ipcp.ifname = ifname
- logger.debug("Node %s interface %s has name %s."
- % (node_n.name, mac, ifname))
+ if ifname is None:
+ logger.error("Could not determine name of node"
+ "%s interface %s"
+ % (node_n.name, mac))
+ else:
+ logger.debug("Node %s interface %s has name %s."
+ % (node_n.name, mac, ifname))
# comp_id = intf.getAttribute("component_id")
# comp_arr = comp_id.split(":")
# ipcp.ifname = comp_arr[-1]
diff --git a/rumba/testbeds/qemu.py b/rumba/testbeds/qemu.py
index df02ab6..1d449dc 100644
--- a/rumba/testbeds/qemu.py
+++ b/rumba/testbeds/qemu.py
@@ -111,11 +111,12 @@ class Testbed(mod.Testbed):
if os.geteuid() != 0:
try:
subprocess.check_call(["sudo", "-v"])
- if not os.access("/dev/vhost-net", os.R_OK) \
- or not os.access("/dev/vhost-net", os.W_OK) \
- or not os.access("/dev/kvm", os.R_OK) \
- or not os.access("/dev/kvm", os.W_OK):
- raise Exception('Cannot open vhost device. Make sure it is'
+ if self.vhost and \
+ (not os.access("/dev/vhost-net", os.R_OK)
+ or not os.access("/dev/vhost-net", os.W_OK)
+ or not os.access("/dev/kvm", os.R_OK)
+ or not os.access("/dev/kvm", os.W_OK)):
+ raise Exception('Cannot open vhost device. Make sure it is '
'available and you have rw permissions '
'on /dev/vhost-net')
except subprocess.CalledProcessError: