Merge "post live migration: don't call Neutron needlessly" into stable/ussuri

This commit is contained in:
Zuul 2020-09-10 19:33:19 +00:00 committed by Gerrit Code Review
commit 07a0358c0e
3 changed files with 34 additions and 33 deletions

View File

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

View File

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

View File

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