X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2Fvim-emu.git;a=blobdiff_plain;f=src%2Femuvim%2Fdcemulator%2Fresourcemodel%2F__init__.py;h=869eb1ddc30a4f0cf3e7148dccc9c890a5dfa464;hp=6ddd45955ac0a26e8204e91e68b1f8231d2a4cf5;hb=d7cbd218427bbfe573d062710006d56751e4406b;hpb=42f08becf9e88b1765793977d581f08c3ebf641f diff --git a/src/emuvim/dcemulator/resourcemodel/__init__.py b/src/emuvim/dcemulator/resourcemodel/__init__.py old mode 100644 new mode 100755 index 6ddd459..869eb1d --- a/src/emuvim/dcemulator/resourcemodel/__init__.py +++ b/src/emuvim/dcemulator/resourcemodel/__init__.py @@ -1,4 +1,31 @@ """ +Copyright (c) 2015 SONATA-NFV and Paderborn University +ALL RIGHTS RESERVED. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Neither the name of the SONATA-NFV, Paderborn University +nor the names of its contributors may be used to endorse or promote +products derived from this software without specific prior written +permission. + +This work has been performed in the framework of the SONATA project, +funded by the European Commission under Grant number 671517 through +the Horizon 2020 and 5G-PPP programmes. The authors would like to +acknowledge the contributions of their colleagues of the SONATA +partner consortium (www.sonata-nfv.eu). +""" +""" Base classes needed for resource models support. """ @@ -8,60 +35,157 @@ LOG.setLevel(logging.DEBUG) class ResourceModelRegistrar(object): + """ + Global registry to keep track of all existing resource models. + """ - def __init__(self, dc_emulation_max_cpu): + def __init__(self, dc_emulation_max_cpu, dc_emulation_max_mem): self.e_cpu = dc_emulation_max_cpu + self.e_mem = dc_emulation_max_mem # pointer to all resource models assigned to DCs self._resource_models = dict() - LOG.info("Resource model registrar created with dc_emulation_max_cpu=%r" % dc_emulation_max_cpu) + LOG.info("Resource model registrar created with dc_emulation_max_cpu=%r and dc_emulation_max_mem=%r" + % (dc_emulation_max_cpu, dc_emulation_max_mem)) def register(self, dc, rm): + """ + Register a new resource model. + :param dc: Data center to which it is assigned. + :param rm: The resource model object. + :return: None + """ 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 + rm.dcs.append(dc) LOG.info("Registrar: Added resource model: %r" % rm) + @property + def resource_models(self): + """ + List of registered resource models + :return: + """ + return list(self._resource_models.itervalues()) + + @property + def num_dcs_with_rms(self): + """ + Total number of data centers that are connected to a resource model + :return: + """ + return sum([len(rm.dcs) for rm in 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._flavors = dict() self._initDefaultFlavors() + self.registrar = None # pointer to registrar + self.dcs = list() + self._allocated_compute_instances = dict() LOG.info("Resource model %r initialized" % self) def __repr__(self): return self.__class__.__name__ def _initDefaultFlavors(self): - # initialize some default flavours (inspired by OpenStack) + """ + initialize some default flavours (naming/sizes inspired by OpenStack) + """ self.addFlavour(ResourceFlavor( - "tiny", {"compute": 1, "memory": 32, "disk": 1})) + "tiny", {"compute": 0.5, "memory": 32, "disk": 1})) self.addFlavour(ResourceFlavor( - "small", {"compute": 4, "memory": 128, "disk": 20})) + "small", {"compute": 1.0, "memory": 128, "disk": 20})) self.addFlavour(ResourceFlavor( - "medium", {"compute": 8, "memory": 256, "disk": 40})) + "medium", {"compute": 4.0, "memory": 256, "disk": 40})) self.addFlavour(ResourceFlavor( - "large", {"compute": 16, "memory": 512, "disk": 80})) + "large", {"compute": 8.0, "memory": 512, "disk": 80})) self.addFlavour(ResourceFlavor( - "xlarge", {"compute": 32, "memory": 1024, "disk": 160})) + "xlarge", {"compute": 16.0, "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 - - def free(self, name): - LOG.info("RM-FREE: %r" % name) - + def allocate(self, d): + """ + This method has to be overwritten by a real resource model. + :param d: Container object + """ + LOG.warning("Allocating in BaseResourceModel: %r with flavor: %r" % (d.name, d.flavor_name)) + self._allocated_compute_instances[d.name] = d.flavor_name + + def free(self, d): + """ + This method has to be overwritten by a real resource model. + :param d: Container object + """ + LOG.warning("Free in BaseResourceModel: %r" % d.name) + del self._allocated_compute_instances[d.name] + + def get_state_dict(self): + """ + Return the state of the resource model as simple dict. + Helper method for logging functionality. + :return: + """ + return dict() + + def write_allocation_log(self, d, path): + """ + Helper to log RM info for experiments. + :param d: container + :param path: log path + :return: + """ + self._write_log(d, path, "allocate") + + def write_free_log(self, d, path): + """ + Helper to log RM info for experiments. + :param d: container + :param path: log path + :return: + """ + self._write_log(d, path, "free") + + def _write_log(self, d, path, action): + """ + Helper to log RM info for experiments. + :param d: container + :param path: log path + :param action: allocate or free + :return: + """ + pass + + +class NotEnoughResourcesAvailable(BaseException): + pass