aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Capitani <m.capitani@nextworks.it>2017-06-13 12:44:04 +0200
committerMarco Capitani <m.capitani@nextworks.it>2017-06-13 12:44:04 +0200
commite36189f8ba98d8a1b254a8dd300f59d5c12a9430 (patch)
treee815229b91e78a13cc96ec7fc3b18015b9544389
parent457977f337a47caddf8788e1d4e1d1736f2a6ccb (diff)
downloadrumba-e36189f8ba98d8a1b254a8dd300f59d5c12a9430.tar.gz
rumba-e36189f8ba98d8a1b254a8dd300f59d5c12a9430.zip
IRATI: added per-node policy support, and revamped policy data model.
additional: + fixed small bug rlated to vhost checking in qemu. + example scripts now correctly use policies.
-rwxr-xr-xexamples/example.py6
-rw-r--r--rumba/model.py78
-rw-r--r--rumba/prototypes/irati.py15
-rw-r--r--rumba/prototypes/irati_templates.py4
-rw-r--r--rumba/testbeds/qemu.py11
5 files changed, 81 insertions, 33 deletions
diff --git a/examples/example.py b/examples/example.py
index 8a68aab..567852f 100755
--- a/examples/example.py
+++ b/examples/example.py
@@ -20,8 +20,10 @@ import rumba.log as log
log.set_logging_level('DEBUG')
-n1 = NormalDIF("n1", policies = {"rmt.pff": {"lfa": {}},
- "security-manager": {"passwd": {}}})
+n1 = NormalDIF("n1")
+
+n1.add_policy("rmt.pff", "lfa")
+n1.add_policy("security-manager", "passwd")
e1 = ShimEthDIF("e1")
diff --git a/rumba/model.py b/rumba/model.py
index e0f1dcc..affdcbf 100644
--- a/rumba/model.py
+++ b/rumba/model.py
@@ -20,9 +20,6 @@
# MA 02110-1301 USA
import abc
-import random
-
-import time
import rumba.log as log
@@ -128,11 +125,11 @@ class ShimEthDIF(DIF):
# 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:
- self.policy = Policy(self)
- self.policy = Policy(self, policies=policies)
+ if policy is None:
+ policy = Policy(self)
+ self.policy = policy
def add_policy(self, comp, pol, **params):
self.policy.add_policy(comp, pol, **params)
@@ -162,7 +159,7 @@ 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 dict to apply for that dif in this node
+# @policies: dict of dif -> policy to apply for that dif in this node
#
#
class Node:
@@ -179,13 +176,12 @@ class Node:
self.dif_registrations = dif_registrations
self.ssh_config = SSHConfig(name)
self.ipcps = []
+ self.policies = dict()
if policies is None:
policies = dict()
- self.policies = dict()
for dif in self.difs:
- if hasattr(dif, 'policy'):
- self.policies[dif] = \
- Policy(dif, self, policies.get(dif.name, {}))
+ if hasattr(dif, 'policy'): # check if the dif supports policies
+ self.policies[dif] = policies.get(dif, Policy(dif, self))
self.client = client
self._validate()
@@ -208,7 +204,7 @@ class Node:
for lower in self.dif_registrations[upper]:
self._undeclared_dif(lower)
- def __repr__(self): # TODO add policies in repr
+ def __repr__(self):
s = "Node " + self.name + ":\n"
s += " DIFs: [ "
@@ -226,6 +222,8 @@ class Node:
s += ", ".join(rl)
s += " ]\n"
+ s += " Policies: [ "
+
return s
def __hash__(self):
@@ -268,6 +266,9 @@ class Node:
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
#
@@ -317,6 +318,10 @@ class ShimUDPIPCP(IPCP):
# 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
@@ -329,11 +334,11 @@ class Policy(object):
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):
- if self.node is not None:
- policy = self._superimpose(self.dif.policy)
- else:
- policy = self
+ policy = self._superimpose()
if component_name is None:
return policy._dict
elif policy_name is None:
@@ -349,10 +354,45 @@ class Policy(object):
else:
del self._dict[component_name][policy_name]
- def _superimpose(self, other):
+ #
+ # 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(base)
+ 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
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..2a5c0f0 100644
--- a/rumba/prototypes/irati_templates.py
+++ b/rumba/prototypes/irati_templates.py
@@ -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/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: