summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-08-26 00:35:24 +0000
committerGerrit Code Review <review@openstack.org>2021-08-26 00:35:24 +0000
commit48ad6b498d9934867bfa9ec7fe83907029b512c5 (patch)
tree2139d11ad99e91dba9009e2c3a1de94b03fa3e1e
parentb8174ece4d49775807826a54b7115e2a66f61cdd (diff)
parent98048ee1393b98573a1d667b5518331d408c62f5 (diff)
downloadnova-48ad6b498d9934867bfa9ec7fe83907029b512c5.tar.gz
Merge "Raise InstanceMappingNotFound if StaleDataError is encountered" into stable/train
-rw-r--r--nova/objects/instance_mapping.py13
-rw-r--r--nova/tests/unit/objects/test_instance_mapping.py9
2 files changed, 20 insertions, 2 deletions
diff --git a/nova/objects/instance_mapping.py b/nova/objects/instance_mapping.py
index 0392f04770..8b5f6ba92e 100644
--- a/nova/objects/instance_mapping.py
+++ b/nova/objects/instance_mapping.py
@@ -15,6 +15,7 @@ import collections
from oslo_log import log as logging
from oslo_utils import versionutils
import six
+from sqlalchemy.orm import exc as orm_exc
from sqlalchemy.orm import joinedload
from sqlalchemy.sql import false
from sqlalchemy.sql import func
@@ -161,8 +162,16 @@ class InstanceMapping(base.NovaTimestampObject, base.NovaObject):
def save(self):
changes = self.obj_get_changes()
changes = self._update_with_cell_id(changes)
- db_mapping = self._save_in_db(self._context, self.instance_uuid,
- changes)
+ try:
+ db_mapping = self._save_in_db(self._context, self.instance_uuid,
+ changes)
+ except orm_exc.StaleDataError:
+ # NOTE(melwitt): If the instance mapping has been deleted out from
+ # under us by conductor (delete requested while booting), we will
+ # encounter a StaleDataError after we retrieved the row and try to
+ # update it after it's been deleted. We can treat this like an
+ # instance mapping not found and allow the caller to handle it.
+ raise exception.InstanceMappingNotFound(uuid=self.instance_uuid)
self._from_db_object(self._context, self, db_mapping)
self.obj_reset_changes()
diff --git a/nova/tests/unit/objects/test_instance_mapping.py b/nova/tests/unit/objects/test_instance_mapping.py
index ec50517a20..2c877c0a1f 100644
--- a/nova/tests/unit/objects/test_instance_mapping.py
+++ b/nova/tests/unit/objects/test_instance_mapping.py
@@ -12,6 +12,7 @@
import mock
from oslo_utils import uuidutils
+from sqlalchemy.orm import exc as orm_exc
from nova import exception
from nova import objects
@@ -151,6 +152,14 @@ class _TestInstanceMappingObject(object):
comparators={
'cell_mapping': self._check_cell_map_value})
+ @mock.patch.object(instance_mapping.InstanceMapping, '_save_in_db')
+ def test_save_stale_data_error(self, save_in_db):
+ save_in_db.side_effect = orm_exc.StaleDataError
+ mapping_obj = objects.InstanceMapping(self.context)
+ mapping_obj.instance_uuid = uuidutils.generate_uuid()
+
+ self.assertRaises(exception.InstanceMappingNotFound, mapping_obj.save)
+
@mock.patch.object(instance_mapping.InstanceMapping, '_destroy_in_db')
def test_destroy(self, destroy_in_db):
uuid = uuidutils.generate_uuid()