summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/compute/utils.py10
-rw-r--r--nova/notifications.py27
-rw-r--r--nova/tests/test_compute_utils.py35
3 files changed, 60 insertions, 12 deletions
diff --git a/nova/compute/utils.py b/nova/compute/utils.py
index f0bfe7646..81726105c 100644
--- a/nova/compute/utils.py
+++ b/nova/compute/utils.py
@@ -23,6 +23,7 @@ from nova.network import model as network_model
from nova import notifications
from nova.notifier import api as notifier_api
from nova.openstack.common import log
+from nova import utils
FLAGS = flags.FLAGS
@@ -55,8 +56,13 @@ def notify_usage_exists(context, instance_ref, current_period=False,
if system_metadata is None:
try:
- system_metadata = db.instance_system_metadata_get(
- context, instance_ref.uuid)
+ 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 = {}
diff --git a/nova/notifications.py b/nova/notifications.py
index 998abee65..933af1f20 100644
--- a/nova/notifications.py
+++ b/nova/notifications.py
@@ -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
diff --git a/nova/tests/test_compute_utils.py b/nova/tests/test_compute_utils.py
index 4e00025bc..5081536ac 100644
--- a/nova/tests/test_compute_utils.py
+++ b/nova/tests/test_compute_utils.py
@@ -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()