Merge "compute: enhance compute evacuate instance to support target state"
This commit is contained in:
commit
ac6f895361
@ -3797,7 +3797,8 @@ class API:
|
|||||||
orig_sys_metadata=orig_sys_metadata, bdms=bdms,
|
orig_sys_metadata=orig_sys_metadata, bdms=bdms,
|
||||||
preserve_ephemeral=preserve_ephemeral, host=host,
|
preserve_ephemeral=preserve_ephemeral, host=host,
|
||||||
request_spec=request_spec,
|
request_spec=request_spec,
|
||||||
reimage_boot_volume=reimage_boot_volume)
|
reimage_boot_volume=reimage_boot_volume,
|
||||||
|
target_state=None)
|
||||||
|
|
||||||
def _check_volume_status(self, context, bdms):
|
def _check_volume_status(self, context, bdms):
|
||||||
"""Check whether the status of the volume is "in-use".
|
"""Check whether the status of the volume is "in-use".
|
||||||
@ -5617,7 +5618,7 @@ class API:
|
|||||||
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.STOPPED,
|
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.STOPPED,
|
||||||
vm_states.ERROR], task_state=None)
|
vm_states.ERROR], task_state=None)
|
||||||
def evacuate(self, context, instance, host, on_shared_storage,
|
def evacuate(self, context, instance, host, on_shared_storage,
|
||||||
admin_password=None, force=None):
|
admin_password=None, force=None, target_state=None):
|
||||||
"""Running evacuate to target host.
|
"""Running evacuate to target host.
|
||||||
|
|
||||||
Checking vm compute host state, if the host not in expected_state,
|
Checking vm compute host state, if the host not in expected_state,
|
||||||
@ -5628,6 +5629,7 @@ class API:
|
|||||||
:param on_shared_storage: True if instance files on shared storage
|
:param on_shared_storage: True if instance files on shared storage
|
||||||
:param admin_password: password to set on rebuilt instance
|
:param admin_password: password to set on rebuilt instance
|
||||||
:param force: Force the evacuation to the specific host target
|
:param force: Force the evacuation to the specific host target
|
||||||
|
:param target_state: Set a target state for the evacuated instance
|
||||||
|
|
||||||
"""
|
"""
|
||||||
LOG.debug('vm evacuation scheduled', instance=instance)
|
LOG.debug('vm evacuation scheduled', instance=instance)
|
||||||
@ -5691,7 +5693,7 @@ class API:
|
|||||||
on_shared_storage=on_shared_storage,
|
on_shared_storage=on_shared_storage,
|
||||||
host=host,
|
host=host,
|
||||||
request_spec=request_spec,
|
request_spec=request_spec,
|
||||||
)
|
target_state=target_state)
|
||||||
|
|
||||||
def get_migrations(self, context, filters):
|
def get_migrations(self, context, filters):
|
||||||
"""Get all migrations for the given filters."""
|
"""Get all migrations for the given filters."""
|
||||||
|
@ -618,7 +618,7 @@ class ComputeVirtAPI(virtapi.VirtAPI):
|
|||||||
class ComputeManager(manager.Manager):
|
class ComputeManager(manager.Manager):
|
||||||
"""Manages the running instances from creation to destruction."""
|
"""Manages the running instances from creation to destruction."""
|
||||||
|
|
||||||
target = messaging.Target(version='6.1')
|
target = messaging.Target(version='6.2')
|
||||||
|
|
||||||
def __init__(self, compute_driver=None, *args, **kwargs):
|
def __init__(self, compute_driver=None, *args, **kwargs):
|
||||||
"""Load configuration options and connect to the hypervisor."""
|
"""Load configuration options and connect to the hypervisor."""
|
||||||
@ -3696,7 +3696,7 @@ class ComputeManager(manager.Manager):
|
|||||||
bdms, recreate, on_shared_storage,
|
bdms, recreate, on_shared_storage,
|
||||||
preserve_ephemeral, migration,
|
preserve_ephemeral, migration,
|
||||||
scheduled_node, limits, request_spec, accel_uuids,
|
scheduled_node, limits, request_spec, accel_uuids,
|
||||||
reimage_boot_volume):
|
reimage_boot_volume, target_state):
|
||||||
"""Destroy and re-make this instance.
|
"""Destroy and re-make this instance.
|
||||||
|
|
||||||
A 'rebuild' effectively purges all existing data from the system and
|
A 'rebuild' effectively purges all existing data from the system and
|
||||||
@ -3731,6 +3731,7 @@ class ComputeManager(manager.Manager):
|
|||||||
:param reimage_boot_volume: Boolean to specify whether the user has
|
:param reimage_boot_volume: Boolean to specify whether the user has
|
||||||
explicitly requested to rebuild a boot
|
explicitly requested to rebuild a boot
|
||||||
volume
|
volume
|
||||||
|
:param target_state: Set a target state for the evacuated instance.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# recreate=True means the instance is being evacuated from a failed
|
# recreate=True means the instance is being evacuated from a failed
|
||||||
@ -3795,7 +3796,8 @@ class ComputeManager(manager.Manager):
|
|||||||
image_meta, injected_files, new_pass, orig_sys_metadata,
|
image_meta, injected_files, new_pass, orig_sys_metadata,
|
||||||
bdms, evacuate, on_shared_storage, preserve_ephemeral,
|
bdms, evacuate, on_shared_storage, preserve_ephemeral,
|
||||||
migration, request_spec, allocs, rebuild_claim,
|
migration, request_spec, allocs, rebuild_claim,
|
||||||
scheduled_node, limits, accel_uuids, reimage_boot_volume)
|
scheduled_node, limits, accel_uuids, reimage_boot_volume,
|
||||||
|
target_state)
|
||||||
except (exception.ComputeResourcesUnavailable,
|
except (exception.ComputeResourcesUnavailable,
|
||||||
exception.RescheduledException) as e:
|
exception.RescheduledException) as e:
|
||||||
if isinstance(e, exception.ComputeResourcesUnavailable):
|
if isinstance(e, exception.ComputeResourcesUnavailable):
|
||||||
@ -3855,7 +3857,7 @@ class ComputeManager(manager.Manager):
|
|||||||
injected_files, new_pass, orig_sys_metadata, bdms, evacuate,
|
injected_files, new_pass, orig_sys_metadata, bdms, evacuate,
|
||||||
on_shared_storage, preserve_ephemeral, migration, request_spec,
|
on_shared_storage, preserve_ephemeral, migration, request_spec,
|
||||||
allocations, rebuild_claim, scheduled_node, limits, accel_uuids,
|
allocations, rebuild_claim, scheduled_node, limits, accel_uuids,
|
||||||
reimage_boot_volume):
|
reimage_boot_volume, target_state):
|
||||||
"""Helper to avoid deep nesting in the top-level method."""
|
"""Helper to avoid deep nesting in the top-level method."""
|
||||||
|
|
||||||
provider_mapping = None
|
provider_mapping = None
|
||||||
@ -3879,7 +3881,8 @@ class ComputeManager(manager.Manager):
|
|||||||
context, instance, orig_image_ref, image_meta, injected_files,
|
context, instance, orig_image_ref, image_meta, injected_files,
|
||||||
new_pass, orig_sys_metadata, bdms, evacuate, on_shared_storage,
|
new_pass, orig_sys_metadata, bdms, evacuate, on_shared_storage,
|
||||||
preserve_ephemeral, migration, request_spec, allocations,
|
preserve_ephemeral, migration, request_spec, allocations,
|
||||||
provider_mapping, accel_uuids, reimage_boot_volume)
|
provider_mapping, accel_uuids, reimage_boot_volume,
|
||||||
|
target_state)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_image_name(image_meta):
|
def _get_image_name(image_meta):
|
||||||
@ -3893,10 +3896,18 @@ class ComputeManager(manager.Manager):
|
|||||||
injected_files, new_pass, orig_sys_metadata, bdms, evacuate,
|
injected_files, new_pass, orig_sys_metadata, bdms, evacuate,
|
||||||
on_shared_storage, preserve_ephemeral, migration, request_spec,
|
on_shared_storage, preserve_ephemeral, migration, request_spec,
|
||||||
allocations, request_group_resource_providers_mapping,
|
allocations, request_group_resource_providers_mapping,
|
||||||
accel_uuids, reimage_boot_volume):
|
accel_uuids, reimage_boot_volume, target_state):
|
||||||
orig_vm_state = instance.vm_state
|
orig_vm_state = instance.vm_state
|
||||||
|
|
||||||
if evacuate:
|
if evacuate:
|
||||||
|
if target_state and orig_vm_state != vm_states.ERROR:
|
||||||
|
# This will ensure that at destination the instance will have
|
||||||
|
# the desired state.
|
||||||
|
if target_state not in vm_states.ALLOW_TARGET_STATES:
|
||||||
|
raise exception.InstanceEvacuateNotSupportedTargetState(
|
||||||
|
target_state=target_state)
|
||||||
|
orig_vm_state = target_state
|
||||||
|
|
||||||
if request_spec:
|
if request_spec:
|
||||||
# NOTE(gibi): Do a late check of server group policy as
|
# NOTE(gibi): Do a late check of server group policy as
|
||||||
# parallel scheduling could violate such policy. This will
|
# parallel scheduling could violate such policy. This will
|
||||||
@ -11369,7 +11380,7 @@ class _ComputeV5Proxy(object):
|
|||||||
bdms, recreate, on_shared_storage,
|
bdms, recreate, on_shared_storage,
|
||||||
preserve_ephemeral, migration,
|
preserve_ephemeral, migration,
|
||||||
scheduled_node, limits, request_spec,
|
scheduled_node, limits, request_spec,
|
||||||
accel_uuids, False)
|
accel_uuids, False, None)
|
||||||
|
|
||||||
# 5.13 support for optional accel_uuids argument
|
# 5.13 support for optional accel_uuids argument
|
||||||
def shelve_instance(self, context, instance, image_id,
|
def shelve_instance(self, context, instance, image_id,
|
||||||
|
@ -403,6 +403,7 @@ class ComputeAPI(object):
|
|||||||
* ... - Rename the instance_type argument of resize_instance() to
|
* ... - Rename the instance_type argument of resize_instance() to
|
||||||
flavor
|
flavor
|
||||||
* 6.1 - Add reimage_boot_volume parameter to rebuild_instance()
|
* 6.1 - Add reimage_boot_volume parameter to rebuild_instance()
|
||||||
|
* 6.2 - Add target_state parameter to rebuild_instance()
|
||||||
'''
|
'''
|
||||||
|
|
||||||
VERSION_ALIASES = {
|
VERSION_ALIASES = {
|
||||||
@ -424,6 +425,7 @@ class ComputeAPI(object):
|
|||||||
'xena': '6.0',
|
'xena': '6.0',
|
||||||
'yoga': '6.0',
|
'yoga': '6.0',
|
||||||
'zed': '6.1',
|
'zed': '6.1',
|
||||||
|
'antilope': '6.2',
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -1083,7 +1085,7 @@ class ComputeAPI(object):
|
|||||||
image_ref, orig_image_ref, orig_sys_metadata, bdms,
|
image_ref, orig_image_ref, orig_sys_metadata, bdms,
|
||||||
recreate, on_shared_storage, host, node,
|
recreate, on_shared_storage, host, node,
|
||||||
preserve_ephemeral, migration, limits, request_spec, accel_uuids,
|
preserve_ephemeral, migration, limits, request_spec, accel_uuids,
|
||||||
reimage_boot_volume):
|
reimage_boot_volume, target_state):
|
||||||
|
|
||||||
# NOTE(edleafe): compute nodes can only use the dict form of limits.
|
# NOTE(edleafe): compute nodes can only use the dict form of limits.
|
||||||
if isinstance(limits, objects.SchedulerLimits):
|
if isinstance(limits, objects.SchedulerLimits):
|
||||||
@ -1096,11 +1098,19 @@ class ComputeAPI(object):
|
|||||||
'limits': limits,
|
'limits': limits,
|
||||||
'request_spec': request_spec,
|
'request_spec': request_spec,
|
||||||
'accel_uuids': accel_uuids,
|
'accel_uuids': accel_uuids,
|
||||||
'reimage_boot_volume': reimage_boot_volume
|
'reimage_boot_volume': reimage_boot_volume,
|
||||||
|
'target_state': target_state,
|
||||||
}
|
}
|
||||||
|
version = '6.2'
|
||||||
version = '6.1'
|
|
||||||
client = self.router.client(ctxt)
|
client = self.router.client(ctxt)
|
||||||
|
if not client.can_send_version(version):
|
||||||
|
if msg_args['target_state']:
|
||||||
|
raise exception.UnsupportedRPCVersion(
|
||||||
|
api="rebuild_instance",
|
||||||
|
required="6.2")
|
||||||
|
else:
|
||||||
|
del msg_args['target_state']
|
||||||
|
version = '6.1'
|
||||||
if not client.can_send_version(version):
|
if not client.can_send_version(version):
|
||||||
if msg_args['reimage_boot_volume']:
|
if msg_args['reimage_boot_volume']:
|
||||||
raise exception.NovaException(
|
raise exception.NovaException(
|
||||||
|
@ -76,3 +76,6 @@ ALLOW_TRIGGER_CRASH_DUMP = [ACTIVE, PAUSED, RESCUED, RESIZED, ERROR]
|
|||||||
|
|
||||||
# states we allow resources to be freed in
|
# states we allow resources to be freed in
|
||||||
ALLOW_RESOURCE_REMOVAL = [DELETED, SHELVED_OFFLOADED]
|
ALLOW_RESOURCE_REMOVAL = [DELETED, SHELVED_OFFLOADED]
|
||||||
|
|
||||||
|
# states we allow for evacuate instance
|
||||||
|
ALLOW_TARGET_STATES = [STOPPED]
|
||||||
|
@ -144,7 +144,8 @@ class ComputeTaskAPI(object):
|
|||||||
injected_files, new_pass, orig_sys_metadata,
|
injected_files, new_pass, orig_sys_metadata,
|
||||||
bdms, recreate=False, on_shared_storage=False,
|
bdms, recreate=False, on_shared_storage=False,
|
||||||
preserve_ephemeral=False, host=None,
|
preserve_ephemeral=False, host=None,
|
||||||
request_spec=None, reimage_boot_volume=False):
|
request_spec=None, reimage_boot_volume=False,
|
||||||
|
target_state=None):
|
||||||
self.conductor_compute_rpcapi.rebuild_instance(context,
|
self.conductor_compute_rpcapi.rebuild_instance(context,
|
||||||
instance=instance,
|
instance=instance,
|
||||||
new_pass=new_pass,
|
new_pass=new_pass,
|
||||||
@ -158,7 +159,8 @@ class ComputeTaskAPI(object):
|
|||||||
preserve_ephemeral=preserve_ephemeral,
|
preserve_ephemeral=preserve_ephemeral,
|
||||||
host=host,
|
host=host,
|
||||||
request_spec=request_spec,
|
request_spec=request_spec,
|
||||||
reimage_boot_volume=reimage_boot_volume)
|
reimage_boot_volume=reimage_boot_volume,
|
||||||
|
target_state=target_state)
|
||||||
|
|
||||||
def cache_images(self, context, aggregate, image_ids):
|
def cache_images(self, context, aggregate, image_ids):
|
||||||
"""Request images be pre-cached on hosts within an aggregate.
|
"""Request images be pre-cached on hosts within an aggregate.
|
||||||
|
@ -235,7 +235,7 @@ class ComputeTaskManager:
|
|||||||
may involve coordinating activities on multiple compute nodes.
|
may involve coordinating activities on multiple compute nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
target = messaging.Target(namespace='compute_task', version='1.24')
|
target = messaging.Target(namespace='compute_task', version='1.25')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||||
@ -1152,7 +1152,8 @@ class ComputeTaskManager:
|
|||||||
injected_files, new_pass, orig_sys_metadata,
|
injected_files, new_pass, orig_sys_metadata,
|
||||||
bdms, recreate, on_shared_storage,
|
bdms, recreate, on_shared_storage,
|
||||||
preserve_ephemeral=False, host=None,
|
preserve_ephemeral=False, host=None,
|
||||||
request_spec=None, reimage_boot_volume=False):
|
request_spec=None, reimage_boot_volume=False,
|
||||||
|
target_state=None):
|
||||||
# recreate=True means the instance is being evacuated from a failed
|
# recreate=True means the instance is being evacuated from a failed
|
||||||
# host to a new destination host. The 'recreate' variable name is
|
# host to a new destination host. The 'recreate' variable name is
|
||||||
# confusing, so rename it to evacuate here at the top, which is simpler
|
# confusing, so rename it to evacuate here at the top, which is simpler
|
||||||
@ -1356,7 +1357,8 @@ class ComputeTaskManager:
|
|||||||
limits=limits,
|
limits=limits,
|
||||||
request_spec=request_spec,
|
request_spec=request_spec,
|
||||||
accel_uuids=accel_uuids,
|
accel_uuids=accel_uuids,
|
||||||
reimage_boot_volume=reimage_boot_volume)
|
reimage_boot_volume=reimage_boot_volume,
|
||||||
|
target_state=target_state)
|
||||||
|
|
||||||
def _validate_image_traits_for_rebuild(self, context, instance, image_ref):
|
def _validate_image_traits_for_rebuild(self, context, instance, image_ref):
|
||||||
"""Validates that the traits specified in the image can be satisfied
|
"""Validates that the traits specified in the image can be satisfied
|
||||||
|
@ -287,6 +287,7 @@ class ComputeTaskAPI(object):
|
|||||||
1.22 - Added confirm_snapshot_based_resize()
|
1.22 - Added confirm_snapshot_based_resize()
|
||||||
1.23 - Added revert_snapshot_based_resize()
|
1.23 - Added revert_snapshot_based_resize()
|
||||||
1.24 - Add reimage_boot_volume parameter to rebuild_instance()
|
1.24 - Add reimage_boot_volume parameter to rebuild_instance()
|
||||||
|
1.25 - Add target_state parameter to rebuild_instance()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -428,8 +429,8 @@ class ComputeTaskAPI(object):
|
|||||||
image_ref, orig_image_ref, orig_sys_metadata, bdms,
|
image_ref, orig_image_ref, orig_sys_metadata, bdms,
|
||||||
recreate=False, on_shared_storage=False, host=None,
|
recreate=False, on_shared_storage=False, host=None,
|
||||||
preserve_ephemeral=False, request_spec=None,
|
preserve_ephemeral=False, request_spec=None,
|
||||||
reimage_boot_volume=False):
|
reimage_boot_volume=False, target_state=None):
|
||||||
version = '1.24'
|
version = '1.25'
|
||||||
kw = {'instance': instance,
|
kw = {'instance': instance,
|
||||||
'new_pass': new_pass,
|
'new_pass': new_pass,
|
||||||
'injected_files': injected_files,
|
'injected_files': injected_files,
|
||||||
@ -442,8 +443,16 @@ class ComputeTaskAPI(object):
|
|||||||
'preserve_ephemeral': preserve_ephemeral,
|
'preserve_ephemeral': preserve_ephemeral,
|
||||||
'host': host,
|
'host': host,
|
||||||
'request_spec': request_spec,
|
'request_spec': request_spec,
|
||||||
'reimage_boot_volume': reimage_boot_volume
|
'reimage_boot_volume': reimage_boot_volume,
|
||||||
|
'target_state': target_state,
|
||||||
}
|
}
|
||||||
|
if not self.client.can_send_version(version):
|
||||||
|
if kw['target_state']:
|
||||||
|
raise exception.UnsupportedRPCVersion(
|
||||||
|
api="rebuild_instance", required="1.25")
|
||||||
|
else:
|
||||||
|
del kw['target_state']
|
||||||
|
version = '1.24'
|
||||||
if not self.client.can_send_version(version):
|
if not self.client.can_send_version(version):
|
||||||
if kw['reimage_boot_volume']:
|
if kw['reimage_boot_volume']:
|
||||||
raise exception.NovaException(
|
raise exception.NovaException(
|
||||||
|
@ -1451,6 +1451,11 @@ class InstanceEvacuateNotSupported(Invalid):
|
|||||||
msg_fmt = _('Instance evacuate is not supported.')
|
msg_fmt = _('Instance evacuate is not supported.')
|
||||||
|
|
||||||
|
|
||||||
|
class InstanceEvacuateNotSupportedTargetState(Invalid):
|
||||||
|
msg_fmt = _("Target state '%(target_state)s' for instance evacuate "
|
||||||
|
"is not supported.")
|
||||||
|
|
||||||
|
|
||||||
class DBNotAllowed(NovaException):
|
class DBNotAllowed(NovaException):
|
||||||
msg_fmt = _('%(binary)s attempted direct database access which is '
|
msg_fmt = _('%(binary)s attempted direct database access which is '
|
||||||
'not allowed by policy')
|
'not allowed by policy')
|
||||||
@ -1479,6 +1484,11 @@ class UnsupportedRescueImage(Invalid):
|
|||||||
msg_fmt = _("Requested rescue image '%(image)s' is not supported")
|
msg_fmt = _("Requested rescue image '%(image)s' is not supported")
|
||||||
|
|
||||||
|
|
||||||
|
class UnsupportedRPCVersion(Invalid):
|
||||||
|
msg_fmt = _("Unsupported RPC version for %(api)s. "
|
||||||
|
"Required >= %(required)s")
|
||||||
|
|
||||||
|
|
||||||
class Base64Exception(NovaException):
|
class Base64Exception(NovaException):
|
||||||
msg_fmt = _("Invalid Base 64 data for file %(path)s")
|
msg_fmt = _("Invalid Base 64 data for file %(path)s")
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
# NOTE(danms): This is the global service version counter
|
# NOTE(danms): This is the global service version counter
|
||||||
SERVICE_VERSION = 65
|
SERVICE_VERSION = 66
|
||||||
|
|
||||||
|
|
||||||
# NOTE(danms): This is our SERVICE_VERSION history. The idea is that any
|
# NOTE(danms): This is our SERVICE_VERSION history. The idea is that any
|
||||||
@ -228,6 +228,9 @@ SERVICE_VERSION_HISTORY = (
|
|||||||
# Version 65: Compute RPC v6.1:
|
# Version 65: Compute RPC v6.1:
|
||||||
# Added stable local node identity
|
# Added stable local node identity
|
||||||
{'compute_rpc': '6.1'},
|
{'compute_rpc': '6.1'},
|
||||||
|
# Version 66: Compute RPC v6.2:
|
||||||
|
# Add target_state parameter to rebuild_instance()
|
||||||
|
{'compute_rpc': '6.2'},
|
||||||
)
|
)
|
||||||
|
|
||||||
# This is the version after which we can rely on having a persistent
|
# This is the version after which we can rely on having a persistent
|
||||||
|
@ -80,7 +80,7 @@ class EvacuateJsonTest(test_servers.ServersSampleBase):
|
|||||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
||||||
on_shared_storage=False, preserve_ephemeral=mock.ANY,
|
on_shared_storage=False, preserve_ephemeral=mock.ANY,
|
||||||
host='testHost', request_spec=mock.ANY,
|
host='testHost', request_spec=mock.ANY,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
||||||
def test_server_evacuate_find_host(self, rebuild_mock):
|
def test_server_evacuate_find_host(self, rebuild_mock):
|
||||||
@ -97,7 +97,7 @@ class EvacuateJsonTest(test_servers.ServersSampleBase):
|
|||||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
||||||
on_shared_storage=False, preserve_ephemeral=mock.ANY,
|
on_shared_storage=False, preserve_ephemeral=mock.ANY,
|
||||||
host=None, request_spec=mock.ANY,
|
host=None, request_spec=mock.ANY,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
|
|
||||||
class EvacuateJsonTestV214(EvacuateJsonTest):
|
class EvacuateJsonTestV214(EvacuateJsonTest):
|
||||||
@ -119,7 +119,7 @@ class EvacuateJsonTestV214(EvacuateJsonTest):
|
|||||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
||||||
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
||||||
host='testHost', request_spec=mock.ANY,
|
host='testHost', request_spec=mock.ANY,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
||||||
def test_server_evacuate_find_host(self, rebuild_mock):
|
def test_server_evacuate_find_host(self, rebuild_mock):
|
||||||
@ -135,7 +135,7 @@ class EvacuateJsonTestV214(EvacuateJsonTest):
|
|||||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
||||||
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
||||||
host=None, request_spec=mock.ANY,
|
host=None, request_spec=mock.ANY,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
|
|
||||||
class EvacuateJsonTestV229(EvacuateJsonTestV214):
|
class EvacuateJsonTestV229(EvacuateJsonTestV214):
|
||||||
@ -163,7 +163,7 @@ class EvacuateJsonTestV229(EvacuateJsonTestV214):
|
|||||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
||||||
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
||||||
host=None, request_spec=mock.ANY,
|
host=None, request_spec=mock.ANY,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
||||||
@mock.patch('nova.objects.ComputeNodeList.get_all_by_host')
|
@mock.patch('nova.objects.ComputeNodeList.get_all_by_host')
|
||||||
@ -184,7 +184,7 @@ class EvacuateJsonTestV229(EvacuateJsonTestV214):
|
|||||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
||||||
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
||||||
host='testHost', request_spec=mock.ANY,
|
host='testHost', request_spec=mock.ANY,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
|
|
||||||
class EvacuateJsonTestV268(EvacuateJsonTestV229):
|
class EvacuateJsonTestV268(EvacuateJsonTestV229):
|
||||||
@ -211,7 +211,7 @@ class EvacuateJsonTestV268(EvacuateJsonTestV229):
|
|||||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=mock.ANY,
|
||||||
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
on_shared_storage=None, preserve_ephemeral=mock.ANY,
|
||||||
host=None, request_spec=mock.ANY,
|
host=None, request_spec=mock.ANY,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
def test_server_evacuate_with_force(self):
|
def test_server_evacuate_with_force(self):
|
||||||
# doesn't apply to v2.68+, which removed the ability to force migrate
|
# doesn't apply to v2.68+, which removed the ability to force migrate
|
||||||
|
@ -4081,7 +4081,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
injected_files=[], bdms=bdms,
|
injected_files=[], bdms=bdms,
|
||||||
preserve_ephemeral=False, host=None,
|
preserve_ephemeral=False, host=None,
|
||||||
request_spec=fake_spec,
|
request_spec=fake_spec,
|
||||||
reimage_boot_volume=True)
|
reimage_boot_volume=True,
|
||||||
|
target_state=None)
|
||||||
_check_auto_disk_config.assert_called_once_with(
|
_check_auto_disk_config.assert_called_once_with(
|
||||||
image=image, auto_disk_config=None)
|
image=image, auto_disk_config=None)
|
||||||
_checks_for_create_and_rebuild.assert_called_once_with(
|
_checks_for_create_and_rebuild.assert_called_once_with(
|
||||||
@ -4096,7 +4097,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
instance,
|
instance,
|
||||||
uuids.image_ref,
|
uuids.image_ref,
|
||||||
admin_pass,
|
admin_pass,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
|
|
||||||
@mock.patch.object(objects.RequestSpec, 'save')
|
@mock.patch.object(objects.RequestSpec, 'save')
|
||||||
@mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid')
|
@mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid')
|
||||||
@ -4155,7 +4157,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
instance,
|
instance,
|
||||||
uuids.image_ref,
|
uuids.image_ref,
|
||||||
admin_pass,
|
admin_pass,
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
|
|
||||||
@mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid')
|
@mock.patch.object(objects.RequestSpec, 'get_by_instance_uuid')
|
||||||
@mock.patch.object(objects.Instance, 'save')
|
@mock.patch.object(objects.Instance, 'save')
|
||||||
@ -4205,7 +4208,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
orig_image_ref=uuids.image_ref,
|
orig_image_ref=uuids.image_ref,
|
||||||
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
||||||
preserve_ephemeral=False, host=instance.host,
|
preserve_ephemeral=False, host=instance.host,
|
||||||
request_spec=fake_spec, reimage_boot_volume=False)
|
request_spec=fake_spec, reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
|
|
||||||
_check_auto_disk_config.assert_called_once_with(
|
_check_auto_disk_config.assert_called_once_with(
|
||||||
image=image, auto_disk_config=None)
|
image=image, auto_disk_config=None)
|
||||||
@ -4278,7 +4282,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
orig_image_ref=uuids.image_ref,
|
orig_image_ref=uuids.image_ref,
|
||||||
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
||||||
preserve_ephemeral=False, host=None,
|
preserve_ephemeral=False, host=None,
|
||||||
request_spec=fake_spec, reimage_boot_volume=False)
|
request_spec=fake_spec, reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
# assert the request spec was modified so the scheduler picks
|
# assert the request spec was modified so the scheduler picks
|
||||||
# the existing instance host/node
|
# the existing instance host/node
|
||||||
req_spec_save.assert_called_once_with()
|
req_spec_save.assert_called_once_with()
|
||||||
@ -4346,7 +4351,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
orig_image_ref=uuids.image_ref,
|
orig_image_ref=uuids.image_ref,
|
||||||
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
||||||
preserve_ephemeral=False, host=instance.host,
|
preserve_ephemeral=False, host=instance.host,
|
||||||
request_spec=fake_spec, reimage_boot_volume=False)
|
request_spec=fake_spec, reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
|
|
||||||
_check_auto_disk_config.assert_called_once_with(
|
_check_auto_disk_config.assert_called_once_with(
|
||||||
image=image, auto_disk_config=None)
|
image=image, auto_disk_config=None)
|
||||||
@ -4405,7 +4411,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
orig_image_ref=uuids.image_ref,
|
orig_image_ref=uuids.image_ref,
|
||||||
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
||||||
preserve_ephemeral=False, host=instance.host,
|
preserve_ephemeral=False, host=instance.host,
|
||||||
request_spec=fake_spec, reimage_boot_volume=False)
|
request_spec=fake_spec, reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
|
|
||||||
_check_auto_disk_config.assert_called_once_with(
|
_check_auto_disk_config.assert_called_once_with(
|
||||||
image=image, auto_disk_config=None)
|
image=image, auto_disk_config=None)
|
||||||
@ -4469,7 +4476,8 @@ class _ComputeAPIUnitTestMixIn(object):
|
|||||||
orig_image_ref=uuids.image_ref,
|
orig_image_ref=uuids.image_ref,
|
||||||
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
orig_sys_metadata=orig_system_metadata, bdms=bdms,
|
||||||
preserve_ephemeral=False, host=instance.host,
|
preserve_ephemeral=False, host=instance.host,
|
||||||
request_spec=fake_spec, reimage_boot_volume=False)
|
request_spec=fake_spec, reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
|
|
||||||
_check_auto_disk_config.assert_called_once_with(
|
_check_auto_disk_config.assert_called_once_with(
|
||||||
image=image, auto_disk_config=None)
|
image=image, auto_disk_config=None)
|
||||||
|
@ -2731,7 +2731,7 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
bdms=[], recreate=False, on_shared_storage=False,
|
bdms=[], recreate=False, on_shared_storage=False,
|
||||||
preserve_ephemeral=False, migration=None, scheduled_node=None,
|
preserve_ephemeral=False, migration=None, scheduled_node=None,
|
||||||
limits={}, request_spec=None, accel_uuids=[],
|
limits={}, request_spec=None, accel_uuids=[],
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
self.compute.terminate_instance(self.context, instance, [])
|
||||||
|
|
||||||
def test_rebuild_driver(self):
|
def test_rebuild_driver(self):
|
||||||
@ -2762,7 +2762,7 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
bdms=[], recreate=False, on_shared_storage=False,
|
bdms=[], recreate=False, on_shared_storage=False,
|
||||||
preserve_ephemeral=False, migration=None, scheduled_node=None,
|
preserve_ephemeral=False, migration=None, scheduled_node=None,
|
||||||
limits={}, request_spec=None, accel_uuids=[],
|
limits={}, request_spec=None, accel_uuids=[],
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
self.assertTrue(called['rebuild'])
|
self.assertTrue(called['rebuild'])
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
self.compute.terminate_instance(self.context, instance, [])
|
||||||
|
|
||||||
@ -2815,7 +2815,7 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
bdms=bdms, recreate=False, preserve_ephemeral=False,
|
bdms=bdms, recreate=False, preserve_ephemeral=False,
|
||||||
migration=None, scheduled_node=None, limits={},
|
migration=None, scheduled_node=None, limits={},
|
||||||
on_shared_storage=False, request_spec=None, accel_uuids=[],
|
on_shared_storage=False, request_spec=None, accel_uuids=[],
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
self.assertTrue(called['rebuild'])
|
self.assertTrue(called['rebuild'])
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
self.compute.terminate_instance(self.context, instance, [])
|
||||||
|
|
||||||
@ -2834,7 +2834,8 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
new_pass="new_password", orig_sys_metadata=sys_metadata, bdms=[],
|
new_pass="new_password", orig_sys_metadata=sys_metadata, bdms=[],
|
||||||
recreate=False, on_shared_storage=False, preserve_ephemeral=False,
|
recreate=False, on_shared_storage=False, preserve_ephemeral=False,
|
||||||
migration=None, scheduled_node=None, limits=None,
|
migration=None, scheduled_node=None, limits=None,
|
||||||
request_spec=None, accel_uuids=[], reimage_boot_volume=False)
|
request_spec=None, accel_uuids=[], reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
self.compute.terminate_instance(self.context, instance, [])
|
||||||
|
|
||||||
def test_rebuild_launched_at_time(self):
|
def test_rebuild_launched_at_time(self):
|
||||||
@ -2855,7 +2856,7 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
new_pass="new_password", orig_sys_metadata={}, bdms=[],
|
new_pass="new_password", orig_sys_metadata={}, bdms=[],
|
||||||
recreate=False, on_shared_storage=False, preserve_ephemeral=False,
|
recreate=False, on_shared_storage=False, preserve_ephemeral=False,
|
||||||
migration=None, scheduled_node=None, limits={}, request_spec=None,
|
migration=None, scheduled_node=None, limits={}, request_spec=None,
|
||||||
accel_uuids=[], reimage_boot_volume=False)
|
accel_uuids=[], reimage_boot_volume=False, target_state=None)
|
||||||
instance.refresh()
|
instance.refresh()
|
||||||
self.assertEqual(cur_time,
|
self.assertEqual(cur_time,
|
||||||
instance['launched_at'].replace(tzinfo=None))
|
instance['launched_at'].replace(tzinfo=None))
|
||||||
@ -2889,7 +2890,7 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
orig_sys_metadata=sys_metadata, bdms=[], recreate=False,
|
orig_sys_metadata=sys_metadata, bdms=[], recreate=False,
|
||||||
on_shared_storage=False, preserve_ephemeral=False, migration=None,
|
on_shared_storage=False, preserve_ephemeral=False, migration=None,
|
||||||
scheduled_node=None, limits={}, request_spec=None, accel_uuids=[],
|
scheduled_node=None, limits={}, request_spec=None, accel_uuids=[],
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
self.compute.terminate_instance(self.context, instance, [])
|
self.compute.terminate_instance(self.context, instance, [])
|
||||||
|
|
||||||
@mock.patch.object(objects.BlockDeviceMappingList, 'get_by_instance_uuid')
|
@mock.patch.object(objects.BlockDeviceMappingList, 'get_by_instance_uuid')
|
||||||
@ -4617,7 +4618,8 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
'request_spec': None,
|
'request_spec': None,
|
||||||
'on_shared_storage': False,
|
'on_shared_storage': False,
|
||||||
'accel_uuids': (),
|
'accel_uuids': (),
|
||||||
'reimage_boot_volume': False}),
|
'reimage_boot_volume': False,
|
||||||
|
'target_state': None}),
|
||||||
("set_admin_password", task_states.UPDATING_PASSWORD,
|
("set_admin_password", task_states.UPDATING_PASSWORD,
|
||||||
{'new_pass': None}),
|
{'new_pass': None}),
|
||||||
("rescue_instance", task_states.RESCUING,
|
("rescue_instance", task_states.RESCUING,
|
||||||
@ -5136,7 +5138,7 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
orig_sys_metadata=orig_sys_metadata, bdms=[], recreate=False,
|
orig_sys_metadata=orig_sys_metadata, bdms=[], recreate=False,
|
||||||
on_shared_storage=False, preserve_ephemeral=False, migration=None,
|
on_shared_storage=False, preserve_ephemeral=False, migration=None,
|
||||||
scheduled_node=None, limits={}, request_spec=None, accel_uuids=[],
|
scheduled_node=None, limits={}, request_spec=None, accel_uuids=[],
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
inst_ref.refresh()
|
inst_ref.refresh()
|
||||||
|
|
||||||
@ -11961,7 +11963,7 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
force=False)
|
force=False)
|
||||||
|
|
||||||
@mock.patch('nova.compute.utils.notify_about_instance_action')
|
@mock.patch('nova.compute.utils.notify_about_instance_action')
|
||||||
def _test_evacuate(self, mock_notify, force=None):
|
def _test_evacuate(self, mock_notify, force=None, target_state=None):
|
||||||
instance = self._create_fake_instance_obj(services=True)
|
instance = self._create_fake_instance_obj(services=True)
|
||||||
self.assertIsNone(instance.task_state)
|
self.assertIsNone(instance.task_state)
|
||||||
|
|
||||||
@ -11998,7 +12000,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
host='fake_dest_host',
|
host='fake_dest_host',
|
||||||
on_shared_storage=True,
|
on_shared_storage=True,
|
||||||
admin_password=None,
|
admin_password=None,
|
||||||
force=force)
|
force=force,
|
||||||
|
target_state=target_state)
|
||||||
if force is False:
|
if force is False:
|
||||||
host = None
|
host = None
|
||||||
else:
|
else:
|
||||||
@ -12015,7 +12018,8 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
recreate=True,
|
recreate=True,
|
||||||
on_shared_storage=True,
|
on_shared_storage=True,
|
||||||
request_spec=fake_spec,
|
request_spec=fake_spec,
|
||||||
host=host)
|
host=host,
|
||||||
|
target_state=target_state)
|
||||||
do_test()
|
do_test()
|
||||||
|
|
||||||
instance.refresh()
|
instance.refresh()
|
||||||
@ -12047,6 +12051,9 @@ class ComputeAPITestCase(BaseTestCase):
|
|||||||
def test_evacuate_with_forced_host(self):
|
def test_evacuate_with_forced_host(self):
|
||||||
self._test_evacuate(force=True)
|
self._test_evacuate(force=True)
|
||||||
|
|
||||||
|
def test_evacuate_with_target_state(self):
|
||||||
|
self._test_evacuate(target_state="stopped")
|
||||||
|
|
||||||
@mock.patch('nova.servicegroup.api.API.service_is_up',
|
@mock.patch('nova.servicegroup.api.API.service_is_up',
|
||||||
return_value=False)
|
return_value=False)
|
||||||
def test_fail_evacuate_with_non_existing_destination(self, _service_is_up):
|
def test_fail_evacuate_with_non_existing_destination(self, _service_is_up):
|
||||||
@ -13540,7 +13547,8 @@ class EvacuateHostTestCase(BaseTestCase):
|
|||||||
image_ref, injected_files, 'newpass', {}, bdms, recreate=True,
|
image_ref, injected_files, 'newpass', {}, bdms, recreate=True,
|
||||||
on_shared_storage=on_shared_storage, migration=migration,
|
on_shared_storage=on_shared_storage, migration=migration,
|
||||||
preserve_ephemeral=False, scheduled_node=node, limits=limits,
|
preserve_ephemeral=False, scheduled_node=node, limits=limits,
|
||||||
request_spec=None, accel_uuids=[], reimage_boot_volume=False)
|
request_spec=None, accel_uuids=[], reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
if vm_states_is_stopped:
|
if vm_states_is_stopped:
|
||||||
mock_notify_rebuild.assert_has_calls([
|
mock_notify_rebuild.assert_has_calls([
|
||||||
mock.call(ctxt, self.inst, self.inst.host, phase='start',
|
mock.call(ctxt, self.inst, self.inst.host, phase='start',
|
||||||
|
@ -5347,7 +5347,8 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
|
|
||||||
self.compute.rebuild_instance(
|
self.compute.rebuild_instance(
|
||||||
self.context, instance, None, None, None, None, None, None,
|
self.context, instance, None, None, None, None, None, None,
|
||||||
recreate, False, False, None, scheduled_node, {}, None, [], False)
|
recreate, False, False, None, scheduled_node, {}, None, [], False,
|
||||||
|
None)
|
||||||
mock_set.assert_called_once_with(None, 'failed')
|
mock_set.assert_called_once_with(None, 'failed')
|
||||||
mock_notify_about_instance_usage.assert_called_once_with(
|
mock_notify_about_instance_usage.assert_called_once_with(
|
||||||
mock.ANY, instance, 'rebuild.error', fault=mock_rebuild.side_effect
|
mock.ANY, instance, 'rebuild.error', fault=mock_rebuild.side_effect
|
||||||
@ -5459,7 +5460,8 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
preserve_ephemeral=False, migration=None,
|
preserve_ephemeral=False, migration=None,
|
||||||
scheduled_node='fake-node',
|
scheduled_node='fake-node',
|
||||||
limits={}, request_spec=request_spec, accel_uuids=[],
|
limits={}, request_spec=request_spec, accel_uuids=[],
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False,
|
||||||
|
target_state=None)
|
||||||
|
|
||||||
mock_validate_policy.assert_called_once_with(
|
mock_validate_policy.assert_called_once_with(
|
||||||
elevated_context, instance, {'group': [uuids.group]})
|
elevated_context, instance, {'group': [uuids.group]})
|
||||||
@ -5499,7 +5501,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
recreate=True, on_shared_storage=None, preserve_ephemeral=False,
|
recreate=True, on_shared_storage=None, preserve_ephemeral=False,
|
||||||
migration=None, scheduled_node='fake-node', limits={},
|
migration=None, scheduled_node='fake-node', limits={},
|
||||||
request_spec=request_spec, accel_uuids=[],
|
request_spec=request_spec, accel_uuids=[],
|
||||||
reimage_boot_volume=False)
|
reimage_boot_volume=False, target_state=None)
|
||||||
|
|
||||||
mock_validate_policy.assert_called_once_with(
|
mock_validate_policy.assert_called_once_with(
|
||||||
elevated_context, instance, {'group': [uuids.group]})
|
elevated_context, instance, {'group': [uuids.group]})
|
||||||
@ -5525,7 +5527,8 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
self.compute.rebuild_instance(
|
self.compute.rebuild_instance(
|
||||||
self.context, instance, None, None,
|
self.context, instance, None, None,
|
||||||
None, None, None, None, False,
|
None, None, None, None, False,
|
||||||
False, False, migration, None, {}, None, [], False)
|
False, False, migration, None, {}, None, [], False,
|
||||||
|
None)
|
||||||
self.assertFalse(mock_get.called)
|
self.assertFalse(mock_get.called)
|
||||||
self.assertEqual(node, instance.node)
|
self.assertEqual(node, instance.node)
|
||||||
self.assertEqual('done', migration.status)
|
self.assertEqual('done', migration.status)
|
||||||
@ -5547,7 +5550,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
self.compute.rebuild_instance(
|
self.compute.rebuild_instance(
|
||||||
self.context, instance, None, None, None, None, None,
|
self.context, instance, None, None, None, None, None,
|
||||||
None, True, False, False, mock.sentinel.migration, None, {},
|
None, True, False, False, mock.sentinel.migration, None, {},
|
||||||
None, [], False)
|
None, [], False, None)
|
||||||
mock_get.assert_called_once_with(mock.ANY, self.compute.host)
|
mock_get.assert_called_once_with(mock.ANY, self.compute.host)
|
||||||
mock_rt.finish_evacuation.assert_called_once_with(
|
mock_rt.finish_evacuation.assert_called_once_with(
|
||||||
instance, 'new-node', mock.sentinel.migration)
|
instance, 'new-node', mock.sentinel.migration)
|
||||||
@ -5630,7 +5633,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
preserve_ephemeral, {}, {},
|
preserve_ephemeral, {}, {},
|
||||||
self.allocations,
|
self.allocations,
|
||||||
mock.sentinel.mapping, [],
|
mock.sentinel.mapping, [],
|
||||||
False)
|
False, None)
|
||||||
|
|
||||||
mock_notify_usage.assert_has_calls(
|
mock_notify_usage.assert_has_calls(
|
||||||
[mock.call(self.context, instance, "rebuild.start",
|
[mock.call(self.context, instance, "rebuild.start",
|
||||||
@ -5889,7 +5892,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase,
|
|||||||
request_spec=objects.RequestSpec(),
|
request_spec=objects.RequestSpec(),
|
||||||
allocations=self.allocations,
|
allocations=self.allocations,
|
||||||
request_group_resource_providers_mapping=mock.sentinel.mapping,
|
request_group_resource_providers_mapping=mock.sentinel.mapping,
|
||||||
accel_uuids=[], reimage_boot_volume=False)
|
accel_uuids=[], reimage_boot_volume=False, target_state=None)
|
||||||
self.assertIn('Trusted image certificates provided on host', str(ex))
|
self.assertIn('Trusted image certificates provided on host', str(ex))
|
||||||
|
|
||||||
def test_reverts_task_state_instance_not_found(self):
|
def test_reverts_task_state_instance_not_found(self):
|
||||||
|
@ -836,7 +836,8 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
|||||||
orig_sys_metadata=None, recreate=True, on_shared_storage=True,
|
orig_sys_metadata=None, recreate=True, on_shared_storage=True,
|
||||||
preserve_ephemeral=True, migration=None, node=None,
|
preserve_ephemeral=True, migration=None, node=None,
|
||||||
limits=None, request_spec=None, accel_uuids=[],
|
limits=None, request_spec=None, accel_uuids=[],
|
||||||
reimage_boot_volume=False, version='6.1')
|
reimage_boot_volume=False, target_state=None,
|
||||||
|
version='6.2')
|
||||||
|
|
||||||
def test_rebuild_instance_old_rpcapi(self):
|
def test_rebuild_instance_old_rpcapi(self):
|
||||||
# With rpcapi < 5.12, accel_uuids must be dropped in the client call.
|
# With rpcapi < 5.12, accel_uuids must be dropped in the client call.
|
||||||
@ -868,9 +869,11 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
|||||||
ctxt, instance=self.fake_instance_obj,
|
ctxt, instance=self.fake_instance_obj,
|
||||||
accel_uuids=['938af7f9-f136-4e5a-bdbe-3b6feab54311'],
|
accel_uuids=['938af7f9-f136-4e5a-bdbe-3b6feab54311'],
|
||||||
node=None, host=None, reimage_boot_volume=False,
|
node=None, host=None, reimage_boot_volume=False,
|
||||||
**rebuild_args)
|
target_state=None, **rebuild_args)
|
||||||
|
|
||||||
mock_client.can_send_version.assert_has_calls([mock.call('6.0'),
|
mock_client.can_send_version.assert_has_calls([mock.call('6.2'),
|
||||||
|
mock.call('6.1'),
|
||||||
|
mock.call('6.0'),
|
||||||
mock.call('5.12')])
|
mock.call('5.12')])
|
||||||
mock_client.prepare.assert_called_with(
|
mock_client.prepare.assert_called_with(
|
||||||
server=self.fake_instance_obj.host, version='5.0')
|
server=self.fake_instance_obj.host, version='5.0')
|
||||||
@ -890,7 +893,7 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
|||||||
compute_api.router.client.return_value = mock_client
|
compute_api.router.client.return_value = mock_client
|
||||||
# Force can_send_version to [False, True, True], so that 6.0
|
# Force can_send_version to [False, True, True], so that 6.0
|
||||||
# version is used.
|
# version is used.
|
||||||
mock_client.can_send_version.side_effect = [False, True, True]
|
mock_client.can_send_version.side_effect = [False, False, True, True]
|
||||||
mock_cctx = mock.MagicMock()
|
mock_cctx = mock.MagicMock()
|
||||||
mock_client.prepare.return_value = mock_cctx
|
mock_client.prepare.return_value = mock_cctx
|
||||||
rebuild_args = {
|
rebuild_args = {
|
||||||
@ -908,12 +911,47 @@ class ComputeRpcAPITestCase(test.NoDBTestCase):
|
|||||||
'limits': None,
|
'limits': None,
|
||||||
'accel_uuids': [],
|
'accel_uuids': [],
|
||||||
'reimage_boot_volume': True,
|
'reimage_boot_volume': True,
|
||||||
|
'target_state': None,
|
||||||
}
|
}
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
exception.NovaException, compute_api.rebuild_instance,
|
exception.NovaException, compute_api.rebuild_instance,
|
||||||
ctxt, instance=self.fake_instance_obj,
|
ctxt, instance=self.fake_instance_obj,
|
||||||
node=None, host=None, **rebuild_args)
|
node=None, host=None, **rebuild_args)
|
||||||
mock_client.can_send_version.assert_has_calls([mock.call('6.1')])
|
mock_client.can_send_version.assert_has_calls([mock.call('6.2')])
|
||||||
|
|
||||||
|
def test_rebuild_instance_evacuate_old_rpcapi(self):
|
||||||
|
# With rpcapi < 6.2, if evacuate we should raise error.
|
||||||
|
ctxt = context.RequestContext('fake_user', 'fake_project')
|
||||||
|
compute_api = compute_rpcapi.ComputeAPI()
|
||||||
|
compute_api.router.client = mock.Mock()
|
||||||
|
mock_client = mock.MagicMock()
|
||||||
|
compute_api.router.client.return_value = mock_client
|
||||||
|
# Force can_send_version to return False.
|
||||||
|
mock_client.can_send_version.return_value = False
|
||||||
|
mock_cctx = mock.MagicMock()
|
||||||
|
mock_client.prepare.return_value = mock_cctx
|
||||||
|
rebuild_args = {
|
||||||
|
'new_pass': 'admin_password',
|
||||||
|
'injected_files': 'files_to_inject',
|
||||||
|
'image_ref': uuids.image_ref,
|
||||||
|
'orig_image_ref': uuids.orig_image_ref,
|
||||||
|
'orig_sys_metadata': 'orig_sys_meta',
|
||||||
|
'bdms': {},
|
||||||
|
'recreate': False,
|
||||||
|
'on_shared_storage': False,
|
||||||
|
'preserve_ephemeral': False,
|
||||||
|
'request_spec': None,
|
||||||
|
'migration': None,
|
||||||
|
'limits': None,
|
||||||
|
'accel_uuids': [],
|
||||||
|
'reimage_boot_volume': True,
|
||||||
|
'target_state': 'stopped',
|
||||||
|
}
|
||||||
|
self.assertRaises(
|
||||||
|
exception.UnsupportedRPCVersion,
|
||||||
|
compute_api.rebuild_instance,
|
||||||
|
ctxt, instance=self.fake_instance_obj,
|
||||||
|
node=None, host=None, **rebuild_args)
|
||||||
|
|
||||||
def test_reserve_block_device_name(self):
|
def test_reserve_block_device_name(self):
|
||||||
self.flags(long_rpc_timeout=1234)
|
self.flags(long_rpc_timeout=1234)
|
||||||
|
@ -389,7 +389,8 @@ class _BaseTaskTestCase(object):
|
|||||||
'preserve_ephemeral': False,
|
'preserve_ephemeral': False,
|
||||||
'host': 'compute-host',
|
'host': 'compute-host',
|
||||||
'request_spec': None,
|
'request_spec': None,
|
||||||
'reimage_boot_volume': False}
|
'reimage_boot_volume': False,
|
||||||
|
'target_state': None}
|
||||||
if update_args:
|
if update_args:
|
||||||
rebuild_args.update(update_args)
|
rebuild_args.update(update_args)
|
||||||
compute_rebuild_args = copy.deepcopy(rebuild_args)
|
compute_rebuild_args = copy.deepcopy(rebuild_args)
|
||||||
@ -4751,9 +4752,34 @@ class ConductorTaskRPCAPITestCase(_BaseTaskTestCase,
|
|||||||
mock.sentinel.migration)
|
mock.sentinel.migration)
|
||||||
can_send_version.assert_called_once_with('1.23')
|
can_send_version.assert_called_once_with('1.23')
|
||||||
|
|
||||||
|
def test_evacuate_old_rpc_with_target_state(self):
|
||||||
|
inst_obj = self._create_fake_instance_obj()
|
||||||
|
rebuild_args, compute_args = self._prepare_rebuild_args(
|
||||||
|
{'host': inst_obj.host,
|
||||||
|
'target_state': 'stopped'})
|
||||||
|
with mock.patch.object(
|
||||||
|
self.conductor.client, 'can_send_version', return_value=False):
|
||||||
|
self.assertRaises(exc.UnsupportedRPCVersion,
|
||||||
|
self.conductor.rebuild_instance,
|
||||||
|
self.context, inst_obj, **rebuild_args)
|
||||||
|
|
||||||
|
def test_evacuate_old_rpc_without_target_state(self):
|
||||||
|
inst_obj = self._create_fake_instance_obj()
|
||||||
|
rebuild_args, compute_args = self._prepare_rebuild_args(
|
||||||
|
{'host': inst_obj.host,
|
||||||
|
'target_state': None})
|
||||||
|
with mock.patch.object(
|
||||||
|
self.conductor.client, 'can_send_version',
|
||||||
|
return_value=False) as can_send_version:
|
||||||
|
self.conductor.rebuild_instance(
|
||||||
|
self.context, inst_obj, **rebuild_args)
|
||||||
|
can_send_version.assert_has_calls([
|
||||||
|
mock.call('1.25'), mock.call('1.24'),
|
||||||
|
mock.call('1.12')])
|
||||||
|
|
||||||
def test_rebuild_instance_volume_backed(self):
|
def test_rebuild_instance_volume_backed(self):
|
||||||
inst_obj = self._create_fake_instance_obj()
|
inst_obj = self._create_fake_instance_obj()
|
||||||
version = '1.24'
|
version = '1.25'
|
||||||
cctxt_mock = mock.MagicMock()
|
cctxt_mock = mock.MagicMock()
|
||||||
rebuild_args, compute_args = self._prepare_rebuild_args(
|
rebuild_args, compute_args = self._prepare_rebuild_args(
|
||||||
{'host': inst_obj.host})
|
{'host': inst_obj.host})
|
||||||
@ -4785,7 +4811,8 @@ class ConductorTaskRPCAPITestCase(_BaseTaskTestCase,
|
|||||||
self.conductor.rebuild_instance,
|
self.conductor.rebuild_instance,
|
||||||
self.context, inst_obj,
|
self.context, inst_obj,
|
||||||
**rebuild_args)
|
**rebuild_args)
|
||||||
can_send_version.assert_called_once_with('1.24')
|
can_send_version.assert_has_calls([mock.call('1.25'),
|
||||||
|
mock.call('1.24')])
|
||||||
|
|
||||||
|
|
||||||
class ConductorTaskAPITestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
|
class ConductorTaskAPITestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
|
||||||
|
Loading…
Reference in New Issue
Block a user