Refactoring: Made complete codebase PEP8 compatible.
[osm/vim-emu.git] / src / emuvim / dcemulator / resourcemodel / __init__.py
1 # Copyright (c) 2015 SONATA-NFV and Paderborn University
2 # ALL RIGHTS RESERVED.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 #
16 # Neither the name of the SONATA-NFV, Paderborn University
17 # nor the names of its contributors may be used to endorse or promote
18 # products derived from this software without specific prior written
19 # permission.
20 #
21 # This work has been performed in the framework of the SONATA project,
22 # funded by the European Commission under Grant number 671517 through
23 # the Horizon 2020 and 5G-PPP programmes. The authors would like to
24 # acknowledge the contributions of their colleagues of the SONATA
25 # partner consortium (www.sonata-nfv.eu).
26 import logging
27 LOG = logging.getLogger("resourcemodel")
28 LOG.setLevel(logging.DEBUG)
29
30
31 class ResourceModelRegistrar(object):
32 """
33 Global registry to keep track of all existing resource models.
34 """
35
36 def __init__(self, dc_emulation_max_cpu, dc_emulation_max_mem):
37 self.e_cpu = dc_emulation_max_cpu
38 self.e_mem = dc_emulation_max_mem
39 # pointer to all resource models assigned to DCs
40 self._resource_models = dict()
41 LOG.info("Resource model registrar created with dc_emulation_max_cpu=%r and dc_emulation_max_mem=%r"
42 % (dc_emulation_max_cpu, dc_emulation_max_mem))
43
44 def register(self, dc, rm):
45 """
46 Register a new resource model.
47 :param dc: Data center to which it is assigned.
48 :param rm: The resource model object.
49 :return: None
50 """
51 if dc in self._resource_models:
52 raise Exception(
53 "There is already an resource model assigned to this DC.")
54 self._resource_models[dc] = rm
55 rm.registrar = self
56 rm.dcs.append(dc)
57 LOG.info("Registrar: Added resource model: %r" % rm)
58
59 @property
60 def resource_models(self):
61 """
62 List of registered resource models
63 :return:
64 """
65 return list(self._resource_models.itervalues())
66
67 @property
68 def num_dcs_with_rms(self):
69 """
70 Total number of data centers that are connected to a resource model
71 :return:
72 """
73 return sum([len(rm.dcs)
74 for rm in list(self._resource_models.itervalues())])
75
76
77 class ResourceFlavor(object):
78 """
79 Simple class that represents resource flavors (c.f. OpenStack).
80 Can contain arbitrary metrics.
81 """
82
83 def __init__(self, name, metrics):
84 self.name = name
85 self._metrics = metrics
86 LOG.debug("Create flavor %r with metrics: %r" % (name, metrics))
87
88 def get(self, metric_key):
89 return self._metrics.get(metric_key)
90
91
92 class BaseResourceModel(object):
93 """
94 Base class for a resource limitation model.
95 Has to be extended by a real resource model implementtion.
96 """
97
98 def __init__(self):
99 self._flavors = dict()
100 self._initDefaultFlavors()
101 self.registrar = None # pointer to registrar
102 self.dcs = list()
103 self._allocated_compute_instances = dict()
104 LOG.info("Resource model %r initialized" % self)
105
106 def __repr__(self):
107 return self.__class__.__name__
108
109 def _initDefaultFlavors(self):
110 """
111 initialize some default flavours (naming/sizes inspired by OpenStack)
112 """
113 self.addFlavour(ResourceFlavor(
114 "tiny", {"compute": 0.5, "memory": 32, "disk": 1}))
115 self.addFlavour(ResourceFlavor(
116 "small", {"compute": 1.0, "memory": 128, "disk": 20}))
117 self.addFlavour(ResourceFlavor(
118 "medium", {"compute": 4.0, "memory": 256, "disk": 40}))
119 self.addFlavour(ResourceFlavor(
120 "large", {"compute": 8.0, "memory": 512, "disk": 80}))
121 self.addFlavour(ResourceFlavor(
122 "xlarge", {"compute": 16.0, "memory": 1024, "disk": 160}))
123
124 def addFlavour(self, fl):
125 """
126 Add a new flavor to the resource model.
127 :param fl: flavor object
128 :return: None
129 """
130 if fl.name in self._flavors:
131 raise Exception("Flavor with name %r already exists!" % fl.name)
132 self._flavors[fl.name] = fl
133
134 def allocate(self, d):
135 """
136 This method has to be overwritten by a real resource model.
137 :param d: Container object
138 """
139 LOG.warning("Allocating in BaseResourceModel: %r with flavor: %r" % (
140 d.name, d.flavor_name))
141 self._allocated_compute_instances[d.name] = d.flavor_name
142
143 def free(self, d):
144 """
145 This method has to be overwritten by a real resource model.
146 :param d: Container object
147 """
148 LOG.warning("Free in BaseResourceModel: %r" % d.name)
149 del self._allocated_compute_instances[d.name]
150
151 def get_state_dict(self):
152 """
153 Return the state of the resource model as simple dict.
154 Helper method for logging functionality.
155 :return:
156 """
157 return dict()
158
159 def write_allocation_log(self, d, path):
160 """
161 Helper to log RM info for experiments.
162 :param d: container
163 :param path: log path
164 :return:
165 """
166 self._write_log(d, path, "allocate")
167
168 def write_free_log(self, d, path):
169 """
170 Helper to log RM info for experiments.
171 :param d: container
172 :param path: log path
173 :return:
174 """
175 self._write_log(d, path, "free")
176
177 def _write_log(self, d, path, action):
178 """
179 Helper to log RM info for experiments.
180 :param d: container
181 :param path: log path
182 :param action: allocate or free
183 :return:
184 """
185 pass
186
187
188 class NotEnoughResourcesAvailable(BaseException):
189 pass