Gerrit feature request : https://osm.etsi.org/gerrit/#/c/7106/
Changes:
NFVO engine to read and parse the quota descriptor and store as flavor extended properties.
Openstack VIM Connector to process the new extended properties and suitably pass them as extra specs when creating flavor.
Change-Id: Icdd8730f6f6de6d420027de962f0f5def0376375
Signed-off-by: anwars <anwars@vmware.com>
db_image["uuid"] = image_uuid
return None
db_image["uuid"] = image_uuid
return None
+def get_resource_allocation_params(quota_descriptor):
+ """
+ read the quota_descriptor from vnfd and fetch the resource allocation properties from the descriptor object
+ :param quota_descriptor: cpu/mem/vif/disk-io quota descriptor
+ :return: quota params for limit, reserve, shares from the descriptor object
+ """
+ quota = {}
+ if quota_descriptor.get("limit"):
+ quota["limit"] = int(quota_descriptor["limit"])
+ if quota_descriptor.get("reserve"):
+ quota["reserve"] = int(quota_descriptor["reserve"])
+ if quota_descriptor.get("shares"):
+ quota["shares"] = int(quota_descriptor["shares"])
+ return quota
+
def new_vnfd_v3(mydb, tenant_id, vnf_descriptor):
"""
Parses an OSM IM vnfd_catalog and insert at DB
def new_vnfd_v3(mydb, tenant_id, vnf_descriptor):
"""
Parses an OSM IM vnfd_catalog and insert at DB
numa["cores"] = max(db_flavor["vcpus"], 1)
else:
numa["threads"] = max(db_flavor["vcpus"], 1)
numa["cores"] = max(db_flavor["vcpus"], 1)
else:
numa["threads"] = max(db_flavor["vcpus"], 1)
+ epa_vcpu_set = True
+ if vdu["guest-epa"].get("cpu-quota") and not epa_vcpu_set:
+ extended["cpu-quota"] = get_resource_allocation_params(vdu["guest-epa"].get("cpu-quota"))
+ if vdu["guest-epa"].get("mem-quota"):
+ extended["mem-quota"] = get_resource_allocation_params(vdu["guest-epa"].get("mem-quota"))
+ if vdu["guest-epa"].get("disk-io-quota"):
+ extended["disk-io-quota"] = get_resource_allocation_params(vdu["guest-epa"].get("disk-io-quota"))
+ if vdu["guest-epa"].get("vif-quota"):
+ extended["vif-quota"] = get_resource_allocation_params(vdu["guest-epa"].get("vif-quota"))
if numa:
extended["numas"] = [numa]
if extended:
if numa:
extended["numas"] = [numa]
if extended:
flavor_candidate_data = (10000, 10000, 10000)
flavor_target = (flavor_dict["ram"], flavor_dict["vcpus"], flavor_dict["disk"])
# numa=None
flavor_candidate_data = (10000, 10000, 10000)
flavor_target = (flavor_dict["ram"], flavor_dict["vcpus"], flavor_dict["disk"])
# numa=None
- numas = flavor_dict.get("extended", {}).get("numas")
- if numas:
+ extended = flavor_dict.get("extended", {})
+ if extended:
#TODO
raise vimconn.vimconnNotFoundException("Flavor with EPA still not implemted")
# if len(numas) > 1:
#TODO
raise vimconn.vimconnNotFoundException("Flavor with EPA still not implemted")
# if len(numas) > 1:
except (nvExceptions.NotFound, nvExceptions.ClientException, ksExceptions.ClientException, ConnectionError) as e:
self._format_exception(e)
except (nvExceptions.NotFound, nvExceptions.ClientException, ksExceptions.ClientException, ConnectionError) as e:
self._format_exception(e)
+ def process_resource_quota(self, quota, prefix, extra_specs):
+ """
+ :param prefix:
+ :param extra_specs:
+ :return:
+ """
+ if 'limit' in quota:
+ extra_specs["quota:" + prefix + "_limit"] = quota['limit']
+ if 'reserve' in quota:
+ extra_specs["quota:" + prefix + "_reservation"] = quota['reserve']
+ if 'shares' in quota:
+ extra_specs["quota:" + prefix + "_shares_level"] = "custom"
+ extra_specs["quota:" + prefix + "_shares_share"] = quota['shares']
+
def new_flavor(self, flavor_data, change_name_if_used=True):
'''Adds a tenant flavor to openstack VIM
if change_name_if_used is True, it will change name in case of conflict, because it is not supported name repetition
def new_flavor(self, flavor_data, change_name_if_used=True):
'''Adds a tenant flavor to openstack VIM
if change_name_if_used is True, it will change name in case of conflict, because it is not supported name repetition
ram = flavor_data.get('ram',64)
vcpus = flavor_data.get('vcpus',1)
ram = flavor_data.get('ram',64)
vcpus = flavor_data.get('vcpus',1)
extended = flavor_data.get("extended")
if extended:
extended = flavor_data.get("extended")
if extended:
numa_nodes = len(numas)
if numa_nodes > 1:
return -1, "Can not add flavor with more than one numa"
numa_nodes = len(numas)
if numa_nodes > 1:
return -1, "Can not add flavor with more than one numa"
- numa_properties = {"hw:numa_nodes":str(numa_nodes)}
- numa_properties["hw:mem_page_size"] = "large"
- numa_properties["hw:cpu_policy"] = "dedicated"
- numa_properties["hw:numa_mempolicy"] = "strict"
+ extra_specs["hw:numa_nodes"] = str(numa_nodes)
+ extra_specs["hw:mem_page_size"] = "large"
+ extra_specs["hw:cpu_policy"] = "dedicated"
+ extra_specs["hw:numa_mempolicy"] = "strict"
if self.vim_type == "VIO":
if self.vim_type == "VIO":
- numa_properties["vmware:extra_config"] = '{"numa.nodeAffinity":"0"}'
- numa_properties["vmware:latency_sensitivity_level"] = "high"
+ extra_specs["vmware:extra_config"] = '{"numa.nodeAffinity":"0"}'
+ extra_specs["vmware:latency_sensitivity_level"] = "high"
for numa in numas:
#overwrite ram and vcpus
#check if key 'memory' is present in numa else use ram value at flavor
for numa in numas:
#overwrite ram and vcpus
#check if key 'memory' is present in numa else use ram value at flavor
if 'paired-threads' in numa:
vcpus = numa['paired-threads']*2
#cpu_thread_policy "require" implies that the compute node must have an STM architecture
if 'paired-threads' in numa:
vcpus = numa['paired-threads']*2
#cpu_thread_policy "require" implies that the compute node must have an STM architecture
- numa_properties["hw:cpu_thread_policy"] = "require"
- numa_properties["hw:cpu_policy"] = "dedicated"
+ extra_specs["hw:cpu_thread_policy"] = "require"
+ extra_specs["hw:cpu_policy"] = "dedicated"
elif 'cores' in numa:
vcpus = numa['cores']
# cpu_thread_policy "prefer" implies that the host must not have an SMT architecture, or a non-SMT architecture will be emulated
elif 'cores' in numa:
vcpus = numa['cores']
# cpu_thread_policy "prefer" implies that the host must not have an SMT architecture, or a non-SMT architecture will be emulated
- numa_properties["hw:cpu_thread_policy"] = "isolate"
- numa_properties["hw:cpu_policy"] = "dedicated"
+ extra_specs["hw:cpu_thread_policy"] = "isolate"
+ extra_specs["hw:cpu_policy"] = "dedicated"
elif 'threads' in numa:
vcpus = numa['threads']
# cpu_thread_policy "prefer" implies that the host may or may not have an SMT architecture
elif 'threads' in numa:
vcpus = numa['threads']
# cpu_thread_policy "prefer" implies that the host may or may not have an SMT architecture
- numa_properties["hw:cpu_thread_policy"] = "prefer"
- numa_properties["hw:cpu_policy"] = "dedicated"
+ extra_specs["hw:cpu_thread_policy"] = "prefer"
+ extra_specs["hw:cpu_policy"] = "dedicated"
# for interface in numa.get("interfaces",() ):
# if interface["dedicated"]=="yes":
# raise vimconn.vimconnException("Passthrough interfaces are not supported for the openstack connector", http_code=vimconn.HTTP_Service_Unavailable)
# #TODO, add the key 'pci_passthrough:alias"="<label at config>:<number ifaces>"' when a way to connect it is available
# for interface in numa.get("interfaces",() ):
# if interface["dedicated"]=="yes":
# raise vimconn.vimconnException("Passthrough interfaces are not supported for the openstack connector", http_code=vimconn.HTTP_Service_Unavailable)
# #TODO, add the key 'pci_passthrough:alias"="<label at config>:<number ifaces>"' when a way to connect it is available
+ elif extended.get("cpu-quota"):
+ self.process_resource_quota(extended.get("cpu-quota"), "cpu", extra_specs)
+ if extended.get("mem-quota"):
+ self.process_resource_quota(extended.get("mem-quota"), "memory", extra_specs)
+ if extended.get("vif-quota"):
+ self.process_resource_quota(extended.get("vif-quota"), "vif", extra_specs)
+ if extended.get("disk-io-quota"):
+ self.process_resource_quota(extended.get("disk-io-quota"), "disk_io", extra_specs)
#create flavor
new_flavor=self.nova.flavors.create(name,
ram,
#create flavor
new_flavor=self.nova.flavors.create(name,
ram,
is_public=flavor_data.get('is_public', True)
)
#add metadata
is_public=flavor_data.get('is_public', True)
)
#add metadata
- if numa_properties:
- new_flavor.set_keys(numa_properties)
+ if extra_specs:
+ new_flavor.set_keys(extra_specs)
return new_flavor.id
except nvExceptions.Conflict as e:
if change_name_if_used and retry < max_retries:
return new_flavor.id
except nvExceptions.Conflict as e:
if change_name_if_used and retry < max_retries: