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:
whoami-rajat 2022-02-28 20:34:53 +05:30
parent 30aab9c234
commit 6919db5612
5 changed files with 68 additions and 15 deletions

View File

@ -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.

View File

@ -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

View File

@ -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']

View File

@ -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

View File

@ -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."""