4 # Copyright 2017 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
22 gi
.require_version('RwcalYang', '1.0')
23 from gi
.repository
import RwcalYang
26 class GuestEPAUtils(object):
28 Utility class for Host EPA to Openstack flavor extra_specs conversion routines
31 self
._mano
_to
_espec
_cpu
_pinning
_policy
= {
32 'DEDICATED' : 'dedicated',
37 self
._espec
_to
_mano
_cpu
_pinning
_policy
= {
38 'dedicated' : 'DEDICATED',
43 self
._mano
_to
_espec
_mempage
_size
= {
48 'PREFER_LARGE' : 'large',
51 self
._espec
_to
_mano
_mempage
_size
= {
56 'large' : 'PREFER_LARGE',
59 self
._mano
_to
_espec
_cpu
_thread
_pinning
_policy
= {
61 'SEPARATE' : 'separate',
62 'ISOLATE' : 'isolate',
66 self
._espec
_to
_mano
_cpu
_thread
_pinning
_policy
= {
68 'separate' : 'SEPARATE',
69 'isolate' : 'ISOLATE',
73 self
._espec
_to
_mano
_numa
_memory
_policy
= {
75 'preferred': 'PREFERRED'
78 self
._mano
_to
_espec
_numa
_memory
_policy
= {
80 'PREFERRED': 'preferred'
83 def mano_to_extra_spec_cpu_pinning_policy(self
, cpu_pinning_policy
):
84 if cpu_pinning_policy
in self
._mano
_to
_espec
_cpu
_pinning
_policy
:
85 return self
._mano
_to
_espec
_cpu
_pinning
_policy
[cpu_pinning_policy
]
89 def extra_spec_to_mano_cpu_pinning_policy(self
, cpu_pinning_policy
):
90 if cpu_pinning_policy
in self
._espec
_to
_mano
_cpu
_pinning
_policy
:
91 return self
._espec
_to
_mano
_cpu
_pinning
_policy
[cpu_pinning_policy
]
95 def mano_to_extra_spec_mempage_size(self
, mempage_size
):
96 if mempage_size
in self
._mano
_to
_espec
_mempage
_size
:
97 return self
._mano
_to
_espec
_mempage
_size
[mempage_size
]
101 def extra_spec_to_mano_mempage_size(self
, mempage_size
):
102 if mempage_size
in self
._espec
_to
_mano
_mempage
_size
:
103 return self
._espec
_to
_mano
_mempage
_size
[mempage_size
]
107 def mano_to_extra_spec_cpu_thread_pinning_policy(self
, cpu_thread_pinning_policy
):
108 if cpu_thread_pinning_policy
in self
._mano
_to
_espec
_cpu
_thread
_pinning
_policy
:
109 return self
._mano
_to
_espec
_cpu
_thread
_pinning
_policy
[cpu_thread_pinning_policy
]
113 def extra_spec_to_mano_cpu_thread_pinning_policy(self
, cpu_thread_pinning_policy
):
114 if cpu_thread_pinning_policy
in self
._espec
_to
_mano
_cpu
_thread
_pinning
_policy
:
115 return self
._espec
_to
_mano
_cpu
_thread
_pinning
_policy
[cpu_thread_pinning_policy
]
119 def mano_to_extra_spec_trusted_execution(self
, trusted_execution
):
120 if trusted_execution
:
125 def extra_spec_to_mano_trusted_execution(self
, trusted_execution
):
126 if trusted_execution
== 'trusted':
128 elif trusted_execution
== 'untrusted':
133 def mano_to_extra_spec_numa_node_count(self
, numa_node_count
):
134 return numa_node_count
136 def extra_specs_to_mano_numa_node_count(self
, numa_node_count
):
137 return int(numa_node_count
)
139 def mano_to_extra_spec_numa_memory_policy(self
, numa_memory_policy
):
140 if numa_memory_policy
in self
._mano
_to
_espec
_numa
_memory
_policy
:
141 return self
._mano
_to
_espec
_numa
_memory
_policy
[numa_memory_policy
]
145 def extra_to_mano_spec_numa_memory_policy(self
, numa_memory_policy
):
146 if numa_memory_policy
in self
._espec
_to
_mano
_numa
_memory
_policy
:
147 return self
._espec
_to
_mano
_numa
_memory
_policy
[numa_memory_policy
]
154 class HostEPAUtils(object):
156 Utility class for Host EPA to Openstack flavor extra_specs conversion routines
159 self
._mano
_to
_espec
_cpumodel
= {
160 "PREFER_WESTMERE" : "Westmere",
161 "REQUIRE_WESTMERE" : "Westmere",
162 "PREFER_SANDYBRIDGE" : "SandyBridge",
163 "REQUIRE_SANDYBRIDGE" : "SandyBridge",
164 "PREFER_IVYBRIDGE" : "IvyBridge",
165 "REQUIRE_IVYBRIDGE" : "IvyBridge",
166 "PREFER_HASWELL" : "Haswell",
167 "REQUIRE_HASWELL" : "Haswell",
168 "PREFER_BROADWELL" : "Broadwell",
169 "REQUIRE_BROADWELL" : "Broadwell",
170 "PREFER_NEHALEM" : "Nehalem",
171 "REQUIRE_NEHALEM" : "Nehalem",
172 "PREFER_PENRYN" : "Penryn",
173 "REQUIRE_PENRYN" : "Penryn",
174 "PREFER_CONROE" : "Conroe",
175 "REQUIRE_CONROE" : "Conroe",
176 "PREFER_CORE2DUO" : "Core2Duo",
177 "REQUIRE_CORE2DUO" : "Core2Duo",
180 self
._espec
_to
_mano
_cpumodel
= {
181 "Westmere" : "REQUIRE_WESTMERE",
182 "SandyBridge" : "REQUIRE_SANDYBRIDGE",
183 "IvyBridge" : "REQUIRE_IVYBRIDGE",
184 "Haswell" : "REQUIRE_HASWELL",
185 "Broadwell" : "REQUIRE_BROADWELL",
186 "Nehalem" : "REQUIRE_NEHALEM",
187 "Penryn" : "REQUIRE_PENRYN",
188 "Conroe" : "REQUIRE_CONROE",
189 "Core2Duo" : "REQUIRE_CORE2DUO",
192 self
._mano
_to
_espec
_cpuarch
= {
193 "PREFER_X86" : "x86",
194 "REQUIRE_X86" : "x86",
195 "PREFER_X86_64" : "x86_64",
196 "REQUIRE_X86_64" : "x86_64",
197 "PREFER_I686" : "i686",
198 "REQUIRE_I686" : "i686",
199 "PREFER_IA64" : "ia64",
200 "REQUIRE_IA64" : "ia64",
201 "PREFER_ARMV7" : "ARMv7",
202 "REQUIRE_ARMV7" : "ARMv7",
203 "PREFER_ARMV8" : "ARMv8-A",
204 "REQUIRE_ARMV8" : "ARMv8-A",
207 self
._espec
_to
_mano
_cpuarch
= {
208 "x86" : "REQUIRE_X86",
209 "x86_64" : "REQUIRE_X86_64",
210 "i686" : "REQUIRE_I686",
211 "ia64" : "REQUIRE_IA64",
212 "ARMv7-A" : "REQUIRE_ARMV7",
213 "ARMv8-A" : "REQUIRE_ARMV8",
216 self
._mano
_to
_espec
_cpuvendor
= {
217 "PREFER_INTEL" : "Intel",
218 "REQUIRE_INTEL" : "Intel",
219 "PREFER_AMD" : "AMD",
220 "REQUIRE_AMD" : "AMD",
223 self
._espec
_to
_mano
_cpuvendor
= {
224 "Intel" : "REQUIRE_INTEL",
225 "AMD" : "REQUIRE_AMD",
228 self
._mano
_to
_espec
_cpufeatures
= {
229 "PREFER_AES" : "aes",
230 "REQUIRE_AES" : "aes",
231 "REQUIRE_VME" : "vme",
232 "PREFER_VME" : "vme",
235 "REQUIRE_PSE" : "pse",
236 "PREFER_PSE" : "pse",
237 "REQUIRE_TSC" : "tsc",
238 "PREFER_TSC" : "tsc",
239 "REQUIRE_MSR" : "msr",
240 "PREFER_MSR" : "msr",
241 "REQUIRE_PAE" : "pae",
242 "PREFER_PAE" : "pae",
243 "REQUIRE_MCE" : "mce",
244 "PREFER_MCE" : "mce",
245 "REQUIRE_CX8" : "cx8",
246 "PREFER_CX8" : "cx8",
247 "REQUIRE_APIC" : "apic",
248 "PREFER_APIC" : "apic",
249 "REQUIRE_SEP" : "sep",
250 "PREFER_SEP" : "sep",
251 "REQUIRE_MTRR" : "mtrr",
252 "PREFER_MTRR" : "mtrr",
253 "REQUIRE_PGE" : "pge",
254 "PREFER_PGE" : "pge",
255 "REQUIRE_MCA" : "mca",
256 "PREFER_MCA" : "mca",
257 "REQUIRE_CMOV" : "cmov",
258 "PREFER_CMOV" : "cmov",
259 "REQUIRE_PAT" : "pat",
260 "PREFER_PAT" : "pat",
261 "REQUIRE_PSE36" : "pse36",
262 "PREFER_PSE36" : "pse36",
263 "REQUIRE_CLFLUSH" : "clflush",
264 "PREFER_CLFLUSH" : "clflush",
265 "REQUIRE_DTS" : "dts",
266 "PREFER_DTS" : "dts",
267 "REQUIRE_ACPI" : "acpi",
268 "PREFER_ACPI" : "acpi",
269 "REQUIRE_MMX" : "mmx",
270 "PREFER_MMX" : "mmx",
271 "REQUIRE_FXSR" : "fxsr",
272 "PREFER_FXSR" : "fxsr",
273 "REQUIRE_SSE" : "sse",
274 "PREFER_SSE" : "sse",
275 "REQUIRE_SSE2" : "sse2",
276 "PREFER_SSE2" : "sse2",
283 "REQUIRE_IA64" : "ia64",
284 "PREFER_IA64" : "ia64",
285 "REQUIRE_PBE" : "pbe",
286 "PREFER_PBE" : "pbe",
287 "REQUIRE_RDTSCP" : "rdtscp",
288 "PREFER_RDTSCP" : "rdtscp",
289 "REQUIRE_PNI" : "pni",
290 "PREFER_PNI" : "pni",
291 "REQUIRE_PCLMULQDQ": "pclmulqdq",
292 "PREFER_PCLMULQDQ" : "pclmulqdq",
293 "REQUIRE_DTES64" : "dtes64",
294 "PREFER_DTES64" : "dtes64",
295 "REQUIRE_MONITOR" : "monitor",
296 "PREFER_MONITOR" : "monitor",
297 "REQUIRE_DS_CPL" : "ds_cpl",
298 "PREFER_DS_CPL" : "ds_cpl",
299 "REQUIRE_VMX" : "vmx",
300 "PREFER_VMX" : "vmx",
301 "REQUIRE_SMX" : "smx",
302 "PREFER_SMX" : "smx",
303 "REQUIRE_EST" : "est",
304 "PREFER_EST" : "est",
305 "REQUIRE_TM2" : "tm2",
306 "PREFER_TM2" : "tm2",
307 "REQUIRE_SSSE3" : "ssse3",
308 "PREFER_SSSE3" : "ssse3",
309 "REQUIRE_CID" : "cid",
310 "PREFER_CID" : "cid",
311 "REQUIRE_FMA" : "fma",
312 "PREFER_FMA" : "fma",
313 "REQUIRE_CX16" : "cx16",
314 "PREFER_CX16" : "cx16",
315 "REQUIRE_XTPR" : "xtpr",
316 "PREFER_XTPR" : "xtpr",
317 "REQUIRE_PDCM" : "pdcm",
318 "PREFER_PDCM" : "pdcm",
319 "REQUIRE_PCID" : "pcid",
320 "PREFER_PCID" : "pcid",
321 "REQUIRE_DCA" : "dca",
322 "PREFER_DCA" : "dca",
323 "REQUIRE_SSE4_1" : "sse4_1",
324 "PREFER_SSE4_1" : "sse4_1",
325 "REQUIRE_SSE4_2" : "sse4_2",
326 "PREFER_SSE4_2" : "sse4_2",
327 "REQUIRE_X2APIC" : "x2apic",
328 "PREFER_X2APIC" : "x2apic",
329 "REQUIRE_MOVBE" : "movbe",
330 "PREFER_MOVBE" : "movbe",
331 "REQUIRE_POPCNT" : "popcnt",
332 "PREFER_POPCNT" : "popcnt",
333 "REQUIRE_TSC_DEADLINE_TIMER" : "tsc_deadline_timer",
334 "PREFER_TSC_DEADLINE_TIMER" : "tsc_deadline_timer",
335 "REQUIRE_XSAVE" : "xsave",
336 "PREFER_XSAVE" : "xsave",
337 "REQUIRE_AVX" : "avx",
338 "PREFER_AVX" : "avx",
339 "REQUIRE_F16C" : "f16c",
340 "PREFER_F16C" : "f16c",
341 "REQUIRE_RDRAND" : "rdrand",
342 "PREFER_RDRAND" : "rdrand",
343 "REQUIRE_FSGSBASE" : "fsgsbase",
344 "PREFER_FSGSBASE" : "fsgsbase",
345 "REQUIRE_BMI1" : "bmi1",
346 "PREFER_BMI1" : "bmi1",
347 "REQUIRE_HLE" : "hle",
348 "PREFER_HLE" : "hle",
349 "REQUIRE_AVX2" : "avx2",
350 "PREFER_AVX2" : "avx2",
351 "REQUIRE_SMEP" : "smep",
352 "PREFER_SMEP" : "smep",
353 "REQUIRE_BMI2" : "bmi2",
354 "PREFER_BMI2" : "bmi2",
355 "REQUIRE_ERMS" : "erms",
356 "PREFER_ERMS" : "erms",
357 "REQUIRE_INVPCID" : "invpcid",
358 "PREFER_INVPCID" : "invpcid",
359 "REQUIRE_RTM" : "rtm",
360 "PREFER_RTM" : "rtm",
361 "REQUIRE_MPX" : "mpx",
362 "PREFER_MPX" : "mpx",
363 "REQUIRE_RDSEED" : "rdseed",
364 "PREFER_RDSEED" : "rdseed",
365 "REQUIRE_ADX" : "adx",
366 "PREFER_ADX" : "adx",
367 "REQUIRE_SMAP" : "smap",
368 "PREFER_SMAP" : "smap",
371 self
._espec
_to
_mano
_cpufeatures
= {
372 "aes" : "REQUIRE_AES",
373 "vme" : "REQUIRE_VME",
375 "pse" : "REQUIRE_PSE",
376 "tsc" : "REQUIRE_TSC",
377 "msr" : "REQUIRE_MSR",
378 "pae" : "REQUIRE_PAE",
379 "mce" : "REQUIRE_MCE",
380 "cx8" : "REQUIRE_CX8",
381 "apic" : "REQUIRE_APIC",
382 "sep" : "REQUIRE_SEP",
383 "mtrr" : "REQUIRE_MTRR",
384 "pge" : "REQUIRE_PGE",
385 "mca" : "REQUIRE_MCA",
386 "cmov" : "REQUIRE_CMOV",
387 "pat" : "REQUIRE_PAT",
388 "pse36" : "REQUIRE_PSE36",
389 "clflush" : "REQUIRE_CLFLUSH",
390 "dts" : "REQUIRE_DTS",
391 "acpi" : "REQUIRE_ACPI",
392 "mmx" : "REQUIRE_MMX",
393 "fxsr" : "REQUIRE_FXSR",
394 "sse" : "REQUIRE_SSE",
395 "sse2" : "REQUIRE_SSE2",
399 "ia64" : "REQUIRE_IA64",
400 "pbe" : "REQUIRE_PBE",
401 "rdtscp" : "REQUIRE_RDTSCP",
402 "pni" : "REQUIRE_PNI",
403 "pclmulqdq": "REQUIRE_PCLMULQDQ",
404 "dtes64" : "REQUIRE_DTES64",
405 "monitor" : "REQUIRE_MONITOR",
406 "ds_cpl" : "REQUIRE_DS_CPL",
407 "vmx" : "REQUIRE_VMX",
408 "smx" : "REQUIRE_SMX",
409 "est" : "REQUIRE_EST",
410 "tm2" : "REQUIRE_TM2",
411 "ssse3" : "REQUIRE_SSSE3",
412 "cid" : "REQUIRE_CID",
413 "fma" : "REQUIRE_FMA",
414 "cx16" : "REQUIRE_CX16",
415 "xtpr" : "REQUIRE_XTPR",
416 "pdcm" : "REQUIRE_PDCM",
417 "pcid" : "REQUIRE_PCID",
418 "dca" : "REQUIRE_DCA",
419 "sse4_1" : "REQUIRE_SSE4_1",
420 "sse4_2" : "REQUIRE_SSE4_2",
421 "x2apic" : "REQUIRE_X2APIC",
422 "movbe" : "REQUIRE_MOVBE",
423 "popcnt" : "REQUIRE_POPCNT",
424 "tsc_deadline_timer" : "REQUIRE_TSC_DEADLINE_TIMER",
425 "xsave" : "REQUIRE_XSAVE",
426 "avx" : "REQUIRE_AVX",
427 "f16c" : "REQUIRE_F16C",
428 "rdrand" : "REQUIRE_RDRAND",
429 "fsgsbase" : "REQUIRE_FSGSBASE",
430 "bmi1" : "REQUIRE_BMI1",
431 "hle" : "REQUIRE_HLE",
432 "avx2" : "REQUIRE_AVX2",
433 "smep" : "REQUIRE_SMEP",
434 "bmi2" : "REQUIRE_BMI2",
435 "erms" : "REQUIRE_ERMS",
436 "invpcid" : "REQUIRE_INVPCID",
437 "rtm" : "REQUIRE_RTM",
438 "mpx" : "REQUIRE_MPX",
439 "rdseed" : "REQUIRE_RDSEED",
440 "adx" : "REQUIRE_ADX",
441 "smap" : "REQUIRE_SMAP",
444 def mano_to_extra_spec_cpu_model(self
, cpu_model
):
445 if cpu_model
in self
._mano
_to
_espec
_cpumodel
:
446 return self
._mano
_to
_espec
_cpumodel
[cpu_model
]
450 def extra_specs_to_mano_cpu_model(self
, cpu_model
):
451 if cpu_model
in self
._espec
_to
_mano
_cpumodel
:
452 return self
._espec
_to
_mano
_cpumodel
[cpu_model
]
456 def mano_to_extra_spec_cpu_arch(self
, cpu_arch
):
457 if cpu_arch
in self
._mano
_to
_espec
_cpuarch
:
458 return self
._mano
_to
_espec
_cpuarch
[cpu_arch
]
462 def extra_specs_to_mano_cpu_arch(self
, cpu_arch
):
463 if cpu_arch
in self
._espec
_to
_mano
_cpuarch
:
464 return self
._espec
_to
_mano
_cpuarch
[cpu_arch
]
468 def mano_to_extra_spec_cpu_vendor(self
, cpu_vendor
):
469 if cpu_vendor
in self
._mano
_to
_espec
_cpuvendor
:
470 return self
._mano
_to
_espec
_cpuvendor
[cpu_vendor
]
474 def extra_spec_to_mano_cpu_vendor(self
, cpu_vendor
):
475 if cpu_vendor
in self
._espec
_to
_mano
_cpuvendor
:
476 return self
._espec
_to
_mano
_cpuvendor
[cpu_vendor
]
480 def mano_to_extra_spec_cpu_socket_count(self
, cpu_sockets
):
483 def extra_spec_to_mano_cpu_socket_count(self
, cpu_sockets
):
484 return int(cpu_sockets
)
486 def mano_to_extra_spec_cpu_core_count(self
, cpu_core_count
):
487 return cpu_core_count
489 def extra_spec_to_mano_cpu_core_count(self
, cpu_core_count
):
490 return int(cpu_core_count
)
492 def mano_to_extra_spec_cpu_core_thread_count(self
, core_thread_count
):
493 return core_thread_count
495 def extra_spec_to_mano_cpu_core_thread_count(self
, core_thread_count
):
496 return int(core_thread_count
)
498 def mano_to_extra_spec_cpu_features(self
, features
):
500 epa_feature_str
= None
502 if f
in self
._mano
_to
_espec
_cpufeatures
:
503 cpu_features
.append(self
._mano
_to
_espec
_cpufeatures
[f
])
505 if len(cpu_features
) > 1:
506 epa_feature_str
= '<all-in> '+ " ".join(cpu_features
)
507 elif len(cpu_features
) == 1:
508 epa_feature_str
= " ".join(cpu_features
)
510 return epa_feature_str
512 def extra_spec_to_mano_cpu_features(self
, features
):
513 oper_symbols
= ['=', '<in>', '<all-in>', '==', '!=', '>=', '<=', 's==', 's!=', 's<', 's<=', 's>', 's>=']
516 for oper
in oper_symbols
:
517 regex
= '^'+oper
+' (.*?)$'
518 result
= re
.search(regex
, features
)
519 if result
is not None:
522 if result
is not None:
523 feature_list
= result
.group(1)
525 feature_list
= features
527 for f
in feature_list
.split():
528 if f
in self
._espec
_to
_mano
_cpufeatures
:
529 cpu_features
.append(self
._espec
_to
_mano
_cpufeatures
[f
])
534 class ExtraSpecUtils(object):
536 General utility class for flavor Extra Specs processing
539 self
.host
= HostEPAUtils()
540 self
.guest
= GuestEPAUtils()
541 self
.extra_specs_keywords
= [ 'hw:cpu_policy',
542 'hw:cpu_threads_policy',
548 'trust:trusted_host',
549 'pci_passthrough:alias',
550 'capabilities:cpu_info:model',
551 'capabilities:cpu_info:arch',
552 'capabilities:cpu_info:vendor',
553 'capabilities:cpu_info:topology:sockets',
554 'capabilities:cpu_info:topology:cores',
555 'capabilities:cpu_info:topology:threads',
556 'capabilities:cpu_info:features',
558 self
.extra_specs_regex
= re
.compile("^"+"|^".join(self
.extra_specs_keywords
))
562 class FlavorUtils(object):
564 Utility class for handling the flavor
566 def __init__(self
, driver
):
568 Constructor for class
570 driver: object of OpenstackDriver()
572 self
._epa
= ExtraSpecUtils()
573 self
._driver
= driver
574 self
.log
= driver
.log
580 def _get_guest_epa_specs(self
, guest_epa
):
582 Returns EPA Specs dictionary for guest_epa attributes
585 if guest_epa
.has_field('mempage_size'):
586 mempage_size
= self
._epa
.guest
.mano_to_extra_spec_mempage_size(guest_epa
.mempage_size
)
587 if mempage_size
is not None:
588 epa_specs
['hw:mem_page_size'] = mempage_size
590 if guest_epa
.has_field('cpu_pinning_policy'):
591 cpu_pinning_policy
= self
._epa
.guest
.mano_to_extra_spec_cpu_pinning_policy(guest_epa
.cpu_pinning_policy
)
592 if cpu_pinning_policy
is not None:
593 epa_specs
['hw:cpu_policy'] = cpu_pinning_policy
595 if guest_epa
.has_field('cpu_thread_pinning_policy'):
596 cpu_thread_pinning_policy
= self
._epa
.guest
.mano_to_extra_spec_cpu_thread_pinning_policy(guest_epa
.cpu_thread_pinning_policy
)
597 if cpu_thread_pinning_policy
is None:
598 epa_specs
['hw:cpu_threads_policy'] = cpu_thread_pinning_policy
600 if guest_epa
.has_field('trusted_execution'):
601 trusted_execution
= self
._epa
.guest
.mano_to_extra_spec_trusted_execution(guest_epa
.trusted_execution
)
602 if trusted_execution
is not None:
603 epa_specs
['trust:trusted_host'] = trusted_execution
605 if guest_epa
.has_field('numa_node_policy'):
606 if guest_epa
.numa_node_policy
.has_field('node_cnt'):
607 numa_node_count
= self
._epa
.guest
.mano_to_extra_spec_numa_node_count(guest_epa
.numa_node_policy
.node_cnt
)
608 if numa_node_count
is not None:
609 epa_specs
['hw:numa_nodes'] = numa_node_count
611 if guest_epa
.numa_node_policy
.has_field('mem_policy'):
612 numa_memory_policy
= self
._epa
.guest
.mano_to_extra_spec_numa_memory_policy(guest_epa
.numa_node_policy
.mem_policy
)
613 if numa_memory_policy
is not None:
614 epa_specs
['hw:numa_mempolicy'] = numa_memory_policy
616 if guest_epa
.numa_node_policy
.has_field('node'):
617 for node
in guest_epa
.numa_node_policy
.node
:
618 if node
.has_field('vcpu') and node
.vcpu
:
619 epa_specs
['hw:numa_cpus.'+str(node
.id)] = ','.join([str(j
.id) for j
in node
.vcpu
])
621 epa_specs
['hw:numa_mem.'+str(node
.id)] = str(node
.memory_mb
)
623 if guest_epa
.has_field('pcie_device'):
625 for device
in guest_epa
.pcie_device
:
626 pci_devices
.append(device
.device_id
+':'+str(device
.count
))
627 epa_specs
['pci_passthrough:alias'] = ','.join(pci_devices
)
631 def _get_host_epa_specs(self
,host_epa
):
633 Returns EPA Specs dictionary for host_epa attributes
637 if host_epa
.has_field('cpu_model'):
638 cpu_model
= self
._epa
.host
.mano_to_extra_spec_cpu_model(host_epa
.cpu_model
)
639 if cpu_model
is not None:
640 epa_specs
['capabilities:cpu_info:model'] = cpu_model
642 if host_epa
.has_field('cpu_arch'):
643 cpu_arch
= self
._epa
.host
.mano_to_extra_spec_cpu_arch(host_epa
.cpu_arch
)
644 if cpu_arch
is not None:
645 epa_specs
['capabilities:cpu_info:arch'] = cpu_arch
647 if host_epa
.has_field('cpu_vendor'):
648 cpu_vendor
= self
._epa
.host
.mano_to_extra_spec_cpu_vendor(host_epa
.cpu_vendor
)
649 if cpu_vendor
is not None:
650 epa_specs
['capabilities:cpu_info:vendor'] = cpu_vendor
652 if host_epa
.has_field('cpu_socket_count'):
653 cpu_socket_count
= self
._epa
.host
.mano_to_extra_spec_cpu_socket_count(host_epa
.cpu_socket_count
)
654 if cpu_socket_count
is not None:
655 epa_specs
['capabilities:cpu_info:topology:sockets'] = cpu_socket_count
657 if host_epa
.has_field('cpu_core_count'):
658 cpu_core_count
= self
._epa
.host
.mano_to_extra_spec_cpu_core_count(host_epa
.cpu_core_count
)
659 if cpu_core_count
is not None:
660 epa_specs
['capabilities:cpu_info:topology:cores'] = cpu_core_count
662 if host_epa
.has_field('cpu_core_thread_count'):
663 cpu_core_thread_count
= self
._epa
.host
.mano_to_extra_spec_cpu_core_thread_count(host_epa
.cpu_core_thread_count
)
664 if cpu_core_thread_count
is not None:
665 epa_specs
['capabilities:cpu_info:topology:threads'] = cpu_core_thread_count
667 if host_epa
.has_field('cpu_feature'):
669 espec_cpu_features
= []
670 for feature
in host_epa
.cpu_feature
:
671 cpu_features
.append(feature
.feature
)
672 espec_cpu_features
= self
._epa
.host
.mano_to_extra_spec_cpu_features(cpu_features
)
673 if espec_cpu_features
is not None:
674 epa_specs
['capabilities:cpu_info:features'] = espec_cpu_features
677 def _get_hypervisor_epa_specs(self
,guest_epa
):
679 Returns EPA Specs dictionary for hypervisor_epa attributes
681 hypervisor_epa
= dict()
682 return hypervisor_epa
684 def _get_vswitch_epa_specs(self
, guest_epa
):
686 Returns EPA Specs dictionary for vswitch_epa attributes
691 def _get_host_aggregate_epa_specs(self
, host_aggregate
):
693 Returns EPA Specs dictionary for host aggregates
696 for aggregate
in host_aggregate
:
697 epa_specs
['aggregate_instance_extra_specs:'+aggregate
.metadata_key
] = aggregate
.metadata_value
701 def get_extra_specs(self
, flavor
):
703 Returns epa_specs dictionary based on flavor information
705 flavor -- Protobuf GI object for flavor_info (RwcalYang.FlavorInfoItem())
707 A dictionary of extra_specs in format understood by novaclient library
710 if flavor
.has_field('guest_epa'):
711 guest_epa
= self
._get
_guest
_epa
_specs
(flavor
.guest_epa
)
712 epa_specs
.update(guest_epa
)
713 if flavor
.has_field('host_epa'):
714 host_epa
= self
._get
_host
_epa
_specs
(flavor
.host_epa
)
715 epa_specs
.update(host_epa
)
716 if flavor
.has_field('hypervisor_epa'):
717 hypervisor_epa
= self
._get
_hypervisor
_epa
_specs
(flavor
.hypervisor_epa
)
718 epa_specs
.update(hypervisor_epa
)
719 if flavor
.has_field('vswitch_epa'):
720 vswitch_epa
= self
._get
_vswitch
_epa
_specs
(flavor
.vswitch_epa
)
721 epa_specs
.update(vswitch_epa
)
722 if flavor
.has_field('host_aggregate'):
723 host_aggregate
= self
._get
_host
_aggregate
_epa
_specs
(flavor
.host_aggregate
)
724 epa_specs
.update(host_aggregate
)
728 def parse_vm_flavor_epa_info(self
, flavor_info
):
730 Parse the flavor_info dictionary (returned by python-client) for vm_flavor
733 flavor_info: A dictionary object return by novaclient library listing flavor attributes
736 vm_flavor = RwcalYang.FlavorInfoItem_VmFlavor()
738 vm_flavor
= RwcalYang
.FlavorInfoItem_VmFlavor()
740 if 'vcpus' in flavor_info
and flavor_info
['vcpus']:
741 vm_flavor
.vcpu_count
= flavor_info
['vcpus']
743 if 'ram' in flavor_info
and flavor_info
['ram']:
744 vm_flavor
.memory_mb
= flavor_info
['ram']
746 if 'disk' in flavor_info
and flavor_info
['disk']:
747 vm_flavor
.storage_gb
= flavor_info
['disk']
751 def parse_guest_epa_info(self
, flavor_info
):
753 Parse the flavor_info dictionary (returned by python-client) for guest_epa
756 flavor_info: A dictionary object return by novaclient library listing flavor attributes
759 guest_epa = RwcalYang.FlavorInfoItem_GuestEpa()
761 guest_epa
= RwcalYang
.FlavorInfoItem_GuestEpa()
762 for attr
in flavor_info
['extra_specs']:
763 if attr
== 'hw:cpu_policy':
764 cpu_pinning_policy
= self
._epa
.guest
.extra_spec_to_mano_cpu_pinning_policy(flavor_info
['extra_specs']['hw:cpu_policy'])
765 if cpu_pinning_policy
is not None:
766 guest_epa
.cpu_pinning_policy
= cpu_pinning_policy
768 elif attr
== 'hw:cpu_threads_policy':
769 cpu_thread_pinning_policy
= self
._epa
.guest
.extra_spec_to_mano_cpu_thread_pinning_policy(flavor_info
['extra_specs']['hw:cpu_threads_policy'])
770 if cpu_thread_pinning_policy
is not None:
771 guest_epa
.cpu_thread_pinning_policy
= cpu_thread_pinning_policy
773 elif attr
== 'hw:mem_page_size':
774 mempage_size
= self
._epa
.guest
.extra_spec_to_mano_mempage_size(flavor_info
['extra_specs']['hw:mem_page_size'])
775 if mempage_size
is not None:
776 guest_epa
.mempage_size
= mempage_size
778 elif attr
== 'hw:numa_nodes':
779 numa_node_count
= self
._epa
.guest
.extra_specs_to_mano_numa_node_count(flavor_info
['extra_specs']['hw:numa_nodes'])
780 if numa_node_count
is not None:
781 guest_epa
.numa_node_policy
.node_cnt
= numa_node_count
783 elif attr
.startswith('hw:numa_cpus.'):
784 node_id
= attr
.split('.')[1]
785 nodes
= [ n
for n
in guest_epa
.numa_node_policy
.node
if n
.id == int(node_id
) ]
789 numa_node
= guest_epa
.numa_node_policy
.node
.add()
790 numa_node
.id = int(node_id
)
792 for x
in flavor_info
['extra_specs'][attr
].split(','):
793 numa_node_vcpu
= numa_node
.vcpu
.add()
794 numa_node_vcpu
.id = int(x
)
796 elif attr
.startswith('hw:numa_mem.'):
797 node_id
= attr
.split('.')[1]
798 nodes
= [ n
for n
in guest_epa
.numa_node_policy
.node
if n
.id == int(node_id
) ]
802 numa_node
= guest_epa
.numa_node_policy
.node
.add()
803 numa_node
.id = int(node_id
)
805 numa_node
.memory_mb
= int(flavor_info
['extra_specs'][attr
])
807 elif attr
== 'hw:numa_mempolicy':
808 numa_memory_policy
= self
._epa
.guest
.extra_to_mano_spec_numa_memory_policy(flavor_info
['extra_specs']['hw:numa_mempolicy'])
809 if numa_memory_policy
is not None:
810 guest_epa
.numa_node_policy
.mem_policy
= numa_memory_policy
812 elif attr
== 'trust:trusted_host':
813 trusted_execution
= self
._epa
.guest
.extra_spec_to_mano_trusted_execution(flavor_info
['extra_specs']['trust:trusted_host'])
814 if trusted_execution
is not None:
815 guest_epa
.trusted_execution
= trusted_execution
817 elif attr
== 'pci_passthrough:alias':
818 device_types
= flavor_info
['extra_specs']['pci_passthrough:alias']
819 for device
in device_types
.split(','):
820 dev
= guest_epa
.pcie_device
.add()
821 dev
.device_id
= device
.split(':')[0]
822 dev
.count
= int(device
.split(':')[1])
825 def parse_host_epa_info(self
, flavor_info
):
827 Parse the flavor_info dictionary (returned by python-client) for host_epa
830 flavor_info: A dictionary object return by novaclient library listing flavor attributes
833 host_epa = RwcalYang.FlavorInfoItem_HostEpa()
835 host_epa
= RwcalYang
.FlavorInfoItem_HostEpa()
836 for attr
in flavor_info
['extra_specs']:
837 if attr
== 'capabilities:cpu_info:model':
838 cpu_model
= self
._epa
.host
.extra_specs_to_mano_cpu_model(flavor_info
['extra_specs']['capabilities:cpu_info:model'])
839 if cpu_model
is not None:
840 host_epa
.cpu_model
= cpu_model
842 elif attr
== 'capabilities:cpu_info:arch':
843 cpu_arch
= self
._epa
.host
.extra_specs_to_mano_cpu_arch(flavor_info
['extra_specs']['capabilities:cpu_info:arch'])
844 if cpu_arch
is not None:
845 host_epa
.cpu_arch
= cpu_arch
847 elif attr
== 'capabilities:cpu_info:vendor':
848 cpu_vendor
= self
._epa
.host
.extra_spec_to_mano_cpu_vendor(flavor_info
['extra_specs']['capabilities:cpu_info:vendor'])
849 if cpu_vendor
is not None:
850 host_epa
.cpu_vendor
= cpu_vendor
852 elif attr
== 'capabilities:cpu_info:topology:sockets':
853 cpu_sockets
= self
._epa
.host
.extra_spec_to_mano_cpu_socket_count(flavor_info
['extra_specs']['capabilities:cpu_info:topology:sockets'])
854 if cpu_sockets
is not None:
855 host_epa
.cpu_socket_count
= cpu_sockets
857 elif attr
== 'capabilities:cpu_info:topology:cores':
858 cpu_cores
= self
._epa
.host
.extra_spec_to_mano_cpu_core_count(flavor_info
['extra_specs']['capabilities:cpu_info:topology:cores'])
859 if cpu_cores
is not None:
860 host_epa
.cpu_core_count
= cpu_cores
862 elif attr
== 'capabilities:cpu_info:topology:threads':
863 cpu_threads
= self
._epa
.host
.extra_spec_to_mano_cpu_core_thread_count(flavor_info
['extra_specs']['capabilities:cpu_info:topology:threads'])
864 if cpu_threads
is not None:
865 host_epa
.cpu_core_thread_count
= cpu_threads
867 elif attr
== 'capabilities:cpu_info:features':
868 cpu_features
= self
._epa
.host
.extra_spec_to_mano_cpu_features(flavor_info
['extra_specs']['capabilities:cpu_info:features'])
869 if cpu_features
is not None:
870 for feature
in cpu_features
:
871 host_epa
.cpu_feature
.append(feature
)
874 def parse_host_aggregate_epa_info(self
, flavor_info
):
876 Parse the flavor_info dictionary (returned by python-client) for host_aggregate
879 flavor_info: A dictionary object return by novaclient library listing flavor attributes
882 A list of objects host_aggregate of type RwcalYang.FlavorInfoItem_HostAggregate()
884 host_aggregates
= list()
885 for attr
in flavor_info
['extra_specs']:
886 if attr
.startswith('aggregate_instance_extra_specs:'):
887 aggregate
= RwcalYang
.FlavorInfoItem_HostAggregate()
888 aggregate
.metadata_key
= ":".join(attr
.split(':')[1::])
889 aggregate
.metadata_value
= flavor_info
['extra_specs'][attr
]
890 host_aggregates
.append(aggregate
)
891 return host_aggregates
894 def parse_flavor_info(self
, flavor_info
):
896 Parse the flavor_info dictionary and put value in RIFT GI object for flavor
898 flavor_info: A dictionary object returned by novaclient library listing flavor attributes
901 Protobuf GI Object of type RwcalYang.FlavorInfoItem()
904 flavor
= RwcalYang
.FlavorInfoItem()
905 if 'name' in flavor_info
and flavor_info
['name']:
906 flavor
.name
= flavor_info
['name']
907 if 'id' in flavor_info
and flavor_info
['id']:
908 flavor
.id = flavor_info
['id']
910 ### If extra_specs in flavor_info
911 if 'extra_specs' in flavor_info
:
912 flavor
.vm_flavor
= self
.parse_vm_flavor_epa_info(flavor_info
)
913 flavor
.guest_epa
= self
.parse_guest_epa_info(flavor_info
)
914 flavor
.host_epa
= self
.parse_host_epa_info(flavor_info
)
915 for aggr
in self
.parse_host_aggregate_epa_info(flavor_info
):
916 ha
= flavor
.host_aggregate
.add()
917 ha
.from_dict(aggr
.as_dict())
920 def _match_vm_flavor(self
, required
, available
):
921 self
.log
.info("Matching VM Flavor attributes")
922 if available
.vcpu_count
!= required
.vcpu_count
:
923 self
.log
.debug("VCPU requirement mismatch. Required: %d, Available: %d",
925 available
.vcpu_count
)
927 if available
.memory_mb
!= required
.memory_mb
:
928 self
.log
.debug("Memory requirement mismatch. Required: %d MB, Available: %d MB",
932 if available
.storage_gb
!= required
.storage_gb
:
933 self
.log
.debug("Storage requirement mismatch. Required: %d GB, Available: %d GB",
935 available
.storage_gb
)
937 self
.log
.debug("VM Flavor match found")
940 def _match_guest_epa(self
, required
, available
):
941 self
.log
.info("Matching Guest EPA attributes")
942 if required
.has_field('pcie_device'):
943 self
.log
.debug("Matching pcie_device")
944 if available
.has_field('pcie_device') == False:
945 self
.log
.debug("Matching pcie_device failed. Not available in flavor")
948 for dev
in required
.pcie_device
:
949 if not [ d
for d
in available
.pcie_device
950 if ((d
.device_id
== dev
.device_id
) and (d
.count
== dev
.count
)) ]:
951 self
.log
.debug("Matching pcie_device failed. Required: %s, Available: %s",
952 required
.pcie_device
, available
.pcie_device
)
954 elif available
.has_field('pcie_device'):
955 self
.log
.debug("Rejecting available flavor because pcie_device not required but available")
959 if required
.has_field('mempage_size'):
960 self
.log
.debug("Matching mempage_size")
961 if available
.has_field('mempage_size') == False:
962 self
.log
.debug("Matching mempage_size failed. Not available in flavor")
965 if required
.mempage_size
!= available
.mempage_size
:
966 self
.log
.debug("Matching mempage_size failed. Required: %s, Available: %s",
967 required
.mempage_size
, available
.mempage_size
)
969 elif available
.has_field('mempage_size'):
970 self
.log
.debug("Rejecting available flavor because mempage_size not required but available")
973 if required
.has_field('cpu_pinning_policy'):
974 self
.log
.debug("Matching cpu_pinning_policy")
975 if required
.cpu_pinning_policy
!= 'ANY':
976 if available
.has_field('cpu_pinning_policy') == False:
977 self
.log
.debug("Matching cpu_pinning_policy failed. Not available in flavor")
980 if required
.cpu_pinning_policy
!= available
.cpu_pinning_policy
:
981 self
.log
.debug("Matching cpu_pinning_policy failed. Required: %s, Available: %s",
982 required
.cpu_pinning_policy
, available
.cpu_pinning_policy
)
984 elif available
.has_field('cpu_pinning_policy'):
985 self
.log
.debug("Rejecting available flavor because cpu_pinning_policy not required but available")
988 if required
.has_field('cpu_thread_pinning_policy'):
989 self
.log
.debug("Matching cpu_thread_pinning_policy")
990 if available
.has_field('cpu_thread_pinning_policy') == False:
991 self
.log
.debug("Matching cpu_thread_pinning_policy failed. Not available in flavor")
994 if required
.cpu_thread_pinning_policy
!= available
.cpu_thread_pinning_policy
:
995 self
.log
.debug("Matching cpu_thread_pinning_policy failed. Required: %s, Available: %s",
996 required
.cpu_thread_pinning_policy
, available
.cpu_thread_pinning_policy
)
998 elif available
.has_field('cpu_thread_pinning_policy'):
999 self
.log
.debug("Rejecting available flavor because cpu_thread_pinning_policy not required but available")
1002 if required
.has_field('trusted_execution'):
1003 self
.log
.debug("Matching trusted_execution")
1004 if required
.trusted_execution
== True:
1005 if available
.has_field('trusted_execution') == False:
1006 self
.log
.debug("Matching trusted_execution failed. Not available in flavor")
1009 if required
.trusted_execution
!= available
.trusted_execution
:
1010 self
.log
.debug("Matching trusted_execution failed. Required: %s, Available: %s",
1011 required
.trusted_execution
, available
.trusted_execution
)
1013 elif available
.has_field('trusted_execution'):
1014 self
.log
.debug("Rejecting available flavor because trusted_execution not required but available")
1017 if required
.has_field('numa_node_policy'):
1018 self
.log
.debug("Matching numa_node_policy")
1019 if available
.has_field('numa_node_policy') == False:
1020 self
.log
.debug("Matching numa_node_policy failed. Not available in flavor")
1023 if required
.numa_node_policy
.has_field('node_cnt'):
1024 self
.log
.debug("Matching numa_node_policy node_cnt")
1025 if available
.numa_node_policy
.has_field('node_cnt') == False:
1026 self
.log
.debug("Matching numa_node_policy node_cnt failed. Not available in flavor")
1029 if required
.numa_node_policy
.node_cnt
!= available
.numa_node_policy
.node_cnt
:
1030 self
.log
.debug("Matching numa_node_policy node_cnt failed. Required: %s, Available: %s",
1031 required
.numa_node_policy
.node_cnt
, available
.numa_node_policy
.node_cnt
)
1033 elif available
.numa_node_policy
.has_field('node_cnt'):
1034 self
.log
.debug("Rejecting available flavor because numa node count not required but available")
1037 if required
.numa_node_policy
.has_field('mem_policy'):
1038 self
.log
.debug("Matching numa_node_policy mem_policy")
1039 if available
.numa_node_policy
.has_field('mem_policy') == False:
1040 self
.log
.debug("Matching numa_node_policy mem_policy failed. Not available in flavor")
1043 if required
.numa_node_policy
.mem_policy
!= available
.numa_node_policy
.mem_policy
:
1044 self
.log
.debug("Matching numa_node_policy mem_policy failed. Required: %s, Available: %s",
1045 required
.numa_node_policy
.mem_policy
, available
.numa_node_policy
.mem_policy
)
1047 elif available
.numa_node_policy
.has_field('mem_policy'):
1048 self
.log
.debug("Rejecting available flavor because num node mem_policy not required but available")
1051 if required
.numa_node_policy
.has_field('node'):
1052 self
.log
.debug("Matching numa_node_policy nodes configuration")
1053 if available
.numa_node_policy
.has_field('node') == False:
1054 self
.log
.debug("Matching numa_node_policy nodes configuration failed. Not available in flavor")
1056 for required_node
in required
.numa_node_policy
.node
:
1057 self
.log
.debug("Matching numa_node_policy nodes configuration for node %s",
1060 for available_node
in available
.numa_node_policy
.node
:
1061 if required_node
.id != available_node
.id:
1062 self
.log
.debug("Matching numa_node_policy nodes configuration failed. Required: %s, Available: %s",
1063 required_node
, available_node
)
1065 if required_node
.vcpu
!= available_node
.vcpu
:
1066 self
.log
.debug("Matching numa_node_policy nodes configuration failed. Required: %s, Available: %s",
1067 required_node
, available_node
)
1069 if required_node
.memory_mb
!= available_node
.memory_mb
:
1070 self
.log
.debug("Matching numa_node_policy nodes configuration failed. Required: %s, Available: %s",
1071 required_node
, available_node
)
1074 if numa_match
== False:
1076 elif available
.numa_node_policy
.has_field('node'):
1077 self
.log
.debug("Rejecting available flavor because numa nodes not required but available")
1079 elif available
.has_field('numa_node_policy'):
1080 self
.log
.debug("Rejecting available flavor because numa_node_policy not required but available")
1082 self
.log
.info("Successful match for Guest EPA attributes")
1085 def _match_vswitch_epa(self
, required
, available
):
1086 self
.log
.debug("VSwitch EPA match found")
1089 def _match_hypervisor_epa(self
, required
, available
):
1090 self
.log
.debug("Hypervisor EPA match found")
1093 def _match_host_epa(self
, required
, available
):
1094 self
.log
.info("Matching Host EPA attributes")
1095 if required
.has_field('cpu_model'):
1096 self
.log
.debug("Matching CPU model")
1097 if available
.has_field('cpu_model') == False:
1098 self
.log
.debug("Matching CPU model failed. Not available in flavor")
1101 #### Convert all PREFER to REQUIRE since flavor will only have REQUIRE attributes
1102 if required
.cpu_model
.replace('PREFER', 'REQUIRE') != available
.cpu_model
:
1103 self
.log
.debug("Matching CPU model failed. Required: %s, Available: %s",
1104 required
.cpu_model
, available
.cpu_model
)
1106 elif available
.has_field('cpu_model'):
1107 self
.log
.debug("Rejecting available flavor because cpu_model not required but available")
1110 if required
.has_field('cpu_arch'):
1111 self
.log
.debug("Matching CPU architecture")
1112 if available
.has_field('cpu_arch') == False:
1113 self
.log
.debug("Matching CPU architecture failed. Not available in flavor")
1116 #### Convert all PREFER to REQUIRE since flavor will only have REQUIRE attributes
1117 if required
.cpu_arch
.replace('PREFER', 'REQUIRE') != available
.cpu_arch
:
1118 self
.log
.debug("Matching CPU architecture failed. Required: %s, Available: %s",
1119 required
.cpu_arch
, available
.cpu_arch
)
1121 elif available
.has_field('cpu_arch'):
1122 self
.log
.debug("Rejecting available flavor because cpu_arch not required but available")
1125 if required
.has_field('cpu_vendor'):
1126 self
.log
.debug("Matching CPU vendor")
1127 if available
.has_field('cpu_vendor') == False:
1128 self
.log
.debug("Matching CPU vendor failed. Not available in flavor")
1131 #### Convert all PREFER to REQUIRE since flavor will only have REQUIRE attributes
1132 if required
.cpu_vendor
.replace('PREFER', 'REQUIRE') != available
.cpu_vendor
:
1133 self
.log
.debug("Matching CPU vendor failed. Required: %s, Available: %s",
1134 required
.cpu_vendor
, available
.cpu_vendor
)
1136 elif available
.has_field('cpu_vendor'):
1137 self
.log
.debug("Rejecting available flavor because cpu_vendor not required but available")
1140 if required
.has_field('cpu_socket_count'):
1141 self
.log
.debug("Matching CPU socket count")
1142 if available
.has_field('cpu_socket_count') == False:
1143 self
.log
.debug("Matching CPU socket count failed. Not available in flavor")
1146 if required
.cpu_socket_count
!= available
.cpu_socket_count
:
1147 self
.log
.debug("Matching CPU socket count failed. Required: %s, Available: %s",
1148 required
.cpu_socket_count
, available
.cpu_socket_count
)
1150 elif available
.has_field('cpu_socket_count'):
1151 self
.log
.debug("Rejecting available flavor because cpu_socket_count not required but available")
1154 if required
.has_field('cpu_core_count'):
1155 self
.log
.debug("Matching CPU core count")
1156 if available
.has_field('cpu_core_count') == False:
1157 self
.log
.debug("Matching CPU core count failed. Not available in flavor")
1160 if required
.cpu_core_count
!= available
.cpu_core_count
:
1161 self
.log
.debug("Matching CPU core count failed. Required: %s, Available: %s",
1162 required
.cpu_core_count
, available
.cpu_core_count
)
1164 elif available
.has_field('cpu_core_count'):
1165 self
.log
.debug("Rejecting available flavor because cpu_core_count not required but available")
1168 if required
.has_field('cpu_core_thread_count'):
1169 self
.log
.debug("Matching CPU core thread count")
1170 if available
.has_field('cpu_core_thread_count') == False:
1171 self
.log
.debug("Matching CPU core thread count failed. Not available in flavor")
1174 if required
.cpu_core_thread_count
!= available
.cpu_core_thread_count
:
1175 self
.log
.debug("Matching CPU core thread count failed. Required: %s, Available: %s",
1176 required
.cpu_core_thread_count
, available
.cpu_core_thread_count
)
1178 elif available
.has_field('cpu_core_thread_count'):
1179 self
.log
.debug("Rejecting available flavor because cpu_core_thread_count not required but available")
1182 if required
.has_field('cpu_feature'):
1183 self
.log
.debug("Matching CPU feature list")
1184 if available
.has_field('cpu_feature') == False:
1185 self
.log
.debug("Matching CPU feature list failed. Not available in flavor")
1188 for feature
in required
.cpu_feature
:
1189 if feature
not in available
.cpu_feature
:
1190 self
.log
.debug("Matching CPU feature list failed. Required feature: %s is not present. Available features: %s",
1191 feature
, available
.cpu_feature
)
1193 elif available
.has_field('cpu_feature'):
1194 self
.log
.debug("Rejecting available flavor because cpu_feature not required but available")
1196 self
.log
.info("Successful match for Host EPA attributes")
1200 def _match_placement_group_inputs(self
, required
, available
):
1201 self
.log
.info("Matching Host aggregate attributes")
1203 if not required
and not available
:
1204 # Host aggregate not required and not available => success
1205 self
.log
.info("Successful match for Host Aggregate attributes")
1207 if required
and available
:
1208 # Host aggregate requested and available => Do a match and decide
1209 xx
= [ x
.as_dict() for x
in required
]
1210 yy
= [ y
.as_dict() for y
in available
]
1213 self
.log
.debug("Rejecting available flavor because host Aggregate mismatch. Required: %s, Available: %s",
1214 required
, available
)
1216 self
.log
.info("Successful match for Host Aggregate attributes")
1219 # Either of following conditions => Failure
1220 # - Host aggregate required but not available
1221 # - Host aggregate not required but available
1222 self
.log
.debug("Rejecting available flavor because host Aggregate mismatch. Required: %s, Available: %s",
1223 required
, available
)
1227 def _match_epa_params(self
, resource_info
, request_params
):
1229 Match EPA attributes
1231 resource_info: Protobuf GI object RwcalYang.FlavorInfoItem()
1232 Following attributes would be accessed
1238 request_params: Protobuf GI object RwcalYang.VDUInitParams().
1239 Following attributes would be accessed
1245 True -- Match between resource_info and request_params
1246 False -- No match between resource_info and request_params
1249 result
= self
._match
_vm
_flavor
(getattr(request_params
, 'vm_flavor'),
1250 getattr(resource_info
, 'vm_flavor'))
1252 self
.log
.debug("VM Flavor mismatched")
1255 result
= self
._match
_guest
_epa
(getattr(request_params
, 'guest_epa'),
1256 getattr(resource_info
, 'guest_epa'))
1258 self
.log
.debug("Guest EPA mismatched")
1261 result
= self
._match
_vswitch
_epa
(getattr(request_params
, 'vswitch_epa'),
1262 getattr(resource_info
, 'vswitch_epa'))
1264 self
.log
.debug("Vswitch EPA mismatched")
1267 result
= self
._match
_hypervisor
_epa
(getattr(request_params
, 'hypervisor_epa'),
1268 getattr(resource_info
, 'hypervisor_epa'))
1270 self
.log
.debug("Hypervisor EPA mismatched")
1273 result
= self
._match
_host
_epa
(getattr(request_params
, 'host_epa'),
1274 getattr(resource_info
, 'host_epa'))
1276 self
.log
.debug("Host EPA mismatched")
1279 result
= self
._match
_placement
_group
_inputs
(getattr(request_params
, 'host_aggregate'),
1280 getattr(resource_info
, 'host_aggregate'))
1283 self
.log
.debug("Host Aggregate mismatched")
1288 def match_resource_flavor(self
, vdu_init
, flavor_list
):
1291 vdu_init: Protobuf GI object RwcalYang.VDUInitParams().
1292 flavor_list: List of Protobuf GI object RwcalYang.FlavorInfoItem()
1295 Flavor_ID -- If match is found between vdu_init and one of flavor_info from flavor_list
1296 None -- No match between vdu_init and one of flavor_info from flavor_list
1298 Select a existing flavor if it matches the request or create new flavor
1300 for flv
in flavor_list
:
1301 self
.log
.info("Attempting to match compute requirement for VDU: %s with flavor %s",
1303 if self
._match
_epa
_params
(flv
, vdu_init
):
1304 self
.log
.info("Flavor match found for compute requirements for VDU: %s with flavor name: %s, flavor-id: %s",
1305 vdu_init
.name
, flv
.name
, flv
.id)