Add conductor RPC interface for rebuild
This patch adds support for passing the ``reimage_boot_volume`` flag from the API layer through the conductor layer to the computer layer and also includes RPC bump as necessary. Related blueprint volume-backed-server-rebuild Change-Id: I8daf177eb67d08112a16fe788910644abf338fa6
This commit is contained in:
parent
30aab9c234
commit
6919db5612
|
@ -144,7 +144,7 @@ class ComputeTaskAPI(object):
|
|||
injected_files, new_pass, orig_sys_metadata,
|
||||
bdms, recreate=False, on_shared_storage=False,
|
||||
preserve_ephemeral=False, host=None,
|
||||
request_spec=None):
|
||||
request_spec=None, reimage_boot_volume=False):
|
||||
self.conductor_compute_rpcapi.rebuild_instance(context,
|
||||
instance=instance,
|
||||
new_pass=new_pass,
|
||||
|
@ -157,7 +157,8 @@ class ComputeTaskAPI(object):
|
|||
on_shared_storage=on_shared_storage,
|
||||
preserve_ephemeral=preserve_ephemeral,
|
||||
host=host,
|
||||
request_spec=request_spec)
|
||||
request_spec=request_spec,
|
||||
reimage_boot_volume=reimage_boot_volume)
|
||||
|
||||
def cache_images(self, context, aggregate, image_ids):
|
||||
"""Request images be pre-cached on hosts within an aggregate.
|
||||
|
|
|
@ -235,7 +235,7 @@ class ComputeTaskManager:
|
|||
may involve coordinating activities on multiple compute nodes.
|
||||
"""
|
||||
|
||||
target = messaging.Target(namespace='compute_task', version='1.23')
|
||||
target = messaging.Target(namespace='compute_task', version='1.24')
|
||||
|
||||
def __init__(self):
|
||||
self.compute_rpcapi = compute_rpcapi.ComputeAPI()
|
||||
|
@ -1344,7 +1344,7 @@ class ComputeTaskManager:
|
|||
limits=limits,
|
||||
request_spec=request_spec,
|
||||
accel_uuids=accel_uuids,
|
||||
reimage_boot_volume=False)
|
||||
reimage_boot_volume=reimage_boot_volume)
|
||||
|
||||
def _validate_image_traits_for_rebuild(self, context, instance, image_ref):
|
||||
"""Validates that the traits specified in the image can be satisfied
|
||||
|
|
|
@ -286,6 +286,7 @@ class ComputeTaskAPI(object):
|
|||
1.21 - Added cache_images()
|
||||
1.22 - Added confirm_snapshot_based_resize()
|
||||
1.23 - Added revert_snapshot_based_resize()
|
||||
1.24 - Add reimage_boot_volume parameter to rebuild_instance()
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
|
@ -426,8 +427,9 @@ class ComputeTaskAPI(object):
|
|||
def rebuild_instance(self, ctxt, instance, new_pass, injected_files,
|
||||
image_ref, orig_image_ref, orig_sys_metadata, bdms,
|
||||
recreate=False, on_shared_storage=False, host=None,
|
||||
preserve_ephemeral=False, request_spec=None):
|
||||
version = '1.12'
|
||||
preserve_ephemeral=False, request_spec=None,
|
||||
reimage_boot_volume=False):
|
||||
version = '1.24'
|
||||
kw = {'instance': instance,
|
||||
'new_pass': new_pass,
|
||||
'injected_files': injected_files,
|
||||
|
@ -440,7 +442,16 @@ class ComputeTaskAPI(object):
|
|||
'preserve_ephemeral': preserve_ephemeral,
|
||||
'host': host,
|
||||
'request_spec': request_spec,
|
||||
'reimage_boot_volume': reimage_boot_volume
|
||||
}
|
||||
if not self.client.can_send_version(version):
|
||||
if kw['reimage_boot_volume']:
|
||||
raise exception.NovaException(
|
||||
'Conductor RPC version does not support '
|
||||
'reimage_boot_volume parameter.')
|
||||
else:
|
||||
del kw['reimage_boot_volume']
|
||||
version = '1.12'
|
||||
if not self.client.can_send_version(version):
|
||||
version = '1.8'
|
||||
del kw['request_spec']
|
||||
|
|
|
@ -79,7 +79,8 @@ class EvacuateJsonTest(test_servers.ServersSampleBase):
|
|||
injected_files=mock.ANY, new_pass="MySecretPass",
|
||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=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)
|
||||
|
||||
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
||||
def test_server_evacuate_find_host(self, rebuild_mock):
|
||||
|
@ -95,7 +96,8 @@ class EvacuateJsonTest(test_servers.ServersSampleBase):
|
|||
injected_files=mock.ANY, new_pass="MySecretPass",
|
||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=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)
|
||||
|
||||
|
||||
class EvacuateJsonTestV214(EvacuateJsonTest):
|
||||
|
@ -116,7 +118,8 @@ class EvacuateJsonTestV214(EvacuateJsonTest):
|
|||
injected_files=mock.ANY, new_pass="MySecretPass",
|
||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=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)
|
||||
|
||||
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
||||
def test_server_evacuate_find_host(self, rebuild_mock):
|
||||
|
@ -131,7 +134,8 @@ class EvacuateJsonTestV214(EvacuateJsonTest):
|
|||
injected_files=mock.ANY, new_pass="MySecretPass",
|
||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=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)
|
||||
|
||||
|
||||
class EvacuateJsonTestV229(EvacuateJsonTestV214):
|
||||
|
@ -158,7 +162,8 @@ class EvacuateJsonTestV229(EvacuateJsonTestV214):
|
|||
injected_files=mock.ANY, new_pass="MySecretPass",
|
||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=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)
|
||||
|
||||
@mock.patch('nova.conductor.manager.ComputeTaskManager.rebuild_instance')
|
||||
@mock.patch('nova.objects.ComputeNodeList.get_all_by_host')
|
||||
|
@ -178,7 +183,8 @@ class EvacuateJsonTestV229(EvacuateJsonTestV214):
|
|||
injected_files=mock.ANY, new_pass="MySecretPass",
|
||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=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)
|
||||
|
||||
|
||||
class EvacuateJsonTestV268(EvacuateJsonTestV229):
|
||||
|
@ -204,7 +210,8 @@ class EvacuateJsonTestV268(EvacuateJsonTestV229):
|
|||
injected_files=mock.ANY, new_pass="MySecretPass",
|
||||
orig_sys_metadata=mock.ANY, bdms=mock.ANY, recreate=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)
|
||||
|
||||
def test_server_evacuate_with_force(self):
|
||||
# doesn't apply to v2.68+, which removed the ability to force migrate
|
||||
|
|
|
@ -1928,8 +1928,6 @@ class _BaseTaskTestCase(object):
|
|||
migration_type='evacuation')
|
||||
migration.create()
|
||||
|
||||
# TODO(whoami-rajat): Remove this compatibility code
|
||||
del rebuild_args['reimage_boot_volume']
|
||||
self.assertRaises(exc.UnsupportedPolicyException,
|
||||
self.conductor.rebuild_instance,
|
||||
self.context,
|
||||
|
@ -4753,6 +4751,42 @@ class ConductorTaskRPCAPITestCase(_BaseTaskTestCase,
|
|||
mock.sentinel.migration)
|
||||
can_send_version.assert_called_once_with('1.23')
|
||||
|
||||
def test_rebuild_instance_volume_backed(self):
|
||||
inst_obj = self._create_fake_instance_obj()
|
||||
version = '1.24'
|
||||
cctxt_mock = mock.MagicMock()
|
||||
rebuild_args, compute_args = self._prepare_rebuild_args(
|
||||
{'host': inst_obj.host})
|
||||
rebuild_args['reimage_boot_volume'] = True
|
||||
|
||||
@mock.patch.object(self.conductor.client, 'prepare',
|
||||
return_value=cctxt_mock)
|
||||
@mock.patch.object(self.conductor.client, 'can_send_version',
|
||||
return_value=True)
|
||||
def _test(mock_can_send_ver, prepare_mock):
|
||||
self.conductor.rebuild_instance(
|
||||
self.context, inst_obj, **rebuild_args)
|
||||
prepare_mock.assert_called_once_with(version=version)
|
||||
kw = {'instance': inst_obj, **rebuild_args}
|
||||
cctxt_mock.cast.assert_called_once_with(
|
||||
self.context, 'rebuild_instance', **kw)
|
||||
_test()
|
||||
|
||||
def test_rebuild_instance_volume_backed_old_service(self):
|
||||
"""Tests rebuild_instance_volume_backed when the service is too old"""
|
||||
inst_obj = mock.MagicMock()
|
||||
rebuild_args, compute_args = self._prepare_rebuild_args(
|
||||
{'host': inst_obj.host})
|
||||
rebuild_args['reimage_boot_volume'] = True
|
||||
with mock.patch.object(
|
||||
self.conductor.client, 'can_send_version',
|
||||
return_value=False) as can_send_version:
|
||||
self.assertRaises(exc.NovaException,
|
||||
self.conductor.rebuild_instance,
|
||||
self.context, inst_obj,
|
||||
**rebuild_args)
|
||||
can_send_version.assert_called_once_with('1.24')
|
||||
|
||||
|
||||
class ConductorTaskAPITestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
|
||||
"""Compute task API Tests."""
|
||||
|
|
Loading…
Reference in New Issue