fix error on delete interface when destroying instance

An instance may be destroyed prior nova-compute receives a
vif-delete-event. detach_interface() will so try to get the lxd
profile related to the instance which does not exist anymore, the
process will fail with a NotFound exception raised by lxclib.

In this commit we solve the issue by handling the exception and so
avoiding on updatating the lxc profile. We still continue the process
of vif_driver.un_plug() to ensure all got cleaned.

Change-Id: If7fd5dd17323ec625df3518311dfb012302b2711
Closes-Bug: #1808819
Signed-off-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@canonical.com>
This commit is contained in:
Sahid Orentino Ferdjaoui 2018-12-17 09:54:48 -05:00
parent 01c81314b8
commit bf3e123e1f
2 changed files with 49 additions and 18 deletions

View File

@ -796,6 +796,28 @@ class LXDDriverTest(test.NoDBTestCase):
self.assertEqual(['root'], sorted(profile.devices.keys()))
profile.save.assert_called_once_with(wait=True)
def test_detach_interface_not_found(self):
self.client.profiles.get.side_effect = lxdcore_exceptions.NotFound(
"404")
ctx = context.get_admin_context()
instance = fake_instance.fake_instance_obj(
ctx, name='test', memory_mb=0)
vif = {
'id': '0123456789abcdef',
'type': network_model.VIF_TYPE_OVS,
'address': '00:11:22:33:44:55',
'network': {
'bridge': 'fakebr'}}
lxd_driver = driver.LXDDriver(None)
lxd_driver.init_host(None)
lxd_driver.detach_interface(ctx, instance, vif)
self.vif_driver.unplug.assert_called_once_with(
instance, vif)
def test_migrate_disk_and_power_off(self):
container = mock.Mock()
self.client.containers.get.return_value = container

View File

@ -800,25 +800,34 @@ class LXDDriver(driver.ComputeDriver):
profile.save(wait=True)
def detach_interface(self, context, instance, vif):
profile = self.client.profiles.get(instance.name)
devname = lxd_vif.get_vif_devname(vif)
try:
profile = self.client.profiles.get(instance.name)
devname = lxd_vif.get_vif_devname(vif)
# NOTE(jamespage): Attempt to remove device using
# new style tap naming
if devname in profile.devices:
del profile.devices[devname]
profile.save(wait=True)
else:
# NOTE(jamespage): For upgrades, scan devices
# and attempt to identify
# using mac address as the
# device will *not* have a
# consistent name
for key, val in profile.devices.items():
if val.get('hwaddr') == vif['address']:
del profile.devices[key]
profile.save(wait=True)
break
# NOTE(jamespage): Attempt to remove device using
# new style tap naming
if devname in profile.devices:
del profile.devices[devname]
profile.save(wait=True)
else:
# NOTE(jamespage): For upgrades, scan devices
# and attempt to identify
# using mac address as the
# device will *not* have a
# consistent name
for key, val in profile.devices.items():
if val.get('hwaddr') == vif['address']:
del profile.devices[key]
profile.save(wait=True)
break
except lxd_exceptions.NotFound:
# This method is called when an instance get destroyed. It
# could happen that Nova to receive an event
# "vif-delete-event" after the instance is destroyed which
# result the lxd profile not exist.
LOG.debug("lxd profile for instance {instance} does not exist. "
"The instance probably got destroyed before this method "
"got called.".format(instance=instance.name))
self.vif_driver.unplug(instance, vif)