Skip to content

Commit

Permalink
Add notification for live migration
Browse files Browse the repository at this point in the history
Fix bug 1167759

Currently, if live migration failed, nova compute did not send
notification, this causes other services such as nova-scheduler
to have no chance to do some operations

The fix add notification logic for live_migration like other
VM instance operations such as resize, run instance etc.

Change-Id: Iaf61f5268e07284fd7d69ff331ce3bacd380c02b
  • Loading branch information
Jay Lau committed May 21, 2013
1 parent eebcd6f commit fe8bddc
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
23 changes: 23 additions & 0 deletions nova/compute/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3188,6 +3188,7 @@ def check_can_live_migrate_source(self, ctxt, instance, dest_check_data):
return self.driver.check_can_live_migrate_source(ctxt, instance,
dest_check_data)

@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
def pre_live_migration(self, context, instance,
block_migration=False, disk=None,
migrate_data=None):
Expand All @@ -3206,6 +3207,9 @@ def pre_live_migration(self, context, instance,
context, instance, bdms=bdms)

network_info = self._get_instance_nw_info(context, instance)
self._notify_about_instance_usage(
context, instance, "live_migration.pre.start",
network_info=network_info)

# TODO(tr3buchet): figure out how on the earth this is necessary
fixed_ips = network_info.fixed_ips()
Expand Down Expand Up @@ -3236,8 +3240,13 @@ def pre_live_migration(self, context, instance,
if block_migration:
self.driver.pre_block_migration(context, instance, disk)

self._notify_about_instance_usage(
context, instance, "live_migration.pre.end",
network_info=network_info)

return pre_live_migration_data

@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
def live_migration(self, context, dest, instance,
block_migration=False, migrate_data=None):
"""Executing live migration.
Expand Down Expand Up @@ -3354,6 +3363,7 @@ def _post_live_migration(self, ctxt, instance_ref,
"This error can be safely ignored."),
instance=instance_ref)

@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
def post_live_migration_at_destination(self, context, instance,
block_migration=False):
"""Post operations for live migration .
Expand All @@ -3379,6 +3389,9 @@ def post_live_migration_at_destination(self, context, instance,
migration)

network_info = self._get_instance_nw_info(context, instance)
self._notify_about_instance_usage(
context, instance, "live_migration.post.dest.start",
network_info=network_info)
block_device_info = self._get_instance_volume_block_device_info(
context, instance)

Expand All @@ -3402,6 +3415,9 @@ def post_live_migration_at_destination(self, context, instance,

# NOTE(vish): this is necessary to update dhcp
self.network_api.setup_networks_on_host(context, instance, self.host)
self._notify_about_instance_usage(
context, instance, "live_migration.post.dest.end",
network_info=network_info)

def _rollback_live_migration(self, context, instance,
dest, block_migration, migrate_data=None):
Expand Down Expand Up @@ -3445,13 +3461,17 @@ def _rollback_live_migration(self, context, instance,
self.compute_rpcapi.rollback_live_migration_at_destination(context,
instance, dest)

@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
def rollback_live_migration_at_destination(self, context, instance):
"""Cleaning up image directory that is created pre_live_migration.
:param context: security context
:param instance: an Instance dict sent over rpc
"""
network_info = self._get_instance_nw_info(context, instance)
self._notify_about_instance_usage(
context, instance, "live_migration.rollback.dest.start",
network_info=network_info)

# NOTE(tr3buchet): tear down networks on destination host
self.network_api.setup_networks_on_host(context, instance,
Expand All @@ -3463,6 +3483,9 @@ def rollback_live_migration_at_destination(self, context, instance):
context, instance)
self.driver.destroy(instance, self._legacy_nw_info(network_info),
block_device_info)
self._notify_about_instance_usage(
context, instance, "live_migration.rollback.dest.end",
network_info=network_info)

@periodic_task.periodic_task
def _heal_instance_info_cache(self, context):
Expand Down
42 changes: 42 additions & 0 deletions nova/tests/compute/test_compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -3493,13 +3493,21 @@ def stupid(*args, **kwargs):
self.compute.driver.ensure_filtering_rules_for_instance(
mox.IsA(instance), nw_info)

test_notifier.NOTIFICATIONS = []
# start test
self.mox.ReplayAll()
migrate_data = {'is_shared_storage': False}
ret = self.compute.pre_live_migration(c, instance=instance,
block_migration=False,
migrate_data=migrate_data)
self.assertEqual(ret, None)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
'compute.instance.live_migration.pre.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
'compute.instance.live_migration.pre.end')

# cleanup
db.instance_destroy(c, instance['uuid'])
Expand Down Expand Up @@ -3719,11 +3727,20 @@ def _finish_post_live_migration_at_destination(self):
self.compute.network_api.setup_networks_on_host(self.admin_ctxt,
mox.IgnoreArg(), self.compute.host)

test_notifier.NOTIFICATIONS = []
self.mox.ReplayAll()

self.compute.post_live_migration_at_destination(self.admin_ctxt,
self.instance)

self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
'compute.instance.live_migration.post.dest.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
'compute.instance.live_migration.post.dest.end')

return self.compute.conductor_api.instance_get_by_uuid(self.admin_ctxt,
self.instance['uuid'])

Expand All @@ -3749,6 +3766,31 @@ def test_post_live_migration_at_destination_without_compute_info(self):
updated = self._finish_post_live_migration_at_destination()
self.assertIsNone(updated['node'])

def test_rollback_live_migration_at_destination_correctly(self):
# creating instance testdata
c = context.get_admin_context()
instance_ref = self._create_fake_instance({'host': 'dummy'})
inst_uuid = instance_ref['uuid']
inst_id = instance_ref['id']

instance = jsonutils.to_primitive(db.instance_get(c, inst_id))
test_notifier.NOTIFICATIONS = []
# start test
self.mox.ReplayAll()
ret = self.compute.rollback_live_migration_at_destination(c,
instance=instance)
self.assertEqual(ret, None)
self.assertEqual(len(test_notifier.NOTIFICATIONS), 2)
msg = test_notifier.NOTIFICATIONS[0]
self.assertEqual(msg['event_type'],
'compute.instance.live_migration.rollback.dest.start')
msg = test_notifier.NOTIFICATIONS[1]
self.assertEqual(msg['event_type'],
'compute.instance.live_migration.rollback.dest.end')

# cleanup
db.instance_destroy(c, inst_uuid)

def test_run_kill_vm(self):
# Detect when a vm is terminated behind the scenes.
self.stubs.Set(compute_manager.ComputeManager,
Expand Down

0 comments on commit fe8bddc

Please sign in to comment.