From e36189f8ba98d8a1b254a8dd300f59d5c12a9430 Mon Sep 17 00:00:00 2001 From: Marco Capitani Date: Tue, 13 Jun 2017 12:44:04 +0200 Subject: 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. --- rumba/model.py | 78 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 19 deletions(-) (limited to 'rumba/model.py') 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 -- cgit v1.2.3