summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Riedemann <mriedem.os@gmail.com>2017-04-05 15:12:41 -0400
committerMatt Riedemann <mriedem.os@gmail.com>2017-04-05 19:46:53 -0400
commiteaa38bc973d65f897078157e2008653ef47e3d47 (patch)
tree9bcdd214ef1a3efe79c1062649e6146a1c8db6ad
parentacb19160d4d348e29a21ad57c61c7369352c4d1c (diff)
downloadnova-eaa38bc973d65f897078157e2008653ef47e3d47.tar.gz
Short-circuit local delete path for cells v2 and InstanceNotFound
When we're going down the local delete path for cells v2 in the API and instance.destroy() fails with an InstanceNotFound error, we are racing with a concurrent delete request and know that the instance is alread deleted, so we can just return rather than fall through to the rest of the code in the _delete() method, like for BDMs and console tokens. Conflicts: nova/compute/api.py NOTE(mriedem): The conflict is due to not having change edf51119fa59ff8a3337abb9107a06fa33d3c68f in stable/ocata. Change-Id: I58690a25044d2804573451983323dde05be9e5d6 Closes-Bug: #1680211 (cherry picked from commit 5a9cc2fb7af3e3a9db44646bbd23cfcfb16891f5)
-rw-r--r--nova/compute/api.py2
-rw-r--r--nova/tests/unit/compute/test_compute_api.py9
2 files changed, 6 insertions, 5 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index 439e570771..5abe581e29 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -1814,6 +1814,8 @@ class API(base.Base):
return
except exception.InstanceNotFound:
quotas.rollback()
+ # Instance is already deleted.
+ return
if not instance:
# Instance is already deleted.
return
diff --git a/nova/tests/unit/compute/test_compute_api.py b/nova/tests/unit/compute/test_compute_api.py
index fa1d8635d3..2ff2a7f953 100644
--- a/nova/tests/unit/compute/test_compute_api.py
+++ b/nova/tests/unit/compute/test_compute_api.py
@@ -1552,9 +1552,7 @@ class _ComputeAPIUnitTestMixIn(object):
@mock.patch('nova.context.target_cell')
@mock.patch('nova.compute.utils.notify_about_instance_delete')
@mock.patch('nova.objects.Instance.destroy')
- @mock.patch('nova.objects.BlockDeviceMappingList.get_by_instance_uuid',
- # This just lets us exit the test early.
- side_effect=test.TestingException)
+ @mock.patch('nova.objects.BlockDeviceMappingList.get_by_instance_uuid')
def test_delete_instance_from_cell0_rollback_quota(
self, bdms_get_by_instance_uuid, destroy_mock, notify_mock,
target_cell_mock):
@@ -1584,8 +1582,7 @@ class _ComputeAPIUnitTestMixIn(object):
_delete_while_booting, _lookup_instance,
_get_flavor_for_reservation, _create_reservations
):
- self.assertRaises(
- test.TestingException, self.compute_api._delete,
+ self.compute_api._delete(
self.context, instance, 'delete', mock.NonCallableMock())
_delete_while_booting.assert_called_once_with(
self.context, instance)
@@ -1615,6 +1612,8 @@ class _ComputeAPIUnitTestMixIn(object):
self.compute_api.notifier, self.context, instance)
destroy_mock.assert_called_once_with()
quota_mock.rollback.assert_called_once_with()
+ # Make sure we short-circuited and returned.
+ bdms_get_by_instance_uuid.assert_not_called()
@mock.patch.object(context, 'target_cell')
@mock.patch.object(objects.InstanceMapping, 'get_by_instance_uuid',