From 67f1c98898406d2c663f46e6380762d81f38aff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9la=20Vancsics?= <vancsics@inf.u-szeged.hu> Date: Thu, 29 Jun 2017 09:29:33 +0200 Subject: [PATCH] Transform live_migration.post.dest notifications The following notifications has been transformed to the versioned notification framework. * live_migration.post.dest.start * live_migration.post.dest.end Co-Authored-By: Takashi Natsume <natsume.takashi@lab.ntt.co.jp> Change-Id: I510136a7eb0a832dfe469cb68d06d1b9472d9ae4 Implements: bp versioned-notification-transformation-rocky --- ...instance-live_migration_post_dest-end.json | 13 ++++++++++ ...stance-live_migration_post_dest-start.json | 11 ++++++++ nova/compute/manager.py | 8 ++++++ nova/notifications/objects/instance.py | 4 +-- .../test_instance.py | 25 +++++++++++++------ nova/tests/unit/compute/test_compute_mgr.py | 23 ++++++++++++++--- nova/virt/fake.py | 12 +++++++-- 7 files changed, 80 insertions(+), 16 deletions(-) create mode 100755 doc/notification_samples/instance-live_migration_post_dest-end.json create mode 100755 doc/notification_samples/instance-live_migration_post_dest-start.json diff --git a/doc/notification_samples/instance-live_migration_post_dest-end.json b/doc/notification_samples/instance-live_migration_post_dest-end.json new file mode 100755 index 000000000000..77f426ccefd9 --- /dev/null +++ b/doc/notification_samples/instance-live_migration_post_dest-end.json @@ -0,0 +1,13 @@ +{ + "event_type":"instance.live_migration_post_dest.end", + "payload":{ + "$ref": "common_payloads/InstanceActionPayload.json#", + "nova_object.data":{ + "host": "host2", + "node": "host2", + "power_state": "pending" + } + }, + "priority":"INFO", + "publisher_id":"nova-compute:host2" +} diff --git a/doc/notification_samples/instance-live_migration_post_dest-start.json b/doc/notification_samples/instance-live_migration_post_dest-start.json new file mode 100755 index 000000000000..74c158249ae9 --- /dev/null +++ b/doc/notification_samples/instance-live_migration_post_dest-start.json @@ -0,0 +1,11 @@ +{ + "event_type":"instance.live_migration_post_dest.start", + "payload":{ + "$ref": "common_payloads/InstanceActionPayload.json#", + "nova_object.data":{ + "task_state": "migrating" + } + }, + "priority":"INFO", + "publisher_id":"nova-compute:host2" +} diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 20b5059a6ea2..ea1b93cf7174 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -6382,6 +6382,10 @@ class ComputeManager(manager.Manager): self._notify_about_instance_usage( context, instance, "live_migration.post.dest.start", network_info=network_info) + compute_utils.notify_about_instance_action(context, instance, + self.host, + action=fields.NotificationAction.LIVE_MIGRATION_POST_DEST, + phase=fields.NotificationPhase.START) block_device_info = self._get_instance_block_device_info(context, instance) @@ -6420,6 +6424,10 @@ class ComputeManager(manager.Manager): self._notify_about_instance_usage( context, instance, "live_migration.post.dest.end", network_info=network_info) + compute_utils.notify_about_instance_action(context, instance, + self.host, + action=fields.NotificationAction.LIVE_MIGRATION_POST_DEST, + phase=fields.NotificationPhase.END) @wrap_exception() @wrap_instance_fault diff --git a/nova/notifications/objects/instance.py b/nova/notifications/objects/instance.py index 07cd6cbeb3e9..1ef22d78198d 100644 --- a/nova/notifications/objects/instance.py +++ b/nova/notifications/objects/instance.py @@ -461,8 +461,8 @@ class InstanceStateUpdatePayload(base.NotificationPayloadBase): @base.notification_sample('instance-live_migration_abort-end.json') # @base.notification_sample('instance-live_migration_post-start.json') # @base.notification_sample('instance-live_migration_post-end.json') -# @base.notification_sample('instance-live_migration_post_dest-start.json') -# @base.notification_sample('instance-live_migration_post_dest-end.json') +@base.notification_sample('instance-live_migration_post_dest-start.json') +@base.notification_sample('instance-live_migration_post_dest-end.json') @base.notification_sample('instance-live_migration_rollback-start.json') @base.notification_sample('instance-live_migration_rollback-end.json') # @base.notification_sample('instance-live_migration_rollback_dest-start.json') diff --git a/nova/tests/functional/notification_sample_tests/test_instance.py b/nova/tests/functional/notification_sample_tests/test_instance.py index 9be0b96c2060..9e3f17bc7055 100644 --- a/nova/tests/functional/notification_sample_tests/test_instance.py +++ b/nova/tests/functional/notification_sample_tests/test_instance.py @@ -55,7 +55,7 @@ class TestInstanceNotificationSampleWithMultipleCompute( actions = [ self._test_live_migration_rollback, self._test_live_migration_abort, - self._test_live_migration_pre, + self._test_live_migration_pre_and_post_dest, self._test_evacuate_server ] @@ -93,7 +93,7 @@ class TestInstanceNotificationSampleWithMultipleCompute( 'uuid': server['id']}, actual=fake_notifier.VERSIONED_NOTIFICATIONS[1]) - def _test_live_migration_pre(self, server): + def _test_live_migration_pre_and_post_dest(self, server): post = { 'os-migrateLive': { 'host': 'host2', @@ -118,12 +118,21 @@ class TestInstanceNotificationSampleWithMultipleCompute( actual=fake_notifier.VERSIONED_NOTIFICATIONS[1]) migrations = self.admin_api.get_active_migrations(server['id']) self.assertEqual(1, len(migrations)) - # FakeLiveMigrateDriver needs force_complete to finish migration - # TODO(elod.illes): Enhance FakeLiveMigrateDriver to finish migration - # automatically. This enhancement probably will happen as part of the - # patch proposing instance.live_migration_post.end transformation. - self.admin_api.force_complete_migration(server['id'], - migrations[0]['id']) + + self._wait_for_notification('instance.live_migration_post_dest.end') + self.assertEqual(4, len(fake_notifier.VERSIONED_NOTIFICATIONS)) + self._verify_notification( + 'instance-live_migration_post_dest-start', + replacements={ + 'reservation_id': server['reservation_id'], + 'uuid': server['id']}, + actual=fake_notifier.VERSIONED_NOTIFICATIONS[2]) + self._verify_notification( + 'instance-live_migration_post_dest-end', + replacements={ + 'reservation_id': server['reservation_id'], + 'uuid': server['id']}, + actual=fake_notifier.VERSIONED_NOTIFICATIONS[3]) def _test_live_migration_abort(self, server): post = { diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index a81c04a11e63..ccabca17d4e1 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -6851,8 +6851,10 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase): @mock.patch.object(self.compute, '_get_compute_info') @mock.patch.object(self.compute.driver, 'post_live_migration_at_destination') - def _do_test(post_live_migration_at_destination, _get_compute_info, - _get_power_state, _get_instance_block_device_info, + @mock.patch('nova.compute.utils.notify_about_instance_action') + def _do_test(mock_notify, post_live_migration_at_destination, + _get_compute_info, _get_power_state, + _get_instance_block_device_info, _notify_about_instance_usage, migrate_instance_finish, setup_networks_on_host, get_instance_nw_info, save): @@ -6865,6 +6867,12 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase): self.compute.post_live_migration_at_destination( self.context, self.instance, False) + mock_notify.assert_has_calls([ + mock.call(self.context, self.instance, self.instance.host, + action='live_migration_post_dest', phase='start'), + mock.call(self.context, self.instance, self.instance.host, + action='live_migration_post_dest', phase='end')]) + setup_networks_calls = [ mock.call(self.context, self.instance, self.compute.host), mock.call(self.context, self.instance, cn_old, teardown=True), @@ -6918,8 +6926,10 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase): host=uuids.fake_host)) @mock.patch.object(self.compute.driver, 'post_live_migration_at_destination') - def _do_test(post_live_migration_at_destination, _get_compute_info, - _get_power_state, _get_instance_block_device_info, + @mock.patch('nova.compute.utils.notify_about_instance_action') + def _do_test(mock_notify, post_live_migration_at_destination, + _get_compute_info, _get_power_state, + _get_instance_block_device_info, _notify_about_instance_usage, network_api, save): cn = mock.Mock(spec_set=['hypervisor_hostname']) cn.hypervisor_hostname = 'test_host' @@ -6927,6 +6937,11 @@ class ComputeManagerMigrationTestCase(test.NoDBTestCase): self.compute.post_live_migration_at_destination( self.context, self.instance, False) + mock_notify.assert_has_calls([ + mock.call(self.context, self.instance, self.instance.host, + action='live_migration_post_dest', phase='start'), + mock.call(self.context, self.instance, self.instance.host, + action='live_migration_post_dest', phase='end')]) self.assertIsNone(self.instance.node) _do_test() diff --git a/nova/virt/fake.py b/nova/virt/fake.py index e20d11f08c6f..33fa195c7486 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -691,8 +691,10 @@ class FakeLiveMigrateDriver(FakeDriver): migrate_data=None): self._abort_migration = False self._migrating = True - while self._migrating: + count = 0 + while self._migrating and count < 50: time.sleep(0.1) + count = count + 1 if self._abort_migration: recover_method(context, instance, dest, migrate_data, @@ -703,8 +705,14 @@ class FakeLiveMigrateDriver(FakeDriver): def live_migration_force_complete(self, instance): self._migrating = False - del self.instances[instance.uuid] + if instance.uuid in self.instances: + del self.instances[instance.uuid] def live_migration_abort(self, instance): self._abort_migration = True self._migrating = False + + def post_live_migration(self, context, instance, block_device_info, + migrate_data=None): + if instance.uuid in self.instances: + del self.instances[instance.uuid]