Merge pull request #68 from mpeuster/master
[osm/vim-emu.git] / src / emuvim / dcemulator / resourcemodel / __init__.py
1 """
2 Base classes needed for resource models support.
3 """
4
5 import logging
6 LOG = logging.getLogger("resourcemodel")
7 LOG.setLevel(logging.DEBUG)
8
9
10 class ResourceModelRegistrar(object):
11 """
12 Global registry to keep track of all existing resource models.
13 """
14
15 def __init__(self, dc_emulation_max_cpu, dc_emulation_max_mem):
16 self.e_cpu = dc_emulation_max_cpu
17 self.e_mem = dc_emulation_max_mem
18 # pointer to all resource models assigned to DCs
19 self._resource_models = dict()
20 LOG.info("Resource model registrar created with dc_emulation_max_cpu=%r and dc_emulation_max_mem=%r"
21 % (dc_emulation_max_cpu, dc_emulation_max_mem))
22
23 def register(self, dc, rm):
24 """
25 Register a new resource model.
26 :param dc: Data center to which it is assigned.
27 :param rm: The resource model object.
28 :return: None
29 """
30 if dc in self._resource_models:
31 raise Exception("There is already an resource model assigned to this DC.")
32 self._resource_models[dc] = rm
33 rm.registrar = self
34 rm.dcs.append(dc)
35 LOG.info("Registrar: Added resource model: %r" % rm)
36
37 @property
38 def resource_models(self):
39 """
40 List of registered resource models
41 :return:
42 """
43 return list(self._resource_models.itervalues())
44
45 @property
46 def num_dcs_with_rms(self):
47 """
48 Total number of data centers that are connected to a resource model
49 :return:
50 """
51 return sum([len(rm.dcs) for rm in list(self._resource_models.itervalues())])
52
53
54 class ResourceFlavor(object):
55 """
56 Simple class that represents resource flavors (c.f. OpenStack).
57 Can contain arbitrary metrics.
58 """
59 def __init__(self, name, metrics):
60 self.name = name
61 self._metrics = metrics
62 LOG.debug("Create flavor %r with metrics: %r" % (name, metrics))
63
64 def get(self, metric_key):
65 return self._metrics.get(metric_key)
66
67
68 class BaseResourceModel(object):
69 """
70 Base class for a resource limitation model.
71 Has to be extended by a real resource model implementtion.
72 """
73
74 def __init__(self):
75 self._flavors = dict()
76 self._initDefaultFlavors()
77 self.registrar = None # pointer to registrar
78 self.dcs = list()
79 self.allocated_compute_instances = dict()
80 LOG.info("Resource model %r initialized" % self)
81
82 def __repr__(self):
83 return self.__class__.__name__
84
85 def _initDefaultFlavors(self):
86 """
87 initialize some default flavours (naming/sizes inspired by OpenStack)
88 """
89 self.addFlavour(ResourceFlavor(
90 "tiny", {"compute": 1, "memory": 32, "disk": 1}))
91 self.addFlavour(ResourceFlavor(
92 "small", {"compute": 4, "memory": 128, "disk": 20}))
93 self.addFlavour(ResourceFlavor(
94 "medium", {"compute": 8, "memory": 256, "disk": 40}))
95 self.addFlavour(ResourceFlavor(
96 "large", {"compute": 16, "memory": 512, "disk": 80}))
97 self.addFlavour(ResourceFlavor(
98 "xlarge", {"compute": 32, "memory": 1024, "disk": 160}))
99
100 def addFlavour(self, fl):
101 """
102 Add a new flavor to the resource model.
103 :param fl: flavor object
104 :return: None
105 """
106 if fl.name in self._flavors:
107 raise Exception("Flavor with name %r already exists!" % fl.name)
108 self._flavors[fl.name] = fl
109
110 def allocate(self, name, flavor_name):
111 """
112 This method has to be overwritten by a real resource model.
113 :param name: Name of the started compute instance.
114 :param flavor_name: Name of the flavor to be allocated.
115 :return: 3-tuple: (CPU-fraction, Mem-limit, Disk-limit)
116 """
117 LOG.warning("Allocating in BaseResourceModel: %r with flavor: %r" % (name, flavor_name))
118 self.allocated_compute_instances[name] = flavor_name
119 return -1.0, -1.0, -1.0 # return invalid values to indicate that this RM is a dummy
120
121 def free(self, name):
122 """
123 This method has to be overwritten by a real resource model.
124 :param name: Name of the compute instance that is stopped.
125 :return: True/False
126 """
127 LOG.warning("Free in BaseResourceModel: %r" % name)
128 del self.allocated_compute_instances[name]
129 return True