Add checks for retrieving deleted instance metadata for notification events.
This enables metadata for a deleted instance to be reported in usage notifications. However, deleted metadata for a nondeleted instance will not be shown. Fixes bug 1021430. Change-Id: I7ce5c720c7705be34724679bb4ff99fb8ba37a27
This commit is contained in:
@@ -109,16 +109,6 @@ def _send_instance_update_notification(context, instance, old_vm_state,
|
||||
bw = bandwidth_usage(instance, audit_start)
|
||||
payload["bandwidth"] = bw
|
||||
|
||||
try:
|
||||
system_metadata = db.instance_system_metadata_get(
|
||||
context, instance.uuid)
|
||||
except exception.NotFound:
|
||||
system_metadata = {}
|
||||
|
||||
# add image metadata
|
||||
image_meta_props = image_meta(system_metadata)
|
||||
payload["image_meta"] = image_meta_props
|
||||
|
||||
# if the service name (e.g. api/scheduler/compute) is not provided, default
|
||||
# to "compute"
|
||||
if not service:
|
||||
@@ -222,6 +212,19 @@ def usage_from_instance(context, instance_ref, network_info,
|
||||
|
||||
instance_type_name = instance_ref.get('instance_type', {}).get('name', '')
|
||||
|
||||
if system_metadata is None:
|
||||
try:
|
||||
if instance_ref.get('deleted'):
|
||||
with utils.temporary_mutation(context, read_deleted='yes'):
|
||||
system_metadata = db.instance_system_metadata_get(
|
||||
context, instance_ref['uuid'])
|
||||
else:
|
||||
system_metadata = db.instance_system_metadata_get(
|
||||
context, instance_ref['uuid'])
|
||||
|
||||
except exception.NotFound:
|
||||
system_metadata = {}
|
||||
|
||||
usage_info = dict(
|
||||
# Owner properties
|
||||
tenant_id=instance_ref['project_id'],
|
||||
@@ -273,5 +276,9 @@ def usage_from_instance(context, instance_ref, network_info,
|
||||
if network_info is not None:
|
||||
usage_info['fixed_ips'] = network_info.fixed_ips()
|
||||
|
||||
# add image metadata
|
||||
image_meta_props = image_meta(system_metadata)
|
||||
usage_info["image_meta"] = image_meta_props
|
||||
|
||||
usage_info.update(kw)
|
||||
return usage_info
|
||||
|
||||
@@ -114,6 +114,41 @@ class UsageInfoTestCase(test.TestCase):
|
||||
self.assertEquals(payload['image_ref_url'], image_ref_url)
|
||||
self.compute.terminate_instance(self.context, instance['uuid'])
|
||||
|
||||
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
|
||||
sys_metadata = {'image_md_key1': 'val1',
|
||||
'image_md_key2': 'val2',
|
||||
'other_data': 'meow'}
|
||||
db.instance_system_metadata_update(self.context, instance['uuid'],
|
||||
sys_metadata, False)
|
||||
self.compute.terminate_instance(self.context, instance['uuid'])
|
||||
instance = db.instance_get(self.context.elevated(read_deleted='yes'),
|
||||
instance_id)
|
||||
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" % utils.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."""
|
||||
instance_id = self._create_instance()
|
||||
|
||||
Reference in New Issue
Block a user