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