diff --git a/blazar/plugins/instances/instance_plugin.py b/blazar/plugins/instances/instance_plugin.py index f5190f06..ff7bb944 100644 --- a/blazar/plugins/instances/instance_plugin.py +++ b/blazar/plugins/instances/instance_plugin.py @@ -498,7 +498,14 @@ class VirtualInstancePlugin(base.BasePlugin, nova.NovaClientWrapper): for server in self.nova.servers.list(search_opts={ 'flavor': reservation_id, 'all_tenants': 1}, detailed=False): - server.delete() + try: + self.nova.servers.delete(server=server) + except nova_exceptions.NotFound: + LOG.info("Could not find server '%s', may have been deleted " + "concurrently.", server.id) + except Exception as e: + LOG.exception("Failed to delete server '%s': %s.", server.id, + str(e)) # We need to check the deletion is complete before deleting the # reservation inventory. See the bug #1813252 for details. diff --git a/blazar/tests/plugins/instances/test_instance_plugin.py b/blazar/tests/plugins/instances/test_instance_plugin.py index d252b993..8887ef03 100644 --- a/blazar/tests/plugins/instances/test_instance_plugin.py +++ b/blazar/tests/plugins/instances/test_instance_plugin.py @@ -17,6 +17,7 @@ import datetime import uuid import mock +from novaclient import exceptions as nova_exceptions import six from blazar import context @@ -920,7 +921,7 @@ class TestVirtualInstancePlugin(tests.TestCase): self.patch(db_api, 'host_allocation_destroy') - fake_servers = [mock.MagicMock(method='delete') for i in range(5)] + fake_servers = [mock.MagicMock() for i in range(5)] mock_nova = mock.MagicMock() type(plugin).nova = mock_nova # First, we return the fake servers to delete. Second, on the check in @@ -930,6 +931,11 @@ class TestVirtualInstancePlugin(tests.TestCase): mock_cleanup_resources = self.patch(plugin, 'cleanup_resources') + mock_log = self.patch(instance_plugin, 'LOG') + mock_nova.servers.delete.side_effect = [nova_exceptions.NotFound( + 404, "The server doesn't exist in Nova"), Exception('Unknown'), + None, None, None] + plugin.on_end('resource-id1') mock_nova.flavor_access.remove_tenant_access.assert_called_once_with( @@ -939,8 +945,12 @@ class TestVirtualInstancePlugin(tests.TestCase): search_opts={'flavor': 'reservation-id1', 'all_tenants': 1}, detailed=False) mock_nova.servers.list.call_count = 3 - for fake in fake_servers: - fake.delete.assert_called_once() + self.assertEqual(5, mock_nova.servers.delete.call_count) + mock_log.info.assert_any_call( + "Could not find server '%s', may have been deleted concurrently.", + fake_servers[0].id) + mock_log.exception.assert_called_with( + "Failed to delete server '%s': %s.", fake_servers[1].id, 'Unknown') for i in range(2): mock_delete_reservation_inventory.assert_any_call( 'host' + str(i + 1), 'reservation-id1')