Skip to content

Commit 6f74bc1

Browse files
committed
Add confirm_snapshot_based_resize conductor RPC method
This adds the conductor ComputeTaskManager method confirm_snapshot_based_resize along with the related conductor RPC API client method which by default will be an RPC cast from the API for a confirmResize server action but can also be RPC called in the case of deleting a server in VERIFY_RESIZE status. Part of blueprint cross-cell-resize Change-Id: If4c4b23891bfc340deb18a2f500510a472a869c9
1 parent 3f11a9d commit 6f74bc1

File tree

4 files changed

+84
-1
lines changed

4 files changed

+84
-1
lines changed

nova/conductor/api.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,8 @@ def cache_images(self, context, aggregate, image_ids):
175175
self.image_api.get(context, image_id)
176176
self.conductor_compute_rpcapi.cache_images(context, aggregate,
177177
image_ids)
178+
179+
def confirm_snapshot_based_resize(
180+
self, ctxt, instance, migration, do_cast=True):
181+
self.conductor_compute_rpcapi.confirm_snapshot_based_resize(
182+
ctxt, instance, migration, do_cast=do_cast)

nova/conductor/manager.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from nova.compute import utils as compute_utils
3939
from nova.compute.utils import wrap_instance_event
4040
from nova.compute import vm_states
41+
from nova.conductor.tasks import cross_cell_migrate
4142
from nova.conductor.tasks import live_migrate
4243
from nova.conductor.tasks import migrate
4344
from nova import context as nova_context
@@ -232,7 +233,7 @@ class ComputeTaskManager(base.Base):
232233
may involve coordinating activities on multiple compute nodes.
233234
"""
234235

235-
target = messaging.Target(namespace='compute_task', version='1.21')
236+
target = messaging.Target(namespace='compute_task', version='1.22')
236237

237238
def __init__(self):
238239
super(ComputeTaskManager, self).__init__()
@@ -1859,3 +1860,18 @@ def skipped_host(context, host, image_ids):
18591860
context, aggregate,
18601861
fields.NotificationAction.IMAGE_CACHE,
18611862
fields.NotificationPhase.END)
1863+
1864+
@targets_cell
1865+
@wrap_instance_event(prefix='conductor')
1866+
def confirm_snapshot_based_resize(self, context, instance, migration):
1867+
"""Executes the ConfirmResizeTask
1868+
1869+
:param context: nova auth request context targeted at the target cell
1870+
:param instance: Instance object in "resized" status from the target
1871+
cell
1872+
:param migration: Migration object from the target cell for the resize
1873+
operation expected to have status "confirming"
1874+
"""
1875+
task = cross_cell_migrate.ConfirmResizeTask(
1876+
context, instance, migration, self.notifier, self.compute_rpcapi)
1877+
task.execute()

nova/conductor/rpcapi.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import nova.conf
2323
from nova import exception
24+
from nova.i18n import _
2425
from nova.objects import base as objects_base
2526
from nova import profiler
2627
from nova import rpc
@@ -283,6 +284,7 @@ class ComputeTaskAPI(object):
283284
1.20 - migrate_server() now gets a 'host_list' parameter that represents
284285
potential alternate hosts for retries within a cell.
285286
1.21 - Added cache_images()
287+
1.22 - Added confirm_snapshot_based_resize()
286288
"""
287289

288290
def __init__(self):
@@ -452,3 +454,14 @@ def cache_images(self, ctxt, aggregate, image_ids):
452454
cctxt = self.client.prepare(version=version)
453455
cctxt.cast(ctxt, 'cache_images', aggregate=aggregate,
454456
image_ids=image_ids)
457+
458+
def confirm_snapshot_based_resize(
459+
self, ctxt, instance, migration, do_cast=True):
460+
version = '1.22'
461+
if not self.client.can_send_version(version):
462+
raise exception.ServiceTooOld(_('nova-conductor too old'))
463+
kw = {'instance': instance, 'migration': migration}
464+
cctxt = self.client.prepare(version=version)
465+
if do_cast:
466+
return cctxt.cast(ctxt, 'confirm_snapshot_based_resize', **kw)
467+
return cctxt.call(ctxt, 'confirm_snapshot_based_resize', **kw)

nova/tests/unit/conductor/test_conductor.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,18 @@ def test_evacuate_instance_with_request_spec(self, mock_notify):
17711771
self.context, inst_obj, 'thebesthost', action='rebuild_scheduled',
17721772
source='nova-conductor')
17731773

1774+
@mock.patch(
1775+
'nova.conductor.tasks.cross_cell_migrate.ConfirmResizeTask.execute')
1776+
def test_confirm_snapshot_based_resize(self, mock_execute):
1777+
instance = self._create_fake_instance_obj(ctxt=self.context)
1778+
migration = objects.Migration(
1779+
context=self.context, source_compute=instance.host,
1780+
source_node=instance.node, instance_uuid=instance.uuid,
1781+
status='confirming', migration_type='resize')
1782+
self.conductor_manager.confirm_snapshot_based_resize(
1783+
self.context, instance=instance, migration=migration)
1784+
mock_execute.assert_called_once_with()
1785+
17741786

17751787
class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
17761788
"""ComputeTaskManager Tests."""
@@ -3794,6 +3806,43 @@ def _test(prepare_mock, can_send_mock):
37943806

37953807
_test()
37963808

3809+
def _test_confirm_snapshot_based_resize(self, do_cast):
3810+
"""Tests how confirm_snapshot_based_resize is called when do_cast is
3811+
True or False.
3812+
"""
3813+
instance = objects.Instance()
3814+
migration = objects.Migration()
3815+
3816+
@mock.patch.object(self.conductor.client, 'can_send_version',
3817+
return_value=True)
3818+
@mock.patch.object(self.conductor.client, 'prepare')
3819+
def _test(prepare_mock, can_send_mock):
3820+
self.conductor.confirm_snapshot_based_resize(
3821+
self.context, instance, migration, do_cast=do_cast)
3822+
kw = {'instance': instance, 'migration': migration}
3823+
if do_cast:
3824+
prepare_mock.return_value.cast.assert_called_once_with(
3825+
self.context, 'confirm_snapshot_based_resize', **kw)
3826+
else:
3827+
prepare_mock.return_value.call.assert_called_once_with(
3828+
self.context, 'confirm_snapshot_based_resize', **kw)
3829+
_test()
3830+
3831+
def test_confirm_snapshot_based_resize_cast(self):
3832+
self._test_confirm_snapshot_based_resize(do_cast=True)
3833+
3834+
def test_confirm_snapshot_based_resize_call(self):
3835+
self._test_confirm_snapshot_based_resize(do_cast=False)
3836+
3837+
def test_confirm_snapshot_based_resize_old_service(self):
3838+
"""Tests confirm_snapshot_based_resize when the service is too old."""
3839+
with mock.patch.object(
3840+
self.conductor.client, 'can_send_version', return_value=False):
3841+
self.assertRaises(exc.ServiceTooOld,
3842+
self.conductor.confirm_snapshot_based_resize,
3843+
self.context, mock.sentinel.instance,
3844+
mock.sentinel.migration)
3845+
37973846

37983847
class ConductorTaskAPITestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
37993848
"""Compute task API Tests."""

0 commit comments

Comments
 (0)