2 Copyright (c) 2015 SONATA-NFV and Paderborn University
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
9 http://www.apache.org/licenses/LICENSE-2.0
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.
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
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).
29 Base classes needed for resource models support.
33 LOG
= logging
.getLogger("resourcemodel")
34 LOG
.setLevel(logging
.DEBUG
)
37 class ResourceModelRegistrar(object):
39 Global registry to keep track of all existing resource models.
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
))
50 def register(self
, dc
, rm
):
52 Register a new resource model.
53 :param dc: Data center to which it is assigned.
54 :param rm: The resource model object.
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
62 LOG
.info("Registrar: Added resource model: %r" % rm
)
65 def resource_models(self
):
67 List of registered resource models
70 return list(self
._resource
_models
.itervalues())
73 def num_dcs_with_rms(self
):
75 Total number of data centers that are connected to a resource model
78 return sum([len(rm
.dcs
) for rm
in list(self
._resource
_models
.itervalues())])
81 class ResourceFlavor(object):
83 Simple class that represents resource flavors (c.f. OpenStack).
84 Can contain arbitrary metrics.
86 def __init__(self
, name
, metrics
):
88 self
._metrics
= metrics
89 LOG
.debug("Create flavor %r with metrics: %r" % (name
, metrics
))
91 def get(self
, metric_key
):
92 return self
._metrics
.get(metric_key
)
95 class BaseResourceModel(object):
97 Base class for a resource limitation model.
98 Has to be extended by a real resource model implementtion.
102 self
._flavors
= dict()
103 self
._initDefaultFlavors
()
104 self
.registrar
= None # pointer to registrar
106 self
._allocated
_compute
_instances
= dict()
107 LOG
.info("Resource model %r initialized" % self
)
110 return self
.__class
__.__name
__
112 def _initDefaultFlavors(self
):
114 initialize some default flavours (naming/sizes inspired by OpenStack)
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}))
127 def addFlavour(self
, fl
):
129 Add a new flavor to the resource model.
130 :param fl: flavor object
133 if fl
.name
in self
._flavors
:
134 raise Exception("Flavor with name %r already exists!" % fl
.name
)
135 self
._flavors
[fl
.name
] = fl
137 def allocate(self
, d
):
139 This method has to be overwritten by a real resource model.
140 :param d: Container object
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
147 This method has to be overwritten by a real resource model.
148 :param d: Container object
150 LOG
.warning("Free in BaseResourceModel: %r" % d
.name
)
151 del self
._allocated
_compute
_instances
[d
.name
]
153 def get_state_dict(self
):
155 Return the state of the resource model as simple dict.
156 Helper method for logging functionality.
161 def write_allocation_log(self
, d
, path
):
163 Helper to log RM info for experiments.
165 :param path: log path
168 self
._write
_log
(d
, path
, "allocate")
170 def write_free_log(self
, d
, path
):
172 Helper to log RM info for experiments.
174 :param path: log path
177 self
._write
_log
(d
, path
, "free")
179 def _write_log(self
, d
, path
, action
):
181 Helper to log RM info for experiments.
183 :param path: log path
184 :param action: allocate or free
190 class NotEnoughResourcesAvailable(BaseException
):