Merge "post live migration: don't call Neutron needlessly" into stable/ussuri
This commit is contained in:
commit
07a0358c0e
|
@ -8434,7 +8434,13 @@ class ComputeManager(manager.Manager):
|
||||||
# Releasing vlan.
|
# Releasing vlan.
|
||||||
# (not necessary in current implementation?)
|
# (not necessary in current implementation?)
|
||||||
|
|
||||||
network_info = self.network_api.get_instance_nw_info(ctxt, instance)
|
# NOTE(artom) At this point in time we have not bound the ports to the
|
||||||
|
# destination host yet (this happens in migrate_instance_start()
|
||||||
|
# below). Therefore, the "old" source network info that's still in the
|
||||||
|
# instance info cache is safe to use here, since it'll be used below
|
||||||
|
# during driver.post_live_migration_at_source() to unplug the VIFs on
|
||||||
|
# the source.
|
||||||
|
network_info = instance.get_network_info()
|
||||||
|
|
||||||
self._notify_about_instance_usage(ctxt, instance,
|
self._notify_about_instance_usage(ctxt, instance,
|
||||||
"live_migration._post.start",
|
"live_migration._post.start",
|
||||||
|
|
|
@ -182,7 +182,8 @@ class TestVolAttachmentsDuringLiveMigration(
|
||||||
self.assertEqual(1, len(attachments))
|
self.assertEqual(1, len(attachments))
|
||||||
|
|
||||||
|
|
||||||
class LiveMigrationNeutronFailure(integrated_helpers._IntegratedTestBase):
|
class LiveMigrationNeutronInteractionsTest(
|
||||||
|
integrated_helpers._IntegratedTestBase):
|
||||||
# NOTE(artom) We need the admin API to force the host when booting the test
|
# NOTE(artom) We need the admin API to force the host when booting the test
|
||||||
# server.
|
# server.
|
||||||
ADMIN_API = True
|
ADMIN_API = True
|
||||||
|
@ -192,38 +193,29 @@ class LiveMigrationNeutronFailure(integrated_helpers._IntegratedTestBase):
|
||||||
self._start_compute('src')
|
self._start_compute('src')
|
||||||
self._start_compute('dest')
|
self._start_compute('dest')
|
||||||
|
|
||||||
def test_live_migrate_get_nw_info_fails(self):
|
def test_live_migrate_vifs_from_info_cache(self):
|
||||||
"""Test that if the driver.post_live_migration() call fails (for
|
"""Test that bug 1879787 can no longer manifest itself because we get
|
||||||
example by not being able to connect to Neutron), the exception goes
|
the network_info from the instance info cache, and not Neutron.
|
||||||
unhandled and results in the live-migration erroring out. This is bug
|
|
||||||
1879787.
|
|
||||||
"""
|
"""
|
||||||
|
def stub_notify(context, instance, event_suffix,
|
||||||
|
network_info=None, extra_usage_info=None, fault=None):
|
||||||
|
vif = network_info[0]
|
||||||
|
# Make sure we have the correct VIF (the NeutronFixture
|
||||||
|
# deterministically uses port_2 for networks=auto) and that the
|
||||||
|
# profile does not contain `migrating_to`, indicating that we did
|
||||||
|
# not obtain it from the Neutron API.
|
||||||
|
self.assertEqual(self.neutron.port_2['id'], vif['id'])
|
||||||
|
self.assertNotIn('migrating_to', vif['profile'])
|
||||||
|
|
||||||
server = self._create_server(networks='auto',
|
server = self._create_server(networks='auto',
|
||||||
host=self.computes['src'].host)
|
host=self.computes['src'].host)
|
||||||
|
|
||||||
orig_plm = self.computes['src'].manager._post_live_migration
|
|
||||||
|
|
||||||
def stub_plm(*args, **kwargs):
|
|
||||||
"""We simulate a failure in driver.post_live_migration() on the
|
|
||||||
source by stubbing the source compute's _post_live_migration() with
|
|
||||||
a method that, within a context that mocks
|
|
||||||
driver.post_live_migration() to raise an exception, calls the
|
|
||||||
original compute.manager._post_live_migration(). This is needed to
|
|
||||||
make sure driver.post_live_migration() raises only once, and only
|
|
||||||
on the source.
|
|
||||||
"""
|
|
||||||
with mock.patch.object(self.computes['src'].manager.network_api,
|
|
||||||
'get_instance_nw_info',
|
|
||||||
side_effect=ConnectionError):
|
|
||||||
return orig_plm(*args, **kwargs)
|
|
||||||
|
|
||||||
with mock.patch.object(self.computes['src'].manager,
|
with mock.patch.object(self.computes['src'].manager,
|
||||||
'_post_live_migration',
|
'_notify_about_instance_usage',
|
||||||
side_effect=stub_plm):
|
side_effect=stub_notify) as mock_notify:
|
||||||
# FIXME(artom) Until bug 1879787 is fixed, the raised
|
self._live_migrate(server, 'completed')
|
||||||
# ConnectionError will go unhandled, the migration will fail, and
|
|
||||||
# the instance will still be reported as being on the source, even
|
|
||||||
# though it's actually running on the destination.
|
|
||||||
self._live_migrate(server, 'error', server_expected_state='ERROR')
|
|
||||||
server = self.api.get_server(server['id'])
|
server = self.api.get_server(server['id'])
|
||||||
self.assertEqual('src', server['OS-EXT-SRV-ATTR:host'])
|
self.assertEqual('dest', server['OS-EXT-SRV-ATTR:host'])
|
||||||
|
# We don't care about call arguments here, we just want to be sure
|
||||||
|
# our stub actually got called.
|
||||||
|
mock_notify.assert_called()
|
||||||
|
|
|
@ -6562,12 +6562,15 @@ class ComputeTestCase(BaseTestCase,
|
||||||
'clear_events_for_instance'),
|
'clear_events_for_instance'),
|
||||||
mock.patch.object(self.compute, 'update_available_resource'),
|
mock.patch.object(self.compute, 'update_available_resource'),
|
||||||
mock.patch.object(migration_obj, 'save'),
|
mock.patch.object(migration_obj, 'save'),
|
||||||
|
mock.patch.object(instance, 'get_network_info'),
|
||||||
) as (
|
) as (
|
||||||
post_live_migration,
|
post_live_migration,
|
||||||
migrate_instance_start, post_live_migration_at_destination,
|
migrate_instance_start, post_live_migration_at_destination,
|
||||||
post_live_migration_at_source, setup_networks_on_host,
|
post_live_migration_at_source, setup_networks_on_host,
|
||||||
clear_events, update_available_resource, mig_save
|
clear_events, update_available_resource, mig_save, get_nw_info,
|
||||||
):
|
):
|
||||||
|
nw_info = network_model.NetworkInfo.hydrate([])
|
||||||
|
get_nw_info.return_value = nw_info
|
||||||
self.compute._post_live_migration(c, instance, dest,
|
self.compute._post_live_migration(c, instance, dest,
|
||||||
migrate_data=migrate_data,
|
migrate_data=migrate_data,
|
||||||
source_bdms=bdms)
|
source_bdms=bdms)
|
||||||
|
@ -6589,7 +6592,7 @@ class ComputeTestCase(BaseTestCase,
|
||||||
post_live_migration_at_destination.assert_has_calls([
|
post_live_migration_at_destination.assert_has_calls([
|
||||||
mock.call(c, instance, False, dest)])
|
mock.call(c, instance, False, dest)])
|
||||||
post_live_migration_at_source.assert_has_calls(
|
post_live_migration_at_source.assert_has_calls(
|
||||||
[mock.call(c, instance, [])])
|
[mock.call(c, instance, nw_info)])
|
||||||
clear_events.assert_called_once_with(instance)
|
clear_events.assert_called_once_with(instance)
|
||||||
update_available_resource.assert_has_calls([mock.call(c)])
|
update_available_resource.assert_has_calls([mock.call(c)])
|
||||||
self.assertEqual('completed', migration_obj.status)
|
self.assertEqual('completed', migration_obj.status)
|
||||||
|
|
Loading…
Reference in New Issue