Don't delete sys_meta on instance delete

Unfortunately, we require to access instance_system_metadata to get
data (specifically at least instance_type data) for instances that have
been deleted.

There's 2 cases where this is true:

1) nova-api supports showing deleting instances when you specify a
'changes-since' param.
2) The _usage_audit_log periodic task pulls all instances during the
audit period, which includes instances that have been deleted during
that period.

This reverts commit 17bca43895, which was
attempting to fix a bug where we leave instance_system_metadata entries
undeleted from the DB.  There's not an easy way to query for the deleted
sys_meta data in an efficient manner, and leaving the entries undeleted is
the lesser of the 2 evils for now.

Fixes bug 1185190

Change-Id: I898f0546c49126dcc56a4237120082f95dc82304
(cherry picked from commit 4885aa2870)
This commit is contained in:
Chris Behrens 2013-05-29 14:21:00 +00:00
parent fde8680dee
commit 8c136a8ee4
3 changed files with 25 additions and 13 deletions

View File

@ -1521,9 +1521,6 @@ def instance_destroy(context, instance_uuid, constraint=None):
session.query(models.InstanceMetadata).\
filter_by(instance_uuid=instance_uuid).\
soft_delete()
session.query(models.InstanceSystemMetadata).\
filter_by(instance_uuid=instance_uuid).\
soft_delete()
return instance_ref

View File

@ -311,9 +311,8 @@ class UsageInfoTestCase(test.TestCase):
self.assertEquals(payload['image_ref_url'], image_ref_url)
self.compute.terminate_instance(self.context, instance)
def test_notify_usage_exists_fail_on_deleted_instance(self):
# notify_usage_exists should not work for a deleted VM. A
# notification should be done before the instance is deleted in the db.
def test_notify_usage_exists_deleted_instance(self):
# Ensure 'exists' notification generates appropriate usage data.
instance_id = self._create_instance()
instance = db.instance_get(self.context, instance_id)
# Set some system metadata
@ -325,8 +324,27 @@ class UsageInfoTestCase(test.TestCase):
self.compute.terminate_instance(self.context, instance)
instance = db.instance_get(self.context.elevated(read_deleted='yes'),
instance_id)
self.assertRaises(KeyError, compute_utils.notify_usage_exists,
self.context, instance)
compute_utils.notify_usage_exists(self.context, instance)
msg = test_notifier.NOTIFICATIONS[-1]
self.assertEquals(msg['priority'], 'INFO')
self.assertEquals(msg['event_type'], 'compute.instance.exists')
payload = msg['payload']
self.assertEquals(payload['tenant_id'], self.project_id)
self.assertEquals(payload['user_id'], self.user_id)
self.assertEquals(payload['instance_id'], instance['uuid'])
self.assertEquals(payload['instance_type'], 'm1.tiny')
type_id = instance_types.get_instance_type_by_name('m1.tiny')['id']
self.assertEquals(str(payload['instance_type_id']), str(type_id))
for attr in ('display_name', 'created_at', 'launched_at',
'state', 'state_description',
'bandwidth', 'audit_period_beginning',
'audit_period_ending', 'image_meta'):
self.assertTrue(attr in payload,
msg="Key %s not in payload" % attr)
self.assertEquals(payload['image_meta'],
{'md_key1': 'val1', 'md_key2': 'val2'})
image_ref_url = "%s/images/1" % glance.generate_glance_url()
self.assertEquals(payload['image_ref_url'], image_ref_url)
def test_notify_usage_exists_instance_not_found(self):
# Ensure 'exists' notification generates appropriate usage data.

View File

@ -411,7 +411,7 @@ class DbApiTestCase(DbTestCase):
system_meta = db.instance_system_metadata_get(ctxt, instance['uuid'])
self.assertEqual('baz', system_meta['original_image_ref'])
def test_delete_instance_and_system_metadata_on_instance_destroy(self):
def test_delete_instance_metadata_on_instance_destroy(self):
ctxt = context.get_admin_context()
# Create an instance with some metadata
@ -423,11 +423,8 @@ class DbApiTestCase(DbTestCase):
self.assertEqual('meow', instance_meta['key1'])
db.instance_destroy(ctxt, instance['uuid'])
instance_meta = db.instance_metadata_get(ctxt, instance['uuid'])
instance_system_meta = db.instance_system_metadata_get(ctxt,
instance['uuid'])
# Make sure instance and system metadata is deleted as well
# Make sure instance metadata is deleted as well
self.assertEqual({}, instance_meta)
self.assertEqual({}, instance_system_meta)
def test_instance_update_unique_name(self):
otherprojectcontext = context.RequestContext(self.user_id,