Remove references to 'instance_type'

They haven't been instance types in a very long time. We're stuck with
that terminology in the database for now, but otherwise we can replace
references to 'instance_type' with 'flavor'.

While we're here, we also rename a single case of an 'i' variable to a
more informative 'idx'. 'i' is too short to be useful outside of a very
limited scope.

Change-Id: I81fec10535034f3a81d46713a6eda813f90561cf
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
Stephen Finucane 2021-01-14 14:37:56 +00:00
parent 61256b4f78
commit 1de6e960af
4 changed files with 249 additions and 246 deletions

View File

@ -583,8 +583,9 @@ class API(base.Base):
# reason, we rely on the DB to cast True to a String. # reason, we rely on the DB to cast True to a String.
return True if bool_val else '' return True if bool_val else ''
def _validate_flavor_image(self, context, image_id, image, def _validate_flavor_image(
instance_type, root_bdm, validate_numa=True): self, context, image_id, image, flavor, root_bdm, validate_numa=True,
):
"""Validate the flavor and image. """Validate the flavor and image.
This is called from the API service to ensure that the flavor This is called from the API service to ensure that the flavor
@ -594,20 +595,20 @@ class API(base.Base):
:param context: A context.RequestContext :param context: A context.RequestContext
:param image_id: UUID of the image :param image_id: UUID of the image
:param image: a dict representation of the image including properties, :param image: a dict representation of the image including properties,
enforces the image status is active. enforces the image status is active.
:param instance_type: Flavor object :param flavor: Flavor object
:param root_bdm: BlockDeviceMapping for root disk. Will be None for :param root_bdm: BlockDeviceMapping for root disk. Will be None for
the resize case. the resize case.
:param validate_numa: Flag to indicate whether or not to validate :param validate_numa: Flag to indicate whether or not to validate
the NUMA-related metadata. the NUMA-related metadata.
:raises: Many different possible exceptions. See :raises: Many different possible exceptions. See
api.openstack.compute.servers.INVALID_FLAVOR_IMAGE_EXCEPTIONS api.openstack.compute.servers.INVALID_FLAVOR_IMAGE_EXCEPTIONS
for the full list. for the full list.
""" """
if image and image['status'] != 'active': if image and image['status'] != 'active':
raise exception.ImageNotActive(image_id=image_id) raise exception.ImageNotActive(image_id=image_id)
self._validate_flavor_image_nostatus(context, image, instance_type, self._validate_flavor_image_nostatus(
root_bdm, validate_numa) context, image, flavor, root_bdm, validate_numa)
@staticmethod @staticmethod
def _detect_nonbootable_image_from_properties(image_id, image): def _detect_nonbootable_image_from_properties(image_id, image):
@ -640,9 +641,10 @@ class API(base.Base):
reason=reason) reason=reason)
@staticmethod @staticmethod
def _validate_flavor_image_nostatus(context, image, instance_type, def _validate_flavor_image_nostatus(
root_bdm, validate_numa=True, context, image, flavor, root_bdm, validate_numa=True,
validate_pci=False): validate_pci=False,
):
"""Validate the flavor and image. """Validate the flavor and image.
This is called from the API service to ensure that the flavor This is called from the API service to ensure that the flavor
@ -651,7 +653,7 @@ class API(base.Base):
:param context: A context.RequestContext :param context: A context.RequestContext
:param image: a dict representation of the image including properties :param image: a dict representation of the image including properties
:param instance_type: Flavor object :param flavor: Flavor object
:param root_bdm: BlockDeviceMapping for root disk. Will be None for :param root_bdm: BlockDeviceMapping for root disk. Will be None for
the resize case. the resize case.
:param validate_numa: Flag to indicate whether or not to validate :param validate_numa: Flag to indicate whether or not to validate
@ -672,7 +674,7 @@ class API(base.Base):
raise exception.InvalidImageConfigDrive( raise exception.InvalidImageConfigDrive(
config_drive=config_drive_option) config_drive=config_drive_option)
if instance_type['memory_mb'] < int(image.get('min_ram') or 0): if flavor['memory_mb'] < int(image.get('min_ram') or 0):
raise exception.FlavorMemoryTooSmall() raise exception.FlavorMemoryTooSmall()
# Image min_disk is in gb, size is in bytes. For sanity, have them both # Image min_disk is in gb, size is in bytes. For sanity, have them both
@ -728,7 +730,7 @@ class API(base.Base):
# Target disk is a local disk whose size is taken from the flavor # Target disk is a local disk whose size is taken from the flavor
else: else:
dest_size = instance_type['root_gb'] * units.Gi dest_size = flavor['root_gb'] * units.Gi
# NOTE(johannes): root_gb is allowed to be 0 for legacy reasons # NOTE(johannes): root_gb is allowed to be 0 for legacy reasons
# since libvirt interpreted the value differently than other # since libvirt interpreted the value differently than other
@ -752,7 +754,7 @@ class API(base.Base):
raise exception.BootFromVolumeRequiredForZeroDiskFlavor() raise exception.BootFromVolumeRequiredForZeroDiskFlavor()
API._validate_flavor_image_numa_pci( API._validate_flavor_image_numa_pci(
image, instance_type, validate_numa=validate_numa, image, flavor, validate_numa=validate_numa,
validate_pci=validate_pci) validate_pci=validate_pci)
# TODO(huaqiang): Remove in Wallaby when there is no nova-compute node # TODO(huaqiang): Remove in Wallaby when there is no nova-compute node
@ -778,9 +780,9 @@ class API(base.Base):
raise exception.MixedInstanceNotSupportByComputeService() raise exception.MixedInstanceNotSupportByComputeService()
@staticmethod @staticmethod
def _validate_flavor_image_numa_pci(image, instance_type, def _validate_flavor_image_numa_pci(
validate_numa=True, image, flavor, validate_numa=True, validate_pci=False,
validate_pci=False): ):
"""Validate the flavor and image NUMA/PCI values. """Validate the flavor and image NUMA/PCI values.
This is called from the API service to ensure that the flavor This is called from the API service to ensure that the flavor
@ -788,7 +790,7 @@ class API(base.Base):
with each other. with each other.
:param image: a dict representation of the image including properties :param image: a dict representation of the image including properties
:param instance_type: Flavor object :param flavor: Flavor object
:param validate_numa: Flag to indicate whether or not to validate :param validate_numa: Flag to indicate whether or not to validate
the NUMA-related metadata. the NUMA-related metadata.
:param validate_pci: Flag to indicate whether or not to validate :param validate_pci: Flag to indicate whether or not to validate
@ -799,10 +801,10 @@ class API(base.Base):
""" """
image_meta = _get_image_meta_obj(image) image_meta = _get_image_meta_obj(image)
API._validate_flavor_image_mem_encryption(instance_type, image_meta) API._validate_flavor_image_mem_encryption(flavor, image_meta)
# validate PMU extra spec and image metadata # validate PMU extra spec and image metadata
flavor_pmu = instance_type.extra_specs.get('hw:pmu') flavor_pmu = flavor.extra_specs.get('hw:pmu')
image_pmu = image_meta.properties.get('hw_pmu') image_pmu = image_meta.properties.get('hw_pmu')
if (flavor_pmu is not None and image_pmu is not None and if (flavor_pmu is not None and image_pmu is not None and
image_pmu != strutils.bool_from_string(flavor_pmu)): image_pmu != strutils.bool_from_string(flavor_pmu)):
@ -810,29 +812,28 @@ class API(base.Base):
# Only validate values of flavor/image so the return results of # Only validate values of flavor/image so the return results of
# following 'get' functions are not used. # following 'get' functions are not used.
hardware.get_number_of_serial_ports(instance_type, image_meta) hardware.get_number_of_serial_ports(flavor, image_meta)
hardware.get_realtime_cpu_constraint(instance_type, image_meta) hardware.get_realtime_cpu_constraint(flavor, image_meta)
hardware.get_cpu_topology_constraints(instance_type, image_meta) hardware.get_cpu_topology_constraints(flavor, image_meta)
if validate_numa: if validate_numa:
hardware.numa_get_constraints(instance_type, image_meta) hardware.numa_get_constraints(flavor, image_meta)
if validate_pci: if validate_pci:
pci_request.get_pci_requests_from_flavor(instance_type) pci_request.get_pci_requests_from_flavor(flavor)
@staticmethod @staticmethod
def _validate_flavor_image_mem_encryption(instance_type, image): def _validate_flavor_image_mem_encryption(flavor, image):
"""Validate that the flavor and image don't make contradictory """Validate that the flavor and image don't make contradictory
requests regarding memory encryption. requests regarding memory encryption.
:param instance_type: Flavor object :param flavor: Flavor object
:param image: an ImageMeta object :param image: an ImageMeta object
:raises: nova.exception.FlavorImageConflict :raises: nova.exception.FlavorImageConflict
""" """
# This library function will raise the exception for us if # This library function will raise the exception for us if
# necessary; if not, we can ignore the result returned. # necessary; if not, we can ignore the result returned.
hardware.get_mem_encryption_constraint(instance_type, image) hardware.get_mem_encryption_constraint(flavor, image)
def _get_image_defined_bdms(self, instance_type, image_meta, def _get_image_defined_bdms(self, flavor, image_meta, root_device_name):
root_device_name):
image_properties = image_meta.get('properties', {}) image_properties = image_meta.get('properties', {})
# Get the block device mappings defined by the image. # Get the block device mappings defined by the image.
@ -849,14 +850,13 @@ class API(base.Base):
image_defined_bdms)) image_defined_bdms))
if image_mapping: if image_mapping:
image_mapping = self._prepare_image_mapping(instance_type, image_mapping = self._prepare_image_mapping(flavor, image_mapping)
image_mapping)
image_defined_bdms = self._merge_bdms_lists( image_defined_bdms = self._merge_bdms_lists(
image_mapping, image_defined_bdms) image_mapping, image_defined_bdms)
return image_defined_bdms return image_defined_bdms
def _get_flavor_defined_bdms(self, instance_type, block_device_mapping): def _get_flavor_defined_bdms(self, flavor, block_device_mapping):
flavor_defined_bdms = [] flavor_defined_bdms = []
have_ephemeral_bdms = any(filter( have_ephemeral_bdms = any(filter(
@ -864,12 +864,12 @@ class API(base.Base):
have_swap_bdms = any(filter( have_swap_bdms = any(filter(
block_device.new_format_is_swap, block_device_mapping)) block_device.new_format_is_swap, block_device_mapping))
if instance_type.get('ephemeral_gb') and not have_ephemeral_bdms: if flavor.get('ephemeral_gb') and not have_ephemeral_bdms:
flavor_defined_bdms.append( flavor_defined_bdms.append(
block_device.create_blank_bdm(instance_type['ephemeral_gb'])) block_device.create_blank_bdm(flavor['ephemeral_gb']))
if instance_type.get('swap') and not have_swap_bdms: if flavor.get('swap') and not have_swap_bdms:
flavor_defined_bdms.append( flavor_defined_bdms.append(
block_device.create_blank_bdm(instance_type['swap'], 'swap')) block_device.create_blank_bdm(flavor['swap'], 'swap'))
return flavor_defined_bdms return flavor_defined_bdms
@ -887,9 +887,10 @@ class API(base.Base):
[bdm for bdm in overridable_mappings [bdm for bdm in overridable_mappings
if bdm['device_name'] not in device_names]) if bdm['device_name'] not in device_names])
def _check_and_transform_bdm(self, context, base_options, instance_type, def _check_and_transform_bdm(
image_meta, min_count, max_count, self, context, base_options, flavor, image_meta, min_count, max_count,
block_device_mapping, legacy_bdm): block_device_mapping, legacy_bdm,
):
# NOTE (ndipanov): Assume root dev name is 'vda' if not supplied. # NOTE (ndipanov): Assume root dev name is 'vda' if not supplied.
# It's needed for legacy conversion to work. # It's needed for legacy conversion to work.
root_device_name = (base_options.get('root_device_name') or 'vda') root_device_name = (base_options.get('root_device_name') or 'vda')
@ -906,7 +907,7 @@ class API(base.Base):
raise exception.InvalidRequest(msg) raise exception.InvalidRequest(msg)
image_defined_bdms = self._get_image_defined_bdms( image_defined_bdms = self._get_image_defined_bdms(
instance_type, image_meta, root_device_name) flavor, image_meta, root_device_name)
root_in_image_bdms = ( root_in_image_bdms = (
block_device.get_root_bdm(image_defined_bdms) is not None) block_device.get_root_bdm(image_defined_bdms) is not None)
@ -942,7 +943,7 @@ class API(base.Base):
raise exception.InvalidRequest(msg) raise exception.InvalidRequest(msg)
block_device_mapping += self._get_flavor_defined_bdms( block_device_mapping += self._get_flavor_defined_bdms(
instance_type, block_device_mapping) flavor, block_device_mapping)
return block_device_obj.block_device_make_list_from_dicts( return block_device_obj.block_device_make_list_from_dicts(
context, block_device_mapping) context, block_device_mapping)
@ -954,33 +955,30 @@ class API(base.Base):
image = self.image_api.get(context, image_href) image = self.image_api.get(context, image_href)
return image['id'], image return image['id'], image
def _checks_for_create_and_rebuild(self, context, image_id, image, def _checks_for_create_and_rebuild(
instance_type, metadata, self, context, image_id, image, flavor, metadata, files_to_inject,
files_to_inject, root_bdm, root_bdm, validate_numa=True,
validate_numa=True): ):
self._check_metadata_properties_quota(context, metadata) self._check_metadata_properties_quota(context, metadata)
self._check_injected_file_quota(context, files_to_inject) self._check_injected_file_quota(context, files_to_inject)
self._detect_nonbootable_image_from_properties(image_id, image) self._detect_nonbootable_image_from_properties(image_id, image)
self._validate_flavor_image(context, image_id, image, self._validate_flavor_image(context, image_id, image,
instance_type, root_bdm, flavor, root_bdm,
validate_numa=validate_numa) validate_numa=validate_numa)
def _validate_and_build_base_options(self, context, instance_type, def _validate_and_build_base_options(
boot_meta, image_href, image_id, self, context, flavor, boot_meta, image_href, image_id, kernel_id,
kernel_id, ramdisk_id, display_name, ramdisk_id, display_name, display_description, key_name,
display_description, key_name, key_data, security_groups, availability_zone, user_data, metadata,
key_data, security_groups, access_ip_v4, access_ip_v6, requested_networks, config_drive,
availability_zone, user_data, auto_disk_config, reservation_id, max_count,
metadata, access_ip_v4, access_ip_v6, supports_port_resource_request,
requested_networks, config_drive, ):
auto_disk_config, reservation_id,
max_count,
supports_port_resource_request):
"""Verify all the input parameters regardless of the provisioning """Verify all the input parameters regardless of the provisioning
strategy being performed. strategy being performed.
""" """
if instance_type['disabled']: if flavor['disabled']:
raise exception.FlavorNotFound(flavor_id=instance_type['id']) raise exception.FlavorNotFound(flavor_id=flavor['id'])
if user_data: if user_data:
try: try:
@ -1017,13 +1015,12 @@ class API(base.Base):
boot_meta.get('properties', {}))) boot_meta.get('properties', {})))
image_meta = _get_image_meta_obj(boot_meta) image_meta = _get_image_meta_obj(boot_meta)
numa_topology = hardware.numa_get_constraints( numa_topology = hardware.numa_get_constraints(flavor, image_meta)
instance_type, image_meta)
system_metadata = {} system_metadata = {}
pci_numa_affinity_policy = hardware.get_pci_numa_policy_constraint( pci_numa_affinity_policy = hardware.get_pci_numa_policy_constraint(
instance_type, image_meta) flavor, image_meta)
# PCI requests come from two sources: instance flavor and # PCI requests come from two sources: instance flavor and
# requested_networks. The first call in below returns an # requested_networks. The first call in below returns an
@ -1032,7 +1029,7 @@ class API(base.Base):
# object for each SR-IOV port, and append it to the list in the # object for each SR-IOV port, and append it to the list in the
# InstancePCIRequests object # InstancePCIRequests object
pci_request_info = pci_request.get_pci_requests_from_flavor( pci_request_info = pci_request.get_pci_requests_from_flavor(
instance_type, affinity_policy=pci_numa_affinity_policy) flavor, affinity_policy=pci_numa_affinity_policy)
result = self.network_api.create_resource_requests( result = self.network_api.create_resource_requests(
context, requested_networks, pci_request_info, context, requested_networks, pci_request_info,
affinity_policy=pci_numa_affinity_policy) affinity_policy=pci_numa_affinity_policy)
@ -1054,11 +1051,11 @@ class API(base.Base):
'config_drive': config_drive, 'config_drive': config_drive,
'user_id': context.user_id, 'user_id': context.user_id,
'project_id': context.project_id, 'project_id': context.project_id,
'instance_type_id': instance_type['id'], 'instance_type_id': flavor['id'],
'memory_mb': instance_type['memory_mb'], 'memory_mb': flavor['memory_mb'],
'vcpus': instance_type['vcpus'], 'vcpus': flavor['vcpus'],
'root_gb': instance_type['root_gb'], 'root_gb': flavor['root_gb'],
'ephemeral_gb': instance_type['ephemeral_gb'], 'ephemeral_gb': flavor['ephemeral_gb'],
'display_name': display_name, 'display_name': display_name,
'display_description': display_description, 'display_description': display_description,
'user_data': user_data, 'user_data': user_data,
@ -1240,13 +1237,15 @@ class API(base.Base):
'instance_az': instance_az, 'volume_az': volume_az} 'instance_az': instance_az, 'volume_az': volume_az}
raise exception.MismatchVolumeAZException(reason=msg) raise exception.MismatchVolumeAZException(reason=msg)
def _provision_instances(self, context, instance_type, min_count, def _provision_instances(
max_count, base_options, boot_meta, security_groups, self, context, flavor, min_count,
block_device_mapping, shutdown_terminate, max_count, base_options, boot_meta, security_groups,
instance_group, check_server_group_quota, filter_properties, block_device_mapping, shutdown_terminate,
key_pair, tags, trusted_certs, supports_multiattach, instance_group, check_server_group_quota, filter_properties,
network_metadata=None, requested_host=None, key_pair, tags, trusted_certs, supports_multiattach,
requested_hypervisor_hostname=None): network_metadata=None, requested_host=None,
requested_hypervisor_hostname=None,
):
# NOTE(boxiang): Check whether compute nodes exist by validating # NOTE(boxiang): Check whether compute nodes exist by validating
# the host and/or the hypervisor_hostname. Pass the destination # the host and/or the hypervisor_hostname. Pass the destination
# to the scheduler with host and/or hypervisor_hostname(node). # to the scheduler with host and/or hypervisor_hostname(node).
@ -1260,9 +1259,9 @@ class API(base.Base):
destination.node = requested_hypervisor_hostname destination.node = requested_hypervisor_hostname
# Check quotas # Check quotas
num_instances = compute_utils.check_num_instances_quota( num_instances = compute_utils.check_num_instances_quota(
context, instance_type, min_count, max_count) context, flavor, min_count, max_count)
security_groups = security_group_api.populate_security_groups( security_groups = security_group_api.populate_security_groups(
security_groups) security_groups)
port_resource_requests = base_options.pop('port_resource_requests') port_resource_requests = base_options.pop('port_resource_requests')
instances_to_build = [] instances_to_build = []
# We could be iterating over several instances with several BDMs per # We could be iterating over several instances with several BDMs per
@ -1281,20 +1280,20 @@ class API(base.Base):
# base_options to match the volume zone. # base_options to match the volume zone.
base_options['availability_zone'] = volume_az base_options['availability_zone'] = volume_az
LOG.debug("Going to run %s instances...", num_instances) LOG.debug("Going to run %s instances...", num_instances)
extra_specs = instance_type.extra_specs extra_specs = flavor.extra_specs
dp_name = extra_specs.get('accel:device_profile') dp_name = extra_specs.get('accel:device_profile')
dp_request_groups = [] dp_request_groups = []
if dp_name: if dp_name:
dp_request_groups = cyborg.get_device_profile_request_groups( dp_request_groups = cyborg.get_device_profile_request_groups(
context, dp_name) context, dp_name)
try: try:
for i in range(num_instances): for idx in range(num_instances):
# Create a uuid for the instance so we can store the # Create a uuid for the instance so we can store the
# RequestSpec before the instance is created. # RequestSpec before the instance is created.
instance_uuid = uuidutils.generate_uuid() instance_uuid = uuidutils.generate_uuid()
# Store the RequestSpec that will be used for scheduling. # Store the RequestSpec that will be used for scheduling.
req_spec = objects.RequestSpec.from_components(context, req_spec = objects.RequestSpec.from_components(context,
instance_uuid, boot_meta, instance_type, instance_uuid, boot_meta, flavor,
base_options['numa_topology'], base_options['numa_topology'],
base_options['pci_requests'], filter_properties, base_options['pci_requests'], filter_properties,
instance_group, base_options['availability_zone'], instance_group, base_options['availability_zone'],
@ -1337,13 +1336,13 @@ class API(base.Base):
context, trusted_certs) context, trusted_certs)
self._populate_instance_for_create( self._populate_instance_for_create(
context, instance, boot_meta, i, context, instance, boot_meta, idx,
security_groups, instance_type, security_groups, flavor,
num_instances, shutdown_terminate) num_instances, shutdown_terminate)
block_device_mapping = ( block_device_mapping = (
self._bdm_validate_set_size_and_instance(context, self._bdm_validate_set_size_and_instance(context,
instance, instance_type, block_device_mapping, instance, flavor, block_device_mapping,
image_cache, volumes, supports_multiattach)) image_cache, volumes, supports_multiattach))
instance_tags = self._transform_tags(tags, instance.uuid) instance_tags = self._transform_tags(tags, instance.uuid)
@ -1460,7 +1459,7 @@ class API(base.Base):
return objects.InstanceGroup.get_by_uuid(context, group_hint) return objects.InstanceGroup.get_by_uuid(context, group_hint)
def _create_instance(self, context, instance_type, def _create_instance(self, context, flavor,
image_href, kernel_id, ramdisk_id, image_href, kernel_id, ramdisk_id,
min_count, max_count, min_count, max_count,
display_name, display_description, display_name, display_description,
@ -1507,14 +1506,17 @@ class API(base.Base):
self._check_auto_disk_config(image=boot_meta, self._check_auto_disk_config(image=boot_meta,
auto_disk_config=auto_disk_config) auto_disk_config=auto_disk_config)
base_options, max_net_count, key_pair, security_groups, \ (
network_metadata = self._validate_and_build_base_options( base_options, max_net_count, key_pair, security_groups,
context, instance_type, boot_meta, image_href, image_id, network_metadata,
kernel_id, ramdisk_id, display_name, display_description, ) = self._validate_and_build_base_options(
key_name, key_data, security_groups, availability_zone, context, flavor, boot_meta, image_href, image_id,
user_data, metadata, access_ip_v4, access_ip_v6, kernel_id, ramdisk_id, display_name, display_description,
requested_networks, config_drive, auto_disk_config, key_name, key_data, security_groups, availability_zone,
reservation_id, max_count, supports_port_resource_request) user_data, metadata, access_ip_v4, access_ip_v6,
requested_networks, config_drive, auto_disk_config,
reservation_id, max_count, supports_port_resource_request,
)
# TODO(huaqiang): Remove in Wallaby # TODO(huaqiang): Remove in Wallaby
# check nova-compute nodes have been updated to Victoria to support the # check nova-compute nodes have been updated to Victoria to support the
@ -1535,7 +1537,7 @@ class API(base.Base):
max_count = max_net_count max_count = max_net_count
block_device_mapping = self._check_and_transform_bdm(context, block_device_mapping = self._check_and_transform_bdm(context,
base_options, instance_type, boot_meta, min_count, max_count, base_options, flavor, boot_meta, min_count, max_count,
block_device_mapping, legacy_bdm) block_device_mapping, legacy_bdm)
# We can't do this check earlier because we need bdms from all sources # We can't do this check earlier because we need bdms from all sources
@ -1543,7 +1545,7 @@ class API(base.Base):
# Set validate_numa=False since numa validation is already done by # Set validate_numa=False since numa validation is already done by
# _validate_and_build_base_options(). # _validate_and_build_base_options().
self._checks_for_create_and_rebuild(context, image_id, boot_meta, self._checks_for_create_and_rebuild(context, image_id, boot_meta,
instance_type, metadata, injected_files, flavor, metadata, injected_files,
block_device_mapping.root_bdm(), validate_numa=False) block_device_mapping.root_bdm(), validate_numa=False)
instance_group = self._get_requested_instance_group(context, instance_group = self._get_requested_instance_group(context,
@ -1552,7 +1554,7 @@ class API(base.Base):
tags = self._create_tag_list_obj(context, tags) tags = self._create_tag_list_obj(context, tags)
instances_to_build = self._provision_instances( instances_to_build = self._provision_instances(
context, instance_type, min_count, max_count, base_options, context, flavor, min_count, max_count, base_options,
boot_meta, security_groups, block_device_mapping, boot_meta, security_groups, block_device_mapping,
shutdown_terminate, instance_group, check_server_group_quota, shutdown_terminate, instance_group, check_server_group_quota,
filter_properties, key_pair, tags, trusted_certs, filter_properties, key_pair, tags, trusted_certs,
@ -1611,18 +1613,18 @@ class API(base.Base):
pass pass
@staticmethod @staticmethod
def _volume_size(instance_type, bdm): def _volume_size(flavor, bdm):
size = bdm.get('volume_size') size = bdm.get('volume_size')
# NOTE (ndipanov): inherit flavor size only for swap and ephemeral # NOTE (ndipanov): inherit flavor size only for swap and ephemeral
if (size is None and bdm.get('source_type') == 'blank' and if (size is None and bdm.get('source_type') == 'blank' and
bdm.get('destination_type') == 'local'): bdm.get('destination_type') == 'local'):
if bdm.get('guest_format') == 'swap': if bdm.get('guest_format') == 'swap':
size = instance_type.get('swap', 0) size = flavor.get('swap', 0)
else: else:
size = instance_type.get('ephemeral_gb', 0) size = flavor.get('ephemeral_gb', 0)
return size return size
def _prepare_image_mapping(self, instance_type, mappings): def _prepare_image_mapping(self, flavor, mappings):
"""Extract and format blank devices from image mappings.""" """Extract and format blank devices from image mappings."""
prepared_mappings = [] prepared_mappings = []
@ -1653,7 +1655,7 @@ class API(base.Base):
'boot_index': -1}) 'boot_index': -1})
values['volume_size'] = self._volume_size( values['volume_size'] = self._volume_size(
instance_type, values) flavor, values)
if values['volume_size'] == 0: if values['volume_size'] == 0:
continue continue
@ -1662,7 +1664,7 @@ class API(base.Base):
return prepared_mappings return prepared_mappings
def _bdm_validate_set_size_and_instance(self, context, instance, def _bdm_validate_set_size_and_instance(self, context, instance,
instance_type, flavor,
block_device_mapping, block_device_mapping,
image_cache, volumes, image_cache, volumes,
supports_multiattach=False): supports_multiattach=False):
@ -1673,7 +1675,7 @@ class API(base.Base):
:param context: nova auth RequestContext :param context: nova auth RequestContext
:param instance: Instance object :param instance: Instance object
:param instance_type: Flavor object - used for swap and ephemeral BDMs :param flavor: Flavor object - used for swap and ephemeral BDMs
:param block_device_mapping: BlockDeviceMappingList object :param block_device_mapping: BlockDeviceMappingList object
:param image_cache: dict of image dicts keyed by id which is used as a :param image_cache: dict of image dicts keyed by id which is used as a
cache in case there are multiple BDMs in the same request using cache in case there are multiple BDMs in the same request using
@ -1685,11 +1687,11 @@ class API(base.Base):
LOG.debug("block_device_mapping %s", list(block_device_mapping), LOG.debug("block_device_mapping %s", list(block_device_mapping),
instance_uuid=instance.uuid) instance_uuid=instance.uuid)
self._validate_bdm( self._validate_bdm(
context, instance, instance_type, block_device_mapping, context, instance, flavor, block_device_mapping,
image_cache, volumes, supports_multiattach) image_cache, volumes, supports_multiattach)
instance_block_device_mapping = block_device_mapping.obj_clone() instance_block_device_mapping = block_device_mapping.obj_clone()
for bdm in instance_block_device_mapping: for bdm in instance_block_device_mapping:
bdm.volume_size = self._volume_size(instance_type, bdm) bdm.volume_size = self._volume_size(flavor, bdm)
bdm.instance_uuid = instance.uuid bdm.instance_uuid = instance.uuid
return instance_block_device_mapping return instance_block_device_mapping
@ -1713,14 +1715,15 @@ class API(base.Base):
raise exception.VolumeTypeNotFound( raise exception.VolumeTypeNotFound(
id_or_name=volume_type_id_or_name) id_or_name=volume_type_id_or_name)
def _validate_bdm(self, context, instance, instance_type, def _validate_bdm(
block_device_mappings, image_cache, volumes, self, context, instance, flavor, block_device_mappings, image_cache,
supports_multiattach=False): volumes, supports_multiattach=False,
):
"""Validate requested block device mappings. """Validate requested block device mappings.
:param context: nova auth RequestContext :param context: nova auth RequestContext
:param instance: Instance object :param instance: Instance object
:param instance_type: Flavor object - used for swap and ephemeral BDMs :param flavor: Flavor object - used for swap and ephemeral BDMs
:param block_device_mappings: BlockDeviceMappingList object :param block_device_mappings: BlockDeviceMappingList object
:param image_cache: dict of image dicts keyed by id which is used as a :param image_cache: dict of image dicts keyed by id which is used as a
cache in case there are multiple BDMs in the same request using cache in case there are multiple BDMs in the same request using
@ -1824,10 +1827,10 @@ class API(base.Base):
if disk_bus and disk_bus not in fields_obj.DiskBus.ALL: if disk_bus and disk_bus not in fields_obj.DiskBus.ALL:
raise exception.InvalidBDMDiskBus(disk_bus=disk_bus) raise exception.InvalidBDMDiskBus(disk_bus=disk_bus)
ephemeral_size = sum(bdm.volume_size or instance_type['ephemeral_gb'] ephemeral_size = sum(bdm.volume_size or flavor['ephemeral_gb']
for bdm in block_device_mappings for bdm in block_device_mappings
if block_device.new_format_is_ephemeral(bdm)) if block_device.new_format_is_ephemeral(bdm))
if ephemeral_size > instance_type['ephemeral_gb']: if ephemeral_size > flavor['ephemeral_gb']:
raise exception.InvalidBDMEphemeralSize() raise exception.InvalidBDMEphemeralSize()
# There should be only one swap # There should be only one swap
@ -1838,7 +1841,7 @@ class API(base.Base):
if swap_list: if swap_list:
swap_size = swap_list[0].volume_size or 0 swap_size = swap_list[0].volume_size or 0
if swap_size > instance_type['swap']: if swap_size > flavor['swap']:
raise exception.InvalidBDMSwapSize() raise exception.InvalidBDMSwapSize()
max_local = CONF.max_local_block_devices max_local = CONF.max_local_block_devices
@ -1881,9 +1884,10 @@ class API(base.Base):
instance.display_name = new_display_name instance.display_name = new_display_name
def _populate_instance_for_create(self, context, instance, image, def _populate_instance_for_create(
index, security_groups, instance_type, self, context, instance, image, index, security_groups, flavor,
num_instances, shutdown_terminate): num_instances, shutdown_terminate,
):
"""Build the beginning of a new instance.""" """Build the beginning of a new instance."""
instance.launch_index = index instance.launch_index = index
@ -1893,7 +1897,7 @@ class API(base.Base):
info_cache.instance_uuid = instance.uuid info_cache.instance_uuid = instance.uuid
info_cache.network_info = network_model.NetworkInfo() info_cache.network_info = network_model.NetworkInfo()
instance.info_cache = info_cache instance.info_cache = info_cache
instance.flavor = instance_type instance.flavor = flavor
instance.old_flavor = None instance.old_flavor = None
instance.new_flavor = None instance.new_flavor = None
if CONF.ephemeral_storage_encryption.enabled: if CONF.ephemeral_storage_encryption.enabled:
@ -1918,7 +1922,7 @@ class API(base.Base):
instance.system_metadata = utils.instance_sys_meta(instance) instance.system_metadata = utils.instance_sys_meta(instance)
system_meta = utils.get_system_metadata_from_image( system_meta = utils.get_system_metadata_from_image(
image, instance_type) image, flavor)
# In case we couldn't find any suitable base_image # In case we couldn't find any suitable base_image
system_meta.setdefault('image_base_image_ref', instance.image_ref) system_meta.setdefault('image_base_image_ref', instance.image_ref)
@ -1965,8 +1969,7 @@ class API(base.Base):
tag.resource_id = resource_id tag.resource_id = resource_id
return instance_tags return instance_tags
def _check_multiple_instances_with_neutron_ports(self, def _check_multiple_instances_with_neutron_ports(self, requested_networks):
requested_networks):
"""Check whether multiple instances are created from port id(s).""" """Check whether multiple instances are created from port id(s)."""
for requested_net in requested_networks: for requested_net in requested_networks:
if requested_net.port_id: if requested_net.port_id:
@ -1984,21 +1987,23 @@ class API(base.Base):
"is specified.") "is specified.")
raise exception.InvalidFixedIpAndMaxCountRequest(reason=msg) raise exception.InvalidFixedIpAndMaxCountRequest(reason=msg)
def create(self, context, instance_type, def create(
image_href, kernel_id=None, ramdisk_id=None, self, context, flavor,
min_count=None, max_count=None, image_href, kernel_id=None, ramdisk_id=None,
display_name=None, display_description=None, min_count=None, max_count=None,
key_name=None, key_data=None, security_groups=None, display_name=None, display_description=None,
availability_zone=None, forced_host=None, forced_node=None, key_name=None, key_data=None, security_groups=None,
user_data=None, metadata=None, injected_files=None, availability_zone=None, forced_host=None, forced_node=None,
admin_password=None, block_device_mapping=None, user_data=None, metadata=None, injected_files=None,
access_ip_v4=None, access_ip_v6=None, requested_networks=None, admin_password=None, block_device_mapping=None,
config_drive=None, auto_disk_config=None, scheduler_hints=None, access_ip_v4=None, access_ip_v6=None, requested_networks=None,
legacy_bdm=True, shutdown_terminate=False, config_drive=None, auto_disk_config=None, scheduler_hints=None,
check_server_group_quota=False, tags=None, legacy_bdm=True, shutdown_terminate=False,
supports_multiattach=False, trusted_certs=None, check_server_group_quota=False, tags=None,
supports_port_resource_request=False, supports_multiattach=False, trusted_certs=None,
requested_host=None, requested_hypervisor_hostname=None): supports_port_resource_request=False,
requested_host=None, requested_hypervisor_hostname=None,
):
"""Provision instances, sending instance information to the """Provision instances, sending instance information to the
scheduler. The scheduler will determine where the instance(s) scheduler. The scheduler will determine where the instance(s)
go and will handle creating the DB entries. go and will handle creating the DB entries.
@ -2021,10 +2026,10 @@ class API(base.Base):
raise exception.InvalidRequest(msg) raise exception.InvalidRequest(msg)
filter_properties = scheduler_utils.build_filter_properties( filter_properties = scheduler_utils.build_filter_properties(
scheduler_hints, forced_host, forced_node, instance_type) scheduler_hints, forced_host, forced_node, flavor)
return self._create_instance( return self._create_instance(
context, instance_type, context, flavor,
image_href, kernel_id, ramdisk_id, image_href, kernel_id, ramdisk_id,
min_count, max_count, min_count, max_count,
display_name, display_description, display_name, display_description,
@ -3972,14 +3977,14 @@ class API(base.Base):
self._check_auto_disk_config( self._check_auto_disk_config(
instance, auto_disk_config=auto_disk_config) instance, auto_disk_config=auto_disk_config)
current_instance_type = instance.get_flavor() current_flavor = instance.get_flavor()
# NOTE(aarents): Ensure image_base_image_ref is present as it will be # NOTE(aarents): Ensure image_base_image_ref is present as it will be
# needed during finish_resize/cross_cell_resize. Instances upgraded # needed during finish_resize/cross_cell_resize. Instances upgraded
# from an older nova release may not have this property because of # from an older nova release may not have this property because of
# a rebuild bug Bug/1893618. # a rebuild bug Bug/1893618.
instance.system_metadata.update( instance.system_metadata.update(
{'image_base_image_ref': instance.image_ref} {'image_base_image_ref': instance.image_ref}
) )
# If flavor_id is not provided, only migrate the instance. # If flavor_id is not provided, only migrate the instance.
@ -3987,52 +3992,51 @@ class API(base.Base):
if not flavor_id: if not flavor_id:
LOG.debug("flavor_id is None. Assuming migration.", LOG.debug("flavor_id is None. Assuming migration.",
instance=instance) instance=instance)
new_instance_type = current_instance_type new_flavor = current_flavor
else: else:
new_instance_type = flavors.get_flavor_by_flavor_id( new_flavor = flavors.get_flavor_by_flavor_id(
flavor_id, read_deleted="no") flavor_id, read_deleted="no")
# NOTE(wenping): We use this instead of the 'block_accelerator' # NOTE(wenping): We use this instead of the 'block_accelerator'
# decorator since the operation can differ depending on args, # decorator since the operation can differ depending on args,
# and for resize we have two flavors to worry about, we should # and for resize we have two flavors to worry about, we should
# reject resize with new flavor with accelerator. # reject resize with new flavor with accelerator.
if new_instance_type.extra_specs.get('accel:device_profile'): if new_flavor.extra_specs.get('accel:device_profile'):
raise exception.ForbiddenWithAccelerators() raise exception.ForbiddenWithAccelerators()
# Check to see if we're resizing to a zero-disk flavor which is # Check to see if we're resizing to a zero-disk flavor which is
# only supported with volume-backed servers. # only supported with volume-backed servers.
if (new_instance_type.get('root_gb') == 0 and if (new_flavor.get('root_gb') == 0 and
current_instance_type.get('root_gb') != 0): current_flavor.get('root_gb') != 0):
volume_backed = compute_utils.is_volume_backed_instance( volume_backed = compute_utils.is_volume_backed_instance(
context, instance) context, instance)
if not volume_backed: if not volume_backed:
reason = _('Resize to zero disk flavor is not allowed.') reason = _('Resize to zero disk flavor is not allowed.')
raise exception.CannotResizeDisk(reason=reason) raise exception.CannotResizeDisk(reason=reason)
current_instance_type_name = current_instance_type['name'] current_flavor_name = current_flavor['name']
new_instance_type_name = new_instance_type['name'] new_flavor_name = new_flavor['name']
LOG.debug("Old instance type %(current_instance_type_name)s, " LOG.debug("Old instance type %(current_flavor_name)s, "
"new instance type %(new_instance_type_name)s", "new instance type %(new_flavor_name)s",
{'current_instance_type_name': current_instance_type_name, {'current_flavor_name': current_flavor_name,
'new_instance_type_name': new_instance_type_name}, 'new_flavor_name': new_flavor_name},
instance=instance) instance=instance)
same_instance_type = (current_instance_type['id'] == same_flavor = current_flavor['id'] == new_flavor['id']
new_instance_type['id'])
# NOTE(sirp): We don't want to force a customer to change their flavor # NOTE(sirp): We don't want to force a customer to change their flavor
# when Ops is migrating off of a failed host. # when Ops is migrating off of a failed host.
if not same_instance_type and new_instance_type.get('disabled'): if not same_flavor and new_flavor.get('disabled'):
raise exception.FlavorNotFound(flavor_id=flavor_id) raise exception.FlavorNotFound(flavor_id=flavor_id)
if same_instance_type and flavor_id: if same_flavor and flavor_id:
raise exception.CannotResizeToSameFlavor() raise exception.CannotResizeToSameFlavor()
# ensure there is sufficient headroom for upsizes # ensure there is sufficient headroom for upsizes
if flavor_id: if flavor_id:
self._check_quota_for_upsize(context, instance, self._check_quota_for_upsize(context, instance,
current_instance_type, current_flavor,
new_instance_type) new_flavor)
if not same_instance_type: if not same_flavor:
image = utils.get_image_from_system_metadata( image = utils.get_image_from_system_metadata(
instance.system_metadata) instance.system_metadata)
# Figure out if the instance is volume-backed but only if we didn't # Figure out if the instance is volume-backed but only if we didn't
@ -4047,14 +4051,14 @@ class API(base.Base):
# resize case. # resize case.
if volume_backed: if volume_backed:
self._validate_flavor_image_numa_pci( self._validate_flavor_image_numa_pci(
image, new_instance_type, validate_pci=True) image, new_flavor, validate_pci=True)
else: else:
self._validate_flavor_image_nostatus( self._validate_flavor_image_nostatus(
context, image, new_instance_type, root_bdm=None, context, image, new_flavor, root_bdm=None,
validate_pci=True) validate_pci=True)
filter_properties = {'ignore_hosts': []} filter_properties = {'ignore_hosts': []}
if not self._allow_resize_to_same_host(same_instance_type, instance): if not self._allow_resize_to_same_host(same_flavor, instance):
filter_properties['ignore_hosts'].append(instance.host) filter_properties['ignore_hosts'].append(instance.host)
request_spec = objects.RequestSpec.get_by_instance_uuid( request_spec = objects.RequestSpec.get_by_instance_uuid(
@ -4062,9 +4066,9 @@ class API(base.Base):
request_spec.ignore_hosts = filter_properties['ignore_hosts'] request_spec.ignore_hosts = filter_properties['ignore_hosts']
# don't recalculate the NUMA topology unless the flavor has changed # don't recalculate the NUMA topology unless the flavor has changed
if not same_instance_type: if not same_flavor:
request_spec.numa_topology = hardware.numa_get_constraints( request_spec.numa_topology = hardware.numa_get_constraints(
new_instance_type, instance.image_meta) new_flavor, instance.image_meta)
# TODO(huaqiang): Remove in Wallaby # TODO(huaqiang): Remove in Wallaby
# check nova-compute nodes have been updated to Victoria to resize # check nova-compute nodes have been updated to Victoria to resize
# instance to a new mixed instance from a dedicated or shared # instance to a new mixed instance from a dedicated or shared
@ -4107,9 +4111,10 @@ class API(base.Base):
# Asynchronously RPC cast to conductor so the response is not blocked # Asynchronously RPC cast to conductor so the response is not blocked
# during scheduling. If something fails the user can find out via # during scheduling. If something fails the user can find out via
# instance actions. # instance actions.
self.compute_task_api.resize_instance(context, instance, self.compute_task_api.resize_instance(
context, instance,
scheduler_hint=scheduler_hint, scheduler_hint=scheduler_hint,
flavor=new_instance_type, flavor=new_flavor,
clean_shutdown=clean_shutdown, clean_shutdown=clean_shutdown,
request_spec=request_spec, request_spec=request_spec,
do_cast=True) do_cast=True)

View File

@ -215,7 +215,7 @@ class _ComputeAPIUnitTestMixIn(object):
get_image.return_value = (None, {}) get_image.return_value = (None, {})
check_requested_networks.return_value = 1 check_requested_networks.return_value = 1
instance_type = self._create_flavor() flavor = self._create_flavor()
port = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' port = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
address = '10.0.0.1' address = '10.0.0.1'
@ -226,7 +226,7 @@ class _ComputeAPIUnitTestMixIn(object):
with mock.patch.object(self.compute_api.network_api, with mock.patch.object(self.compute_api.network_api,
'create_resource_requests', 'create_resource_requests',
return_value=(None, [])): return_value=(None, [])):
self.compute_api.create(self.context, instance_type, 'image_id', self.compute_api.create(self.context, flavor, 'image_id',
requested_networks=requested_networks, requested_networks=requested_networks,
max_count=None) max_count=None)
@ -239,7 +239,7 @@ class _ComputeAPIUnitTestMixIn(object):
mock_limit_check, mock_count): mock_limit_check, mock_count):
image_href = "image_href" image_href = "image_href"
image_id = 0 image_id = 0
instance_type = self._create_flavor() flavor = self._create_flavor()
quotas = {'instances': 1, 'cores': 1, 'ram': 1} quotas = {'instances': 1, 'cores': 1, 'ram': 1}
quota_exception = exception.OverQuota(quotas=quotas, quota_exception = exception.OverQuota(quotas=quotas,
@ -259,7 +259,7 @@ class _ComputeAPIUnitTestMixIn(object):
return_value=(image_id, {})) as mock_get_image: return_value=(image_id, {})) as mock_get_image:
for min_count, message in [(20, '20-40'), (40, '40')]: for min_count, message in [(20, '20-40'), (40, '40')]:
try: try:
self.compute_api.create(self.context, instance_type, self.compute_api.create(self.context, flavor,
"image_href", min_count=min_count, "image_href", min_count=min_count,
max_count=40) max_count=40)
except exception.TooManyInstances as e: except exception.TooManyInstances as e:
@ -277,7 +277,7 @@ class _ComputeAPIUnitTestMixIn(object):
# creating a volume-backed instance # creating a volume-backed instance
self.assertRaises(exception.CertificateValidationFailed, self.assertRaises(exception.CertificateValidationFailed,
self.compute_api.create, self.context, self.compute_api.create, self.context,
instance_type=self._create_flavor(), image_href=None, flavor=self._create_flavor(), image_href=None,
trusted_certs=['test-cert-1', 'test-cert-2']) trusted_certs=['test-cert-1', 'test-cert-2'])
@mock.patch('nova.objects.Quotas.limit_check') @mock.patch('nova.objects.Quotas.limit_check')
@ -290,7 +290,7 @@ class _ComputeAPIUnitTestMixIn(object):
# creating a volume-backed instance # creating a volume-backed instance
self.assertRaises(exception.CertificateValidationFailed, self.assertRaises(exception.CertificateValidationFailed,
self.compute_api.create, self.context, self.compute_api.create, self.context,
instance_type=self._create_flavor(), flavor=self._create_flavor(),
image_href=None) image_href=None)
def _test_create_max_net_count(self, max_net_count, min_count, max_count): def _test_create_max_net_count(self, max_net_count, min_count, max_count):
@ -4628,7 +4628,7 @@ class _ComputeAPIUnitTestMixIn(object):
side_effect=exception.CinderConnectionFailed(reason='error')) side_effect=exception.CinderConnectionFailed(reason='error'))
def test_validate_bdm_with_cinder_down(self, mock_get_snapshot): def test_validate_bdm_with_cinder_down(self, mock_get_snapshot):
instance = self._create_instance_obj() instance = self._create_instance_obj()
instance_type = self._create_flavor() flavor = self._create_flavor()
bdms = [objects.BlockDeviceMapping( bdms = [objects.BlockDeviceMapping(
**fake_block_device.FakeDbBlockDeviceDict( **fake_block_device.FakeDbBlockDeviceDict(
{ {
@ -4643,7 +4643,7 @@ class _ComputeAPIUnitTestMixIn(object):
self.assertRaises(exception.CinderConnectionFailed, self.assertRaises(exception.CinderConnectionFailed,
self.compute_api._validate_bdm, self.compute_api._validate_bdm,
self.context, self.context,
instance, instance_type, bdms, image_cache, volumes) instance, flavor, bdms, image_cache, volumes)
@mock.patch.object(cinder.API, 'attachment_create', @mock.patch.object(cinder.API, 'attachment_create',
side_effect=exception.InvalidInput(reason='error')) side_effect=exception.InvalidInput(reason='error'))
@ -4653,7 +4653,7 @@ class _ComputeAPIUnitTestMixIn(object):
# 'available' results in _validate_bdm re-raising InvalidVolume. # 'available' results in _validate_bdm re-raising InvalidVolume.
instance = self._create_instance_obj() instance = self._create_instance_obj()
del instance.id del instance.id
instance_type = self._create_flavor() flavor = self._create_flavor()
volume_id = 'e856840e-9f5b-4894-8bde-58c6e29ac1e8' volume_id = 'e856840e-9f5b-4894-8bde-58c6e29ac1e8'
volume_info = {'status': 'error', volume_info = {'status': 'error',
'attach_status': 'detached', 'attach_status': 'detached',
@ -4671,7 +4671,7 @@ class _ComputeAPIUnitTestMixIn(object):
self.assertRaises(exception.InvalidVolume, self.assertRaises(exception.InvalidVolume,
self.compute_api._validate_bdm, self.compute_api._validate_bdm,
self.context, self.context,
instance, instance_type, bdms, {}, instance, flavor, bdms, {},
{volume_id: volume_info}) {volume_id: volume_info})
mock_attach_create.assert_called_once_with( mock_attach_create.assert_called_once_with(
@ -4694,7 +4694,7 @@ class _ComputeAPIUnitTestMixIn(object):
"""Test _check_requested_volume_type method is used. """Test _check_requested_volume_type method is used.
""" """
instance = self._create_instance_obj() instance = self._create_instance_obj()
instance_type = self._create_flavor() flavor = self._create_flavor()
volume_type = 'fake_lvm_1' volume_type = 'fake_lvm_1'
volume_types = [{'id': 'fake_volume_type_id_1', 'name': 'fake_lvm_1'}, volume_types = [{'id': 'fake_volume_type_id_1', 'name': 'fake_lvm_1'},
@ -4733,7 +4733,7 @@ class _ComputeAPIUnitTestMixIn(object):
image_cache = volumes = {} image_cache = volumes = {}
self.compute_api._validate_bdm(self.context, instance, self.compute_api._validate_bdm(self.context, instance,
instance_type, bdms, image_cache, flavor, bdms, image_cache,
volumes) volumes)
get_all_vol_types.assert_called_once_with(self.context) get_all_vol_types.assert_called_once_with(self.context)
@ -4951,7 +4951,7 @@ class _ComputeAPIUnitTestMixIn(object):
@mock.patch('nova.objects.Instance') @mock.patch('nova.objects.Instance')
@mock.patch('nova.objects.InstanceMapping.create') @mock.patch('nova.objects.InstanceMapping.create')
def _test_provision_instances_with_accels(self, def _test_provision_instances_with_accels(self,
instance_type, dp_request_groups, prev_request_groups, flavor, dp_request_groups, prev_request_groups,
mock_im, mock_instance, mock_br, mock_rs, mock_get_dp): mock_im, mock_instance, mock_br, mock_rs, mock_get_dp):
@mock.patch.object(self.compute_api, '_get_volumes_for_bdms') @mock.patch.object(self.compute_api, '_get_volumes_for_bdms')
@ -4968,7 +4968,7 @@ class _ComputeAPIUnitTestMixIn(object):
def do_test(mock_bdm_v, mock_sg, mock_cniq, mock_get_vols): def do_test(mock_bdm_v, mock_sg, mock_cniq, mock_get_vols):
mock_cniq.return_value = 1 mock_cniq.return_value = 1
self.compute_api._provision_instances(self.context, self.compute_api._provision_instances(self.context,
instance_type, flavor,
1, 1, mock.MagicMock(), 1, 1, mock.MagicMock(),
{}, None, {}, None,
None, None, None, {}, None, None, None, None, {}, None,
@ -4988,7 +4988,7 @@ class _ComputeAPIUnitTestMixIn(object):
# should be obtained, and added to reqspec's requested_resources. # should be obtained, and added to reqspec's requested_resources.
dp_name = 'mydp' dp_name = 'mydp'
extra_specs = {'extra_specs': {'accel:device_profile': dp_name}} extra_specs = {'extra_specs': {'accel:device_profile': dp_name}}
instance_type = self._create_flavor(**extra_specs) flavor = self._create_flavor(**extra_specs)
prev_groups = [objects.RequestGroup(requester_id='prev0'), prev_groups = [objects.RequestGroup(requester_id='prev0'),
objects.RequestGroup(requester_id='prev1')] objects.RequestGroup(requester_id='prev1')]
@ -4996,7 +4996,7 @@ class _ComputeAPIUnitTestMixIn(object):
objects.RequestGroup(requester_id='deviceprofile3')] objects.RequestGroup(requester_id='deviceprofile3')]
mock_get_dp, fake_rs = self._test_provision_instances_with_accels( mock_get_dp, fake_rs = self._test_provision_instances_with_accels(
instance_type, dp_groups, prev_groups) flavor, dp_groups, prev_groups)
mock_get_dp.assert_called_once_with(self.context, dp_name) mock_get_dp.assert_called_once_with(self.context, dp_name)
self.assertEqual(prev_groups + dp_groups, fake_rs.requested_resources) self.assertEqual(prev_groups + dp_groups, fake_rs.requested_resources)
@ -5004,11 +5004,11 @@ class _ComputeAPIUnitTestMixIn(object):
# If extra specs has no accel spec, no attempt should be made to # If extra specs has no accel spec, no attempt should be made to
# get device profile's request_groups, and reqspec.requested_resources # get device profile's request_groups, and reqspec.requested_resources
# should be left unchanged. # should be left unchanged.
instance_type = self._create_flavor() flavor = self._create_flavor()
prev_groups = [objects.RequestGroup(requester_id='prev0'), prev_groups = [objects.RequestGroup(requester_id='prev0'),
objects.RequestGroup(requester_id='prev1')] objects.RequestGroup(requester_id='prev1')]
mock_get_dp, fake_rs = self._test_provision_instances_with_accels( mock_get_dp, fake_rs = self._test_provision_instances_with_accels(
instance_type, [], prev_groups) flavor, [], prev_groups)
mock_get_dp.assert_not_called() mock_get_dp.assert_not_called()
self.assertEqual(prev_groups, fake_rs.requested_resources) self.assertEqual(prev_groups, fake_rs.requested_resources)
@ -5654,7 +5654,7 @@ class _ComputeAPIUnitTestMixIn(object):
self._test_detach_interface_invalid_state(state) self._test_detach_interface_invalid_state(state)
def _test_check_and_transform_bdm(self, block_device_mapping): def _test_check_and_transform_bdm(self, block_device_mapping):
instance_type = self._create_flavor() flavor = self._create_flavor()
base_options = {'uuid': uuids.bdm_instance, base_options = {'uuid': uuids.bdm_instance,
'image_ref': 'fake_image_ref', 'image_ref': 'fake_image_ref',
'metadata': {}} 'metadata': {}}
@ -5667,7 +5667,7 @@ class _ComputeAPIUnitTestMixIn(object):
block_device_mapping = block_device_mapping block_device_mapping = block_device_mapping
self.assertRaises(exception.InvalidRequest, self.assertRaises(exception.InvalidRequest,
self.compute_api._check_and_transform_bdm, self.compute_api._check_and_transform_bdm,
self.context, base_options, instance_type, self.context, base_options, flavor,
image_meta, 1, 1, block_device_mapping, legacy_bdm) image_meta, 1, 1, block_device_mapping, legacy_bdm)
def test_check_and_transform_bdm_source_volume(self): def test_check_and_transform_bdm_source_volume(self):
@ -5698,8 +5698,8 @@ class _ComputeAPIUnitTestMixIn(object):
swap_size = 42 swap_size = 42
ephemeral_size = 24 ephemeral_size = 24
instance = self._create_instance_obj() instance = self._create_instance_obj()
instance_type = self._create_flavor(swap=swap_size, flavor = self._create_flavor(
ephemeral_gb=ephemeral_size) swap=swap_size, ephemeral_gb=ephemeral_size)
block_device_mapping = [ block_device_mapping = [
{'device_name': '/dev/sda1', {'device_name': '/dev/sda1',
'source_type': 'snapshot', 'destination_type': 'volume', 'source_type': 'snapshot', 'destination_type': 'volume',
@ -5722,7 +5722,7 @@ class _ComputeAPIUnitTestMixIn(object):
with mock.patch.object(self.compute_api, '_validate_bdm'): with mock.patch.object(self.compute_api, '_validate_bdm'):
image_cache = volumes = {} image_cache = volumes = {}
bdms = self.compute_api._bdm_validate_set_size_and_instance( bdms = self.compute_api._bdm_validate_set_size_and_instance(
self.context, instance, instance_type, block_device_mapping, self.context, instance, flavor, block_device_mapping,
image_cache, volumes) image_cache, volumes)
expected = [{'device_name': '/dev/sda1', expected = [{'device_name': '/dev/sda1',
@ -7083,7 +7083,7 @@ class ComputeAPIUnitTestCase(_ComputeAPIUnitTestMixIn, test.NoDBTestCase):
requested Neutron security group and that will be returned from requested Neutron security group and that will be returned from
_validate_and_build_base_options _validate_and_build_base_options
""" """
instance_type = objects.Flavor(**test_flavor.fake_flavor) flavor = objects.Flavor(**test_flavor.fake_flavor)
boot_meta = metadata = {} boot_meta = metadata = {}
kernel_id = ramdisk_id = key_name = key_data = user_data = \ kernel_id = ramdisk_id = key_name = key_data = user_data = \
access_ip_v4 = access_ip_v6 = config_drive = \ access_ip_v4 = access_ip_v6 = config_drive = \
@ -7102,7 +7102,7 @@ class ComputeAPIUnitTestCase(_ComputeAPIUnitTestMixIn, test.NoDBTestCase):
base_options, max_network_count, key_pair, security_groups, \ base_options, max_network_count, key_pair, security_groups, \
network_metadata = ( network_metadata = (
self.compute_api._validate_and_build_base_options( self.compute_api._validate_and_build_base_options(
self.context, instance_type, boot_meta, uuids.image_href, self.context, flavor, boot_meta, uuids.image_href,
mock.sentinel.image_id, kernel_id, ramdisk_id, mock.sentinel.image_id, kernel_id, ramdisk_id,
'fake-display-name', 'fake-description', key_name, 'fake-display-name', 'fake-description', key_name,
key_data, requested_secgroups, 'fake-az', user_data, key_data, requested_secgroups, 'fake-az', user_data,

View File

@ -1621,7 +1621,7 @@ class ComputeTestCase(BaseTestCase,
self.assertRaises(exception.MultiplePortsNotApplicable, self.assertRaises(exception.MultiplePortsNotApplicable,
self.compute_api.create, self.compute_api.create,
self.context, self.context,
instance_type=self.default_flavor, flavor=self.default_flavor,
image_href=None, image_href=None,
max_count=2, max_count=2,
requested_networks=requested_networks) requested_networks=requested_networks)
@ -8612,11 +8612,12 @@ class ComputeAPITestCase(BaseTestCase):
def test_create_instance_sets_system_metadata(self): def test_create_instance_sets_system_metadata(self):
# Make sure image properties are copied into system metadata. # Make sure image properties are copied into system metadata.
with mock.patch.object(self.compute_api.compute_task_api, with mock.patch.object(
'schedule_and_build_instances') as mock_sbi: self.compute_api.compute_task_api, 'schedule_and_build_instances',
(ref, resv_id) = self.compute_api.create( ) as mock_sbi:
ref, resv_id = self.compute_api.create(
self.context, self.context,
instance_type=self.default_flavor, flavor=self.default_flavor,
image_href='f5000000-0000-0000-0000-000000000000') image_href='f5000000-0000-0000-0000-000000000000')
build_call = mock_sbi.call_args_list[0] build_call = mock_sbi.call_args_list[0]
@ -8630,11 +8631,12 @@ class ComputeAPITestCase(BaseTestCase):
self.assertEqual(value, instance.system_metadata[key]) self.assertEqual(value, instance.system_metadata[key])
def test_create_saves_flavor(self): def test_create_saves_flavor(self):
with mock.patch.object(self.compute_api.compute_task_api, with mock.patch.object(
'schedule_and_build_instances') as mock_sbi: self.compute_api.compute_task_api, 'schedule_and_build_instances',
(ref, resv_id) = self.compute_api.create( ) as mock_sbi:
ref, resv_id = self.compute_api.create(
self.context, self.context,
instance_type=self.default_flavor, flavor=self.default_flavor,
image_href=uuids.image_href_id) image_href=uuids.image_href_id)
build_call = mock_sbi.call_args_list[0] build_call = mock_sbi.call_args_list[0]
@ -8654,7 +8656,7 @@ class ComputeAPITestCase(BaseTestCase):
) as (mock_sbi, mock_secgroups): ) as (mock_sbi, mock_secgroups):
self.compute_api.create( self.compute_api.create(
self.context, self.context,
instance_type=self.default_flavor, flavor=self.default_flavor,
image_href=uuids.image_href_id, image_href=uuids.image_href_id,
security_groups=['testgroup']) security_groups=['testgroup'])
@ -8671,12 +8673,13 @@ class ComputeAPITestCase(BaseTestCase):
'nova.network.security_group_api.validate_name', 'nova.network.security_group_api.validate_name',
side_effect=exception.SecurityGroupNotFound('foo'), side_effect=exception.SecurityGroupNotFound('foo'),
) as mock_secgroups: ) as mock_secgroups:
self.assertRaises(exception.SecurityGroupNotFound, self.assertRaises(
self.compute_api.create, exception.SecurityGroupNotFound,
self.context, self.compute_api.create,
instance_type=self.default_flavor, self.context,
image_href=None, flavor=self.default_flavor,
security_groups=['invalid_sec_group']) image_href=None,
security_groups=['invalid_sec_group'])
self.assertEqual(pre_build_len, self.assertEqual(pre_build_len,
len(db.instance_get_all(self.context))) len(db.instance_get_all(self.context)))
@ -8697,7 +8700,7 @@ class ComputeAPITestCase(BaseTestCase):
) as (mock_sbi, _mock_create_resreqs): ) as (mock_sbi, _mock_create_resreqs):
self.compute_api.create( self.compute_api.create(
self.context, self.context,
instance_type=self.default_flavor, flavor=self.default_flavor,
image_href=uuids.image_href_id, image_href=uuids.image_href_id,
requested_networks=requested_networks) requested_networks=requested_networks)
@ -8737,14 +8740,14 @@ class ComputeAPITestCase(BaseTestCase):
instance = objects.Instance() instance = objects.Instance()
instance.update(base_options) instance.update(base_options)
instance = self.compute_api._populate_instance_for_create( instance = self.compute_api._populate_instance_for_create(
self.context, self.context,
instance, instance,
self.fake_image, self.fake_image,
1, 1,
security_groups=objects.SecurityGroupList(), security_groups=objects.SecurityGroupList(),
instance_type=self.tiny_flavor, flavor=self.tiny_flavor,
num_instances=num_instances, num_instances=num_instances,
shutdown_terminate=False) shutdown_terminate=False)
self.assertEqual(str(base_options['image_ref']), self.assertEqual(str(base_options['image_ref']),
instance['system_metadata']['image_base_image_ref']) instance['system_metadata']['image_base_image_ref'])
self.assertEqual(vm_states.BUILDING, instance['vm_state']) self.assertEqual(vm_states.BUILDING, instance['vm_state'])
@ -8772,14 +8775,14 @@ class ComputeAPITestCase(BaseTestCase):
self.compute_api.key_manager = key_manager.API() self.compute_api.key_manager = key_manager.API()
index = 1 index = 1
instance = self.compute_api._populate_instance_for_create( instance = self.compute_api._populate_instance_for_create(
self.context, self.context,
instance, instance,
self.fake_image, self.fake_image,
index, index,
security_groups=objects.SecurityGroupList(), security_groups=objects.SecurityGroupList(),
instance_type=self.tiny_flavor, flavor=self.tiny_flavor,
num_instances=num_instances, num_instances=num_instances,
shutdown_terminate=False) shutdown_terminate=False)
self.assertIsNotNone(instance.ephemeral_key_uuid) self.assertIsNotNone(instance.ephemeral_key_uuid)
def test_default_hostname_generator(self): def test_default_hostname_generator(self):

View File

@ -64,7 +64,7 @@ class QuotaIntegrationTestCase(test.TestCase):
self.context = context.RequestContext(self.user_id, self.context = context.RequestContext(self.user_id,
self.project_id, self.project_id,
is_admin=True) is_admin=True)
self.inst_type = objects.Flavor.get_by_name(self.context, 'm1.small') self.flavor = objects.Flavor.get_by_name(self.context, 'm1.small')
self.useFixture(nova_fixtures.GlanceFixture(self)) self.useFixture(nova_fixtures.GlanceFixture(self))
@ -106,9 +106,9 @@ class QuotaIntegrationTestCase(test.TestCase):
self._create_instance() self._create_instance()
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175' image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
try: try:
self.compute_api.create(self.context, min_count=1, max_count=1, self.compute_api.create(
instance_type=self.inst_type, self.context, min_count=1, max_count=1,
image_href=image_uuid) flavor=self.flavor, image_href=image_uuid)
except exception.QuotaError as e: except exception.QuotaError as e:
expected_kwargs = {'code': 413, expected_kwargs = {'code': 413,
'req': '1, 1', 'req': '1, 1',
@ -123,9 +123,9 @@ class QuotaIntegrationTestCase(test.TestCase):
self._create_instance() self._create_instance()
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175' image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
try: try:
self.compute_api.create(self.context, min_count=1, max_count=1, self.compute_api.create(
instance_type=self.inst_type, self.context, min_count=1, max_count=1, flavor=self.flavor,
image_href=image_uuid) image_href=image_uuid)
except exception.QuotaError as e: except exception.QuotaError as e:
expected_kwargs = {'code': 413, expected_kwargs = {'code': 413,
'req': '1', 'req': '1',
@ -149,27 +149,22 @@ class QuotaIntegrationTestCase(test.TestCase):
for i in range(CONF.quota.metadata_items + 1): for i in range(CONF.quota.metadata_items + 1):
metadata['key%s' % i] = 'value%s' % i metadata['key%s' % i] = 'value%s' % i
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175' image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
self.assertRaises(exception.QuotaError, self.compute_api.create, self.assertRaises(
self.context, exception.QuotaError, self.compute_api.create,
min_count=1, self.context, min_count=1, max_count=1, flavor=self.flavor,
max_count=1, image_href=image_uuid, metadata=metadata)
instance_type=self.inst_type,
image_href=image_uuid,
metadata=metadata)
def _create_with_injected_files(self, files): def _create_with_injected_files(self, files):
api = self.compute_api api = self.compute_api
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175' image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
api.create(self.context, min_count=1, max_count=1, api.create(
instance_type=self.inst_type, image_href=image_uuid, self.context, min_count=1, max_count=1, flavor=self.flavor,
injected_files=files) image_href=image_uuid, injected_files=files)
def test_no_injected_files(self): def test_no_injected_files(self):
api = self.compute_api api = self.compute_api
image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175' image_uuid = 'cedef40a-ed67-4d10-800e-17455edce175'
api.create(self.context, api.create(self.context, flavor=self.flavor, image_href=image_uuid)
instance_type=self.inst_type,
image_href=image_uuid)
def test_max_injected_files(self): def test_max_injected_files(self):
files = [] files = []