From a769d95a4ee55df7b12d93c10c71d29dff62cbeb Mon Sep 17 00:00:00 2001 From: peusterm Date: Sat, 12 Mar 2016 12:01:27 +0100 Subject: [PATCH] Further work on resource model API --- src/emuvim/dcemulator/node.py | 5 +- .../dcemulator/resourcemodel/__init__.py | 48 ++++++++++++++++--- .../dcemulator/resourcemodel/upb/__init__.py | 0 .../dcemulator/resourcemodel/upb/simple.py | 22 +++++++++ src/emuvim/dcemulator/resourcemodel/upbrm.py | 15 ------ .../examples/resource_model_demo_topology.py | 6 +-- 6 files changed, 70 insertions(+), 26 deletions(-) create mode 100644 src/emuvim/dcemulator/resourcemodel/upb/__init__.py create mode 100644 src/emuvim/dcemulator/resourcemodel/upb/simple.py delete mode 100644 src/emuvim/dcemulator/resourcemodel/upbrm.py diff --git a/src/emuvim/dcemulator/node.py b/src/emuvim/dcemulator/node.py index 5b35b9b..d9971c8 100755 --- a/src/emuvim/dcemulator/node.py +++ b/src/emuvim/dcemulator/node.py @@ -136,8 +136,9 @@ class Datacenter(object): # allocate in resource resource model and compute resource limits for new container if self._resource_model is not None: - # TODO pass resource limits to new container (cf. Dockernet API) - cpu_limit, mem_limit, disk_limit = self._resource_model.allocate(name, flavor_name) + # TODO pass resource limits to new container (cf. Dockernet API) Issue #47 + (cpu_limit, mem_limit, disk_limit) = alloc = self._resource_model.allocate(name, flavor_name) + logging.info("Allocation result: %r" % str(alloc)) # create the container d = self.net.addDocker( "%s" % (name), diff --git a/src/emuvim/dcemulator/resourcemodel/__init__.py b/src/emuvim/dcemulator/resourcemodel/__init__.py index 6ddd459..6432361 100644 --- a/src/emuvim/dcemulator/resourcemodel/__init__.py +++ b/src/emuvim/dcemulator/resourcemodel/__init__.py @@ -19,22 +19,42 @@ class ResourceModelRegistrar(object): if dc in self._resource_models: raise Exception("There is already an resource model assigned to this DC.") self._resource_models[dc] = rm + rm.registrar = self LOG.info("Registrar: Added resource model: %r" % rm) + @property + def num_models(self): + return len(self._resource_models) + + @property + def resource_models(self): + return list(self._resource_models.itervalues()) -class ResourceFlavor(object): +class ResourceFlavor(object): + """ + Simple class that represents resource flavors (c.f. OpenStack). + Can contain arbitrary metrics. + """ def __init__(self, name, metrics): self.name = name - self.metrics = metrics + self._metrics = metrics LOG.debug("Create flavor %r with metrics: %r" % (name, metrics)) + def get(self, metric_key): + return self._metrics.get(metric_key) + class BaseResourceModel(object): + """ + Base class for a resource limitation model. + Has to be extended by a real resource model implementtion. + """ def __init__(self): self._flavors=dict() self._initDefaultFlavors() + self.registrar = None # pointer to registrar LOG.info("Resource model %r initialized" % self) def __repr__(self): @@ -54,14 +74,30 @@ class BaseResourceModel(object): "xlarge", {"compute": 32, "memory": 1024, "disk": 160})) def addFlavour(self, fl): + """ + Add a new flavor to the resource model. + :param fl: flavor object + :return: None + """ if fl.name in self._flavors: raise Exception("Flavor with name %r already exists!" % fl.name) self._flavors[fl.name] = fl def allocate(self, name, flavor_name): - LOG.info("RM-ALLOCATE: %r with flavor: %r" % (name, flavor_name)) - return 0.0, 0.0, 0.0 + """ + This method has to be overwritten by a real resource model. + :param name: Name of the started compute instance. + :param flavor_name: Name of the flavor to be allocated. + :return: 3-tuple: (CPU-fraction, Mem-limit, Disk-limit) + """ + LOG.warning("Allocating in BaseResourceModel: %r with flavor: %r" % (name, flavor_name)) + return -1.0, -1.0, -1.0 # return invalid values to indicate that this RM is a dummy def free(self, name): - LOG.info("RM-FREE: %r" % name) - + """ + This method has to be overwritten by a real resource model. + :param name: Name of the compute instance that is stopped. + :return: True/False + """ + LOG.warning("Free in BaseResourceModel: %r" % name) + return True diff --git a/src/emuvim/dcemulator/resourcemodel/upb/__init__.py b/src/emuvim/dcemulator/resourcemodel/upb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/emuvim/dcemulator/resourcemodel/upb/simple.py b/src/emuvim/dcemulator/resourcemodel/upb/simple.py new file mode 100644 index 0000000..503e35c --- /dev/null +++ b/src/emuvim/dcemulator/resourcemodel/upb/simple.py @@ -0,0 +1,22 @@ +""" +Playground for resource models created by University of Paderborn. +""" +import logging +from emuvim.dcemulator.resourcemodel import BaseResourceModel + +LOG = logging.getLogger("rm.upb.simple") +LOG.setLevel(logging.DEBUG) + + +class UpbSimpleCloudDcApproxRM(BaseResourceModel): + """ + This will be an example resource model that limits the overall + resources that can be deployed per data center. + """ + # TODO Implement resource model issue #12 + + def __init__(self, max_cu=32, max_mu=1024): + self._max_cu = max_cu + self._max_mu = max_mu + super(self.__class__, self).__init__() + diff --git a/src/emuvim/dcemulator/resourcemodel/upbrm.py b/src/emuvim/dcemulator/resourcemodel/upbrm.py deleted file mode 100644 index c6666ae..0000000 --- a/src/emuvim/dcemulator/resourcemodel/upbrm.py +++ /dev/null @@ -1,15 +0,0 @@ -""" -Playground for resource models created by University of Paderborn. -""" -import logging -from emuvim.dcemulator.resourcemodel import BaseResourceModel - -LOG = logging.getLogger("upbrm") -LOG.setLevel(logging.DEBUG) - - -class UpbSimpleCloudDcApproxRM(BaseResourceModel): - - def __init__(self): - super(self.__class__, self).__init__() - diff --git a/src/emuvim/examples/resource_model_demo_topology.py b/src/emuvim/examples/resource_model_demo_topology.py index 329ce7d..e65a8ce 100644 --- a/src/emuvim/examples/resource_model_demo_topology.py +++ b/src/emuvim/examples/resource_model_demo_topology.py @@ -8,7 +8,7 @@ from mininet.log import setLogLevel from emuvim.dcemulator.net import DCNetwork from emuvim.api.zerorpc.compute import ZeroRpcApiEndpoint from emuvim.api.sonata import SonataDummyGatekeeperEndpoint -from emuvim.dcemulator.resourcemodel.upbrm import UpbSimpleCloudDcApproxRM +from emuvim.dcemulator.resourcemodel.upb.simple import UpbSimpleCloudDcApproxRM logging.basicConfig(level=logging.INFO) @@ -25,8 +25,8 @@ def create_topology1(): net.addLink(dc2, s1, delay="20ms") # create and assign resource models for each DC - rm1 = UpbSimpleCloudDcApproxRM() - rm2 = UpbSimpleCloudDcApproxRM() + rm1 = UpbSimpleCloudDcApproxRM(max_cu=10, max_mu=1024) + rm2 = UpbSimpleCloudDcApproxRM(max_cu=20) dc1.assignResourceModel(rm1) dc2.assignResourceModel(rm2) -- 2.25.1