--- /dev/null
+#!/usr/bin/env python3
+
+#
+# Copyright 2016 RIFT.IO Inc
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import re
+
+class OpenstackGuestEPAUtils(object):
+ """
+ Utility class for Host EPA to Openstack flavor extra_specs conversion routines
+ """
+ def __init__(self):
+ self._mano_to_espec_cpu_pinning_policy = {
+ 'DEDICATED' : 'dedicated',
+ 'SHARED' : 'shared',
+ 'ANY' : 'any',
+ }
+
+ self._espec_to_mano_cpu_pinning_policy = {
+ 'dedicated' : 'DEDICATED',
+ 'shared' : 'SHARED',
+ 'any' : 'ANY',
+ }
+
+ self._mano_to_espec_mempage_size = {
+ 'LARGE' : 'large',
+ 'SMALL' : 'small',
+ 'SIZE_2MB' : 2048,
+ 'SIZE_1GB' : 1048576,
+ 'PREFER_LARGE' : 'large',
+ }
+
+ self._espec_to_mano_mempage_size = {
+ 'large' : 'LARGE',
+ 'small' : 'SMALL',
+ 2048 : 'SIZE_2MB',
+ 1048576 : 'SIZE_1GB',
+ 'large' : 'PREFER_LARGE',
+ }
+
+ self._mano_to_espec_cpu_thread_pinning_policy = {
+ 'AVOID' : 'avoid',
+ 'SEPARATE' : 'separate',
+ 'ISOLATE' : 'isolate',
+ 'PREFER' : 'prefer',
+ }
+
+ self._espec_to_mano_cpu_thread_pinning_policy = {
+ 'avoid' : 'AVOID',
+ 'separate' : 'SEPARATE',
+ 'isolate' : 'ISOLATE',
+ 'prefer' : 'PREFER',
+ }
+
+ self._espec_to_mano_numa_memory_policy = {
+ 'strict' : 'STRICT',
+ 'preferred': 'PREFERRED'
+ }
+
+ self._mano_to_espec_numa_memory_policy = {
+ 'STRICT' : 'strict',
+ 'PREFERRED': 'preferred'
+ }
+
+ def mano_to_extra_spec_cpu_pinning_policy(self, cpu_pinning_policy):
+ if cpu_pinning_policy in self._mano_to_espec_cpu_pinning_policy:
+ return self._mano_to_espec_cpu_pinning_policy[cpu_pinning_policy]
+ else:
+ return None
+
+ def extra_spec_to_mano_cpu_pinning_policy(self, cpu_pinning_policy):
+ if cpu_pinning_policy in self._espec_to_mano_cpu_pinning_policy:
+ return self._espec_to_mano_cpu_pinning_policy[cpu_pinning_policy]
+ else:
+ return None
+
+ def mano_to_extra_spec_mempage_size(self, mempage_size):
+ if mempage_size in self._mano_to_espec_mempage_size:
+ return self._mano_to_espec_mempage_size[mempage_size]
+ else:
+ return None
+
+ def extra_spec_to_mano_mempage_size(self, mempage_size):
+ if mempage_size in self._espec_to_mano_mempage_size:
+ return self._espec_to_mano_mempage_size[mempage_size]
+ else:
+ return None
+
+ def mano_to_extra_spec_cpu_thread_pinning_policy(self, cpu_thread_pinning_policy):
+ if cpu_thread_pinning_policy in self._mano_to_espec_cpu_thread_pinning_policy:
+ return self._mano_to_espec_cpu_thread_pinning_policy[cpu_thread_pinning_policy]
+ else:
+ return None
+
+ def extra_spec_to_mano_cpu_thread_pinning_policy(self, cpu_thread_pinning_policy):
+ if cpu_thread_pinning_policy in self._espec_to_mano_cpu_thread_pinning_policy:
+ return self._espec_to_mano_cpu_thread_pinning_policy[cpu_thread_pinning_policy]
+ else:
+ return None
+
+ def mano_to_extra_spec_trusted_execution(self, trusted_execution):
+ if trusted_execution:
+ return 'trusted'
+ else:
+ return 'untrusted'
+
+ def extra_spec_to_mano_trusted_execution(self, trusted_execution):
+ if trusted_execution == 'trusted':
+ return True
+ elif trusted_execution == 'untrusted':
+ return False
+ else:
+ return None
+
+ def mano_to_extra_spec_numa_node_count(self, numa_node_count):
+ return numa_node_count
+
+ def extra_specs_to_mano_numa_node_count(self, numa_node_count):
+ return int(numa_node_count)
+
+ def mano_to_extra_spec_numa_memory_policy(self, numa_memory_policy):
+ if numa_memory_policy in self._mano_to_espec_numa_memory_policy:
+ return self._mano_to_espec_numa_memory_policy[numa_memory_policy]
+ else:
+ return None
+
+ def extra_to_mano_spec_numa_memory_policy(self, numa_memory_policy):
+ if numa_memory_policy in self._espec_to_mano_numa_memory_policy:
+ return self._espec_to_mano_numa_memory_policy[numa_memory_policy]
+ else:
+ return None
+
+
+
+
+class OpenstackHostEPAUtils(object):
+ """
+ Utility class for Host EPA to Openstack flavor extra_specs conversion routines
+ """
+ def __init__(self):
+ self._mano_to_espec_cpumodel = {
+ "PREFER_WESTMERE" : "Westmere",
+ "REQUIRE_WESTMERE" : "Westmere",
+ "PREFER_SANDYBRIDGE" : "SandyBridge",
+ "REQUIRE_SANDYBRIDGE" : "SandyBridge",
+ "PREFER_IVYBRIDGE" : "IvyBridge",
+ "REQUIRE_IVYBRIDGE" : "IvyBridge",
+ "PREFER_HASWELL" : "Haswell",
+ "REQUIRE_HASWELL" : "Haswell",
+ "PREFER_BROADWELL" : "Broadwell",
+ "REQUIRE_BROADWELL" : "Broadwell",
+ "PREFER_NEHALEM" : "Nehalem",
+ "REQUIRE_NEHALEM" : "Nehalem",
+ "PREFER_PENRYN" : "Penryn",
+ "REQUIRE_PENRYN" : "Penryn",
+ "PREFER_CONROE" : "Conroe",
+ "REQUIRE_CONROE" : "Conroe",
+ "PREFER_CORE2DUO" : "Core2Duo",
+ "REQUIRE_CORE2DUO" : "Core2Duo",
+ }
+
+ self._espec_to_mano_cpumodel = {
+ "Westmere" : "REQUIRE_WESTMERE",
+ "SandyBridge" : "REQUIRE_SANDYBRIDGE",
+ "IvyBridge" : "REQUIRE_IVYBRIDGE",
+ "Haswell" : "REQUIRE_HASWELL",
+ "Broadwell" : "REQUIRE_BROADWELL",
+ "Nehalem" : "REQUIRE_NEHALEM",
+ "Penryn" : "REQUIRE_PENRYN",
+ "Conroe" : "REQUIRE_CONROE",
+ "Core2Duo" : "REQUIRE_CORE2DUO",
+ }
+
+ self._mano_to_espec_cpuarch = {
+ "PREFER_X86" : "x86",
+ "REQUIRE_X86" : "x86",
+ "PREFER_X86_64" : "x86_64",
+ "REQUIRE_X86_64" : "x86_64",
+ "PREFER_I686" : "i686",
+ "REQUIRE_I686" : "i686",
+ "PREFER_IA64" : "ia64",
+ "REQUIRE_IA64" : "ia64",
+ "PREFER_ARMV7" : "ARMv7",
+ "REQUIRE_ARMV7" : "ARMv7",
+ "PREFER_ARMV8" : "ARMv8-A",
+ "REQUIRE_ARMV8" : "ARMv8-A",
+ }
+
+ self._espec_to_mano_cpuarch = {
+ "x86" : "REQUIRE_X86",
+ "x86_64" : "REQUIRE_X86_64",
+ "i686" : "REQUIRE_I686",
+ "ia64" : "REQUIRE_IA64",
+ "ARMv7-A" : "REQUIRE_ARMV7",
+ "ARMv8-A" : "REQUIRE_ARMV8",
+ }
+
+ self._mano_to_espec_cpuvendor = {
+ "PREFER_INTEL" : "Intel",
+ "REQUIRE_INTEL" : "Intel",
+ "PREFER_AMD" : "AMD",
+ "REQUIRE_AMD" : "AMD",
+ }
+
+ self._espec_to_mano_cpuvendor = {
+ "Intel" : "REQUIRE_INTEL",
+ "AMD" : "REQUIRE_AMD",
+ }
+
+ self._mano_to_espec_cpufeatures = {
+ "PREFER_AES" : "aes",
+ "REQUIRE_AES" : "aes",
+ "REQUIRE_VME" : "vme",
+ "PREFER_VME" : "vme",
+ "REQUIRE_DE" : "de",
+ "PREFER_DE" : "de",
+ "REQUIRE_PSE" : "pse",
+ "PREFER_PSE" : "pse",
+ "REQUIRE_TSC" : "tsc",
+ "PREFER_TSC" : "tsc",
+ "REQUIRE_MSR" : "msr",
+ "PREFER_MSR" : "msr",
+ "REQUIRE_PAE" : "pae",
+ "PREFER_PAE" : "pae",
+ "REQUIRE_MCE" : "mce",
+ "PREFER_MCE" : "mce",
+ "REQUIRE_CX8" : "cx8",
+ "PREFER_CX8" : "cx8",
+ "REQUIRE_APIC" : "apic",
+ "PREFER_APIC" : "apic",
+ "REQUIRE_SEP" : "sep",
+ "PREFER_SEP" : "sep",
+ "REQUIRE_MTRR" : "mtrr",
+ "PREFER_MTRR" : "mtrr",
+ "REQUIRE_PGE" : "pge",
+ "PREFER_PGE" : "pge",
+ "REQUIRE_MCA" : "mca",
+ "PREFER_MCA" : "mca",
+ "REQUIRE_CMOV" : "cmov",
+ "PREFER_CMOV" : "cmov",
+ "REQUIRE_PAT" : "pat",
+ "PREFER_PAT" : "pat",
+ "REQUIRE_PSE36" : "pse36",
+ "PREFER_PSE36" : "pse36",
+ "REQUIRE_CLFLUSH" : "clflush",
+ "PREFER_CLFLUSH" : "clflush",
+ "REQUIRE_DTS" : "dts",
+ "PREFER_DTS" : "dts",
+ "REQUIRE_ACPI" : "acpi",
+ "PREFER_ACPI" : "acpi",
+ "REQUIRE_MMX" : "mmx",
+ "PREFER_MMX" : "mmx",
+ "REQUIRE_FXSR" : "fxsr",
+ "PREFER_FXSR" : "fxsr",
+ "REQUIRE_SSE" : "sse",
+ "PREFER_SSE" : "sse",
+ "REQUIRE_SSE2" : "sse2",
+ "PREFER_SSE2" : "sse2",
+ "REQUIRE_SS" : "ss",
+ "PREFER_SS" : "ss",
+ "REQUIRE_HT" : "ht",
+ "PREFER_HT" : "ht",
+ "REQUIRE_TM" : "tm",
+ "PREFER_TM" : "tm",
+ "REQUIRE_IA64" : "ia64",
+ "PREFER_IA64" : "ia64",
+ "REQUIRE_PBE" : "pbe",
+ "PREFER_PBE" : "pbe",
+ "REQUIRE_RDTSCP" : "rdtscp",
+ "PREFER_RDTSCP" : "rdtscp",
+ "REQUIRE_PNI" : "pni",
+ "PREFER_PNI" : "pni",
+ "REQUIRE_PCLMULQDQ": "pclmulqdq",
+ "PREFER_PCLMULQDQ" : "pclmulqdq",
+ "REQUIRE_DTES64" : "dtes64",
+ "PREFER_DTES64" : "dtes64",
+ "REQUIRE_MONITOR" : "monitor",
+ "PREFER_MONITOR" : "monitor",
+ "REQUIRE_DS_CPL" : "ds_cpl",
+ "PREFER_DS_CPL" : "ds_cpl",
+ "REQUIRE_VMX" : "vmx",
+ "PREFER_VMX" : "vmx",
+ "REQUIRE_SMX" : "smx",
+ "PREFER_SMX" : "smx",
+ "REQUIRE_EST" : "est",
+ "PREFER_EST" : "est",
+ "REQUIRE_TM2" : "tm2",
+ "PREFER_TM2" : "tm2",
+ "REQUIRE_SSSE3" : "ssse3",
+ "PREFER_SSSE3" : "ssse3",
+ "REQUIRE_CID" : "cid",
+ "PREFER_CID" : "cid",
+ "REQUIRE_FMA" : "fma",
+ "PREFER_FMA" : "fma",
+ "REQUIRE_CX16" : "cx16",
+ "PREFER_CX16" : "cx16",
+ "REQUIRE_XTPR" : "xtpr",
+ "PREFER_XTPR" : "xtpr",
+ "REQUIRE_PDCM" : "pdcm",
+ "PREFER_PDCM" : "pdcm",
+ "REQUIRE_PCID" : "pcid",
+ "PREFER_PCID" : "pcid",
+ "REQUIRE_DCA" : "dca",
+ "PREFER_DCA" : "dca",
+ "REQUIRE_SSE4_1" : "sse4_1",
+ "PREFER_SSE4_1" : "sse4_1",
+ "REQUIRE_SSE4_2" : "sse4_2",
+ "PREFER_SSE4_2" : "sse4_2",
+ "REQUIRE_X2APIC" : "x2apic",
+ "PREFER_X2APIC" : "x2apic",
+ "REQUIRE_MOVBE" : "movbe",
+ "PREFER_MOVBE" : "movbe",
+ "REQUIRE_POPCNT" : "popcnt",
+ "PREFER_POPCNT" : "popcnt",
+ "REQUIRE_TSC_DEADLINE_TIMER" : "tsc_deadline_timer",
+ "PREFER_TSC_DEADLINE_TIMER" : "tsc_deadline_timer",
+ "REQUIRE_XSAVE" : "xsave",
+ "PREFER_XSAVE" : "xsave",
+ "REQUIRE_AVX" : "avx",
+ "PREFER_AVX" : "avx",
+ "REQUIRE_F16C" : "f16c",
+ "PREFER_F16C" : "f16c",
+ "REQUIRE_RDRAND" : "rdrand",
+ "PREFER_RDRAND" : "rdrand",
+ "REQUIRE_FSGSBASE" : "fsgsbase",
+ "PREFER_FSGSBASE" : "fsgsbase",
+ "REQUIRE_BMI1" : "bmi1",
+ "PREFER_BMI1" : "bmi1",
+ "REQUIRE_HLE" : "hle",
+ "PREFER_HLE" : "hle",
+ "REQUIRE_AVX2" : "avx2",
+ "PREFER_AVX2" : "avx2",
+ "REQUIRE_SMEP" : "smep",
+ "PREFER_SMEP" : "smep",
+ "REQUIRE_BMI2" : "bmi2",
+ "PREFER_BMI2" : "bmi2",
+ "REQUIRE_ERMS" : "erms",
+ "PREFER_ERMS" : "erms",
+ "REQUIRE_INVPCID" : "invpcid",
+ "PREFER_INVPCID" : "invpcid",
+ "REQUIRE_RTM" : "rtm",
+ "PREFER_RTM" : "rtm",
+ "REQUIRE_MPX" : "mpx",
+ "PREFER_MPX" : "mpx",
+ "REQUIRE_RDSEED" : "rdseed",
+ "PREFER_RDSEED" : "rdseed",
+ "REQUIRE_ADX" : "adx",
+ "PREFER_ADX" : "adx",
+ "REQUIRE_SMAP" : "smap",
+ "PREFER_SMAP" : "smap",
+ }
+
+ self._espec_to_mano_cpufeatures = {
+ "aes" : "REQUIRE_AES",
+ "vme" : "REQUIRE_VME",
+ "de" : "REQUIRE_DE",
+ "pse" : "REQUIRE_PSE",
+ "tsc" : "REQUIRE_TSC",
+ "msr" : "REQUIRE_MSR",
+ "pae" : "REQUIRE_PAE",
+ "mce" : "REQUIRE_MCE",
+ "cx8" : "REQUIRE_CX8",
+ "apic" : "REQUIRE_APIC",
+ "sep" : "REQUIRE_SEP",
+ "mtrr" : "REQUIRE_MTRR",
+ "pge" : "REQUIRE_PGE",
+ "mca" : "REQUIRE_MCA",
+ "cmov" : "REQUIRE_CMOV",
+ "pat" : "REQUIRE_PAT",
+ "pse36" : "REQUIRE_PSE36",
+ "clflush" : "REQUIRE_CLFLUSH",
+ "dts" : "REQUIRE_DTS",
+ "acpi" : "REQUIRE_ACPI",
+ "mmx" : "REQUIRE_MMX",
+ "fxsr" : "REQUIRE_FXSR",
+ "sse" : "REQUIRE_SSE",
+ "sse2" : "REQUIRE_SSE2",
+ "ss" : "REQUIRE_SS",
+ "ht" : "REQUIRE_HT",
+ "tm" : "REQUIRE_TM",
+ "ia64" : "REQUIRE_IA64",
+ "pbe" : "REQUIRE_PBE",
+ "rdtscp" : "REQUIRE_RDTSCP",
+ "pni" : "REQUIRE_PNI",
+ "pclmulqdq": "REQUIRE_PCLMULQDQ",
+ "dtes64" : "REQUIRE_DTES64",
+ "monitor" : "REQUIRE_MONITOR",
+ "ds_cpl" : "REQUIRE_DS_CPL",
+ "vmx" : "REQUIRE_VMX",
+ "smx" : "REQUIRE_SMX",
+ "est" : "REQUIRE_EST",
+ "tm2" : "REQUIRE_TM2",
+ "ssse3" : "REQUIRE_SSSE3",
+ "cid" : "REQUIRE_CID",
+ "fma" : "REQUIRE_FMA",
+ "cx16" : "REQUIRE_CX16",
+ "xtpr" : "REQUIRE_XTPR",
+ "pdcm" : "REQUIRE_PDCM",
+ "pcid" : "REQUIRE_PCID",
+ "dca" : "REQUIRE_DCA",
+ "sse4_1" : "REQUIRE_SSE4_1",
+ "sse4_2" : "REQUIRE_SSE4_2",
+ "x2apic" : "REQUIRE_X2APIC",
+ "movbe" : "REQUIRE_MOVBE",
+ "popcnt" : "REQUIRE_POPCNT",
+ "tsc_deadline_timer" : "REQUIRE_TSC_DEADLINE_TIMER",
+ "xsave" : "REQUIRE_XSAVE",
+ "avx" : "REQUIRE_AVX",
+ "f16c" : "REQUIRE_F16C",
+ "rdrand" : "REQUIRE_RDRAND",
+ "fsgsbase" : "REQUIRE_FSGSBASE",
+ "bmi1" : "REQUIRE_BMI1",
+ "hle" : "REQUIRE_HLE",
+ "avx2" : "REQUIRE_AVX2",
+ "smep" : "REQUIRE_SMEP",
+ "bmi2" : "REQUIRE_BMI2",
+ "erms" : "REQUIRE_ERMS",
+ "invpcid" : "REQUIRE_INVPCID",
+ "rtm" : "REQUIRE_RTM",
+ "mpx" : "REQUIRE_MPX",
+ "rdseed" : "REQUIRE_RDSEED",
+ "adx" : "REQUIRE_ADX",
+ "smap" : "REQUIRE_SMAP",
+ }
+
+ def mano_to_extra_spec_cpu_model(self, cpu_model):
+ if cpu_model in self._mano_to_espec_cpumodel:
+ return self._mano_to_espec_cpumodel[cpu_model]
+ else:
+ return None
+
+ def extra_specs_to_mano_cpu_model(self, cpu_model):
+ if cpu_model in self._espec_to_mano_cpumodel:
+ return self._espec_to_mano_cpumodel[cpu_model]
+ else:
+ return None
+
+ def mano_to_extra_spec_cpu_arch(self, cpu_arch):
+ if cpu_arch in self._mano_to_espec_cpuarch:
+ return self._mano_to_espec_cpuarch[cpu_arch]
+ else:
+ return None
+
+ def extra_specs_to_mano_cpu_arch(self, cpu_arch):
+ if cpu_arch in self._espec_to_mano_cpuarch:
+ return self._espec_to_mano_cpuarch[cpu_arch]
+ else:
+ return None
+
+ def mano_to_extra_spec_cpu_vendor(self, cpu_vendor):
+ if cpu_vendor in self._mano_to_espec_cpuvendor:
+ return self._mano_to_espec_cpuvendor[cpu_vendor]
+ else:
+ return None
+
+ def extra_spec_to_mano_cpu_vendor(self, cpu_vendor):
+ if cpu_vendor in self._espec_to_mano_cpuvendor:
+ return self._espec_to_mano_cpuvendor[cpu_vendor]
+ else:
+ return None
+
+ def mano_to_extra_spec_cpu_socket_count(self, cpu_sockets):
+ return cpu_sockets
+
+ def extra_spec_to_mano_cpu_socket_count(self, cpu_sockets):
+ return int(cpu_sockets)
+
+ def mano_to_extra_spec_cpu_core_count(self, cpu_core_count):
+ return cpu_core_count
+
+ def extra_spec_to_mano_cpu_core_count(self, cpu_core_count):
+ return int(cpu_core_count)
+
+ def mano_to_extra_spec_cpu_core_thread_count(self, core_thread_count):
+ return core_thread_count
+
+ def extra_spec_to_mano_cpu_core_thread_count(self, core_thread_count):
+ return int(core_thread_count)
+
+ def mano_to_extra_spec_cpu_features(self, features):
+ cpu_features = []
+ epa_feature_str = None
+ for f in features:
+ if f in self._mano_to_espec_cpufeatures:
+ cpu_features.append(self._mano_to_espec_cpufeatures[f])
+
+ if len(cpu_features) > 1:
+ epa_feature_str = '<all-in> '+ " ".join(cpu_features)
+ elif len(cpu_features) == 1:
+ epa_feature_str = " ".join(cpu_features)
+
+ return epa_feature_str
+
+ def extra_spec_to_mano_cpu_features(self, features):
+ oper_symbols = ['=', '<in>', '<all-in>', '==', '!=', '>=', '<=', 's==', 's!=', 's<', 's<=', 's>', 's>=']
+ cpu_features = []
+ result = None
+ for oper in oper_symbols:
+ regex = '^'+oper+' (.*?)$'
+ result = re.search(regex, features)
+ if result is not None:
+ break
+
+ if result is not None:
+ feature_list = result.group(1)
+ else:
+ feature_list = features
+
+ for f in feature_list.split():
+ if f in self._espec_to_mano_cpufeatures:
+ cpu_features.append(self._espec_to_mano_cpufeatures[f])
+
+ return cpu_features
+
+
+class OpenstackExtraSpecUtils(object):
+ """
+ General utility class for flavor Extra Specs processing
+ """
+ def __init__(self):
+ self.host = OpenstackHostEPAUtils()
+ self.guest = OpenstackGuestEPAUtils()
+ self.extra_specs_keywords = [ 'hw:cpu_policy',
+ 'hw:cpu_threads_policy',
+ 'hw:mem_page_size',
+ 'hw:numa_nodes',
+ 'hw:numa_mempolicy',
+ 'hw:numa_cpus',
+ 'hw:numa_mem',
+ 'trust:trusted_host',
+ 'pci_passthrough:alias',
+ 'capabilities:cpu_info:model',
+ 'capabilities:cpu_info:arch',
+ 'capabilities:cpu_info:vendor',
+ 'capabilities:cpu_info:topology:sockets',
+ 'capabilities:cpu_info:topology:cores',
+ 'capabilities:cpu_info:topology:threads',
+ 'capabilities:cpu_info:features',
+ ]
+ self.extra_specs_regex = re.compile("^"+"|^".join(self.extra_specs_keywords))