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:
parent
61256b4f78
commit
1de6e960af
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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 = []
|
||||||
|
|
Loading…
Reference in New Issue