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