driver: catch any cleanup exceptions during spawning process

If something wrong happens during the process of spawning an
instance. The process is calling 'cleanup' to rollback, unfortunately
this process is also sensible and can fail in a way that the original
error would be hidden.

In this commit we ensure to catch any exceptions coming from cleanup
to keep the original and root error well logged.

Change-Id: I81e5d0a9532e88b11ad2ef14c995db6e6a966f2f
Related-bug: #1821878
Signed-off-by: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@canonical.com>
This commit is contained in:
Sahid Orentino Ferdjaoui 2019-04-02 11:06:34 +02:00 committed by sahid
parent aee3ef71d9
commit 067e4bd1bf
2 changed files with 42 additions and 3 deletions

View File

@ -413,6 +413,41 @@ class LXDDriverTest(test.NoDBTestCase):
lxd_driver.cleanup.assert_called_once_with(
ctx, instance, network_info, block_device_info)
@mock.patch('nova.virt.configdrive.required_by', return_value=False)
def test_spawn_container_cleanup_fail(self, configdrive):
"""Cleanup is called but also fail when container creation fails."""
self.client.containers.get.side_effect = (
lxdcore_exceptions.LXDAPIException(MockResponse(404)))
container = mock.Mock()
self.client.containers.create.return_value = container
ctx = context.get_admin_context()
instance = fake_instance.fake_instance_obj(
ctx, name='test', memory_mb=0)
image_meta = mock.Mock()
injected_files = mock.Mock()
admin_password = mock.Mock()
allocations = mock.Mock()
network_info = [_VIF]
block_device_info = mock.Mock()
virtapi = manager.ComputeVirtAPI(mock.MagicMock())
lxd_driver = driver.LXDDriver(virtapi)
lxd_driver.init_host(None)
container.start.side_effect = (
lxdcore_exceptions.LXDAPIException(MockResponse(500)))
lxd_driver.cleanup = mock.Mock()
lxd_driver.cleanup.side_effect = Exception("a bad thing")
self.assertRaises(
lxdcore_exceptions.LXDAPIException,
lxd_driver.spawn,
ctx, instance, image_meta, injected_files, admin_password,
allocations, network_info, block_device_info)
lxd_driver.cleanup.assert_called_once_with(
ctx, instance, network_info, block_device_info)
def test_spawn_container_start_fail(self, neutron_failure=None):
def container_get(*args, **kwargs):
raise lxdcore_exceptions.LXDAPIException(MockResponse(404))

View File

@ -611,10 +611,14 @@ class LXDDriver(driver.ComputeDriver):
self.firewall_driver.apply_instance_filter(
instance, network_info)
except lxd_exceptions.LXDAPIException as e:
except lxd_exceptions.LXDAPIException:
with excutils.save_and_reraise_exception():
self.cleanup(
context, instance, network_info, block_device_info)
try:
self.cleanup(
context, instance, network_info, block_device_info)
except Exception as e:
LOG.warn('The cleanup process failed with: %s. This '
'error may or not may be relevant', e)
def destroy(self, context, instance, network_info, block_device_info=None,
destroy_disks=True, migrate_data=None):