Don't attempt to lazy-load tags on a deleted instance

Since we don't have a specific handler for lazy-loading
tags on an Instance object it loads generically but
that will fail with an InstanceNotFound on a deleted
instance, so just handle this in obj_load_attr like we
do for 'services'. Note we can't call the TagList object
to load the tags for us since the DB API will fail if
the instance is deleted too.

Change-Id: If3580dcc3e83f612b96a2c3ad893a5045ee6100a
Related-Bug: #1592963
This commit is contained in:
Matt Riedemann 2016-06-15 17:39:52 -04:00
parent ffe2487cf6
commit e74b5b75de
2 changed files with 12 additions and 0 deletions

View File

@ -980,6 +980,11 @@ class Instance(base.NovaPersistentObject, base.NovaObject,
# filters on instances.deleted == 0, so if the instance is deleted
# don't attempt to even load services since we'll fail.
self.services = objects.ServiceList(self._context)
elif attrname == 'tags' and self.deleted:
# NOTE(mriedem): Same story as services, the DB API query
# in instance_tag_get_by_instance_uuid will fail if the instance
# has been deleted so just return an empty tag list here.
self.tags = objects.TagList(self._context)
else:
# FIXME(comstud): This should be optimized to only load the attr.
self._load_generic(attrname)

View File

@ -208,6 +208,13 @@ class _TestInstanceObject(object):
deleted=True)
self.assertEqual(0, len(instance.services))
def test_lazy_load_tags_on_deleted_instance(self):
# We should avoid trying to hit the database to reload the instance
# and just set the tags attribute to an empty list.
instance = objects.Instance(self.context, uuid=uuids.instance,
deleted=True)
self.assertEqual(0, len(instance.tags))
@mock.patch.object(db, 'instance_get')
def test_get_by_id(self, mock_get):
mock_get.return_value = self.fake_instance