diff options
| -rwxr-xr-x | examples/example.py | 7 | ||||
| -rw-r--r-- | rumba/model.py | 136 | ||||
| -rw-r--r-- | rumba/prototypes/irati.py | 15 | ||||
| -rw-r--r-- | rumba/prototypes/irati_templates.py | 4 | ||||
| -rw-r--r-- | rumba/testbeds/qemu.py | 11 | 
5 files changed, 144 insertions, 29 deletions
diff --git a/examples/example.py b/examples/example.py index 1acc883..567852f 100755 --- a/examples/example.py +++ b/examples/example.py @@ -19,8 +19,11 @@ 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 9818ac7..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 @@ -122,25 +119,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 @@ -157,10 +159,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() @@ -172,6 +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() +        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() @@ -212,6 +222,8 @@ class Node:          s += ", ".join(rl)          s += " ]\n" +        s += "  Policies: [ " +          return s      def __hash__(self): @@ -226,11 +238,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): @@ -241,6 +260,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  # @@ -289,6 +317,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..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:  | 
