summaryrefslogtreecommitdiffstats
path: root/nova/compute
diff options
context:
space:
mode:
Diffstat (limited to 'nova/compute')
-rw-r--r--nova/compute/api.py23
-rw-r--r--nova/compute/manager.py8
-rw-r--r--nova/compute/utils.py94
3 files changed, 35 insertions, 90 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py
index e83dfb3a6..3fd358a34 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -41,6 +41,7 @@ from nova import flags
import nova.image
from nova import log as logging
from nova import network
+from nova import notifications
from nova.openstack.common import cfg
from nova.openstack.common import excutils
from nova.openstack.common import jsonutils
@@ -599,6 +600,11 @@ class API(base.Base):
instance_id = instance['id']
instance_uuid = instance['uuid']
+ # send a state update notification for the initial create to
+ # show it going from non-existent to BUILDING
+ notifications.send_update_with_states(context, instance, None,
+ vm_states.BUILDING, None, None)
+
for security_group_id in security_groups:
self.db.instance_add_security_group(elevated,
instance_uuid,
@@ -919,8 +925,14 @@ class API(base.Base):
:returns: None
"""
- rv = self.db.instance_update(context, instance["id"], kwargs)
- return dict(rv.iteritems())
+
+ # Update the instance record and send a state update notification
+ # if task or vm state changed
+ old_ref, instance_ref = self.db.instance_update_and_get_original(
+ context, instance["id"], kwargs)
+ notifications.send_update(context, old_ref, instance_ref)
+
+ return dict(instance_ref.iteritems())
@wrap_check_policy
@check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.SHUTOFF,
@@ -1260,9 +1272,16 @@ class API(base.Base):
else:
raise Exception(_('Image type not recognized %s') % image_type)
+ # change instance state and notify
+ old_vm_state = instance["vm_state"]
+ old_task_state = instance["task_state"]
+
self.db.instance_test_and_set(
context, instance_uuid, 'task_state', [None], task_state)
+ notifications.send_update_with_states(context, instance, old_vm_state,
+ instance["vm_state"], old_task_state, instance["task_state"])
+
properties = {
'instance_uuid': instance_uuid,
'user_id': str(context.user_id),
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index bd3cd02cc..6a0251a15 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -61,6 +61,7 @@ from nova import log as logging
from nova import manager
from nova import network
from nova.network import model as network_model
+from nova import notifications
from nova.notifier import api as notifier
from nova.openstack.common import cfg
from nova.openstack.common import excutils
@@ -253,7 +254,12 @@ class ComputeManager(manager.SchedulerDependentManager):
def _instance_update(self, context, instance_id, **kwargs):
"""Update an instance in the database using kwargs as value."""
- return self.db.instance_update(context, instance_id, kwargs)
+
+ (old_ref, instance_ref) = self.db.instance_update_and_get_original(
+ context, instance_id, kwargs)
+ notifications.send_update(context, old_ref, instance_ref)
+
+ return instance_ref
def _set_instance_error_state(self, context, instance_uuid):
try:
diff --git a/nova/compute/utils.py b/nova/compute/utils.py
index 7a6ac8671..ab5ccfbf0 100644
--- a/nova/compute/utils.py
+++ b/nova/compute/utils.py
@@ -25,6 +25,7 @@ from nova import flags
from nova import log
from nova import network
from nova.network import model as network_model
+from nova import notifications
from nova.notifier import api as notifier_api
from nova import utils
@@ -52,45 +53,10 @@ def notify_usage_exists(context, instance_ref, current_period=False,
override in the notification if not None.
"""
- admin_context = nova.context.get_admin_context(read_deleted='yes')
- begin, end = utils.last_completed_audit_period()
- bw = {}
- if current_period:
- audit_start = end
- audit_end = utils.utcnow()
- else:
- audit_start = begin
- audit_end = end
-
- if (instance_ref.get('info_cache') and
- instance_ref['info_cache'].get('network_info')):
-
- cached_info = instance_ref['info_cache']['network_info']
- nw_info = network_model.NetworkInfo.hydrate(cached_info)
- else:
- try:
- nw_info = network.API().get_instance_nw_info(admin_context,
- instance_ref)
- except Exception:
- LOG.exception('Failed to get nw_info', instance=instance_ref)
- if ignore_missing_network_data:
- return
- raise
-
- macs = [vif['address'] for vif in nw_info]
- uuids = [instance_ref.uuid]
-
- bw_usages = db.bw_usage_get_by_uuids(admin_context, uuids, audit_start)
- bw_usages = [b for b in bw_usages if b.mac in macs]
-
- for b in bw_usages:
- label = 'net-name-not-found-%s' % b['mac']
- for vif in nw_info:
- if vif['address'] == b['mac']:
- label = vif['network']['label']
- break
+ audit_start, audit_end = notifications.audit_period_bounds(current_period)
- bw[label] = dict(bw_in=b.bw_in, bw_out=b.bw_out)
+ bw = notifications.bandwidth_usage(instance_ref, audit_start,
+ ignore_missing_network_data)
if system_metadata is None:
try:
@@ -100,10 +66,7 @@ def notify_usage_exists(context, instance_ref, current_period=False,
system_metadata = {}
# add image metadata to the notification:
- image_meta = {}
- for md_key, md_value in system_metadata.iteritems():
- if md_key.startswith('image_'):
- image_meta[md_key[6:]] = md_value
+ image_meta = notifications.image_meta(system_metadata)
extra_info = dict(audit_period_beginning=str(audit_start),
audit_period_ending=str(audit_end),
@@ -231,49 +194,6 @@ def legacy_network_info(network_model):
return network_info
-def _usage_from_instance(context, instance_ref, network_info,
- system_metadata, **kw):
- """
- Get usage information for an instance which is common to all
- notifications.
-
- :param network_info: network_info provided if not None
- :param system_metadata: system_metadata DB entries for the instance,
- if not None. *NOTE*: Currently unused here in trunk, but needed for
- potential custom modifications.
- """
-
- def null_safe_str(s):
- return str(s) if s else ''
-
- image_ref_url = utils.generate_image_url(instance_ref['image_ref'])
-
- usage_info = dict(
- tenant_id=instance_ref['project_id'],
- user_id=instance_ref['user_id'],
- instance_id=instance_ref['uuid'],
- instance_type=instance_ref['instance_type']['name'],
- instance_type_id=instance_ref['instance_type_id'],
- memory_mb=instance_ref['memory_mb'],
- disk_gb=instance_ref['root_gb'] + instance_ref['ephemeral_gb'],
- display_name=instance_ref['display_name'],
- created_at=str(instance_ref['created_at']),
- # Nova's deleted vs terminated instance terminology is confusing,
- # this should be when the instance was deleted (i.e. terminated_at),
- # not when the db record was deleted. (mdragon)
- deleted_at=null_safe_str(instance_ref['terminated_at']),
- launched_at=null_safe_str(instance_ref['launched_at']),
- image_ref_url=image_ref_url,
- state=instance_ref['vm_state'],
- state_description=null_safe_str(instance_ref['task_state']))
-
- if network_info is not None:
- usage_info['fixed_ips'] = network_info.fixed_ips()
-
- usage_info.update(kw)
- return usage_info
-
-
def notify_about_instance_usage(context, instance, event_suffix,
network_info=None, system_metadata=None,
extra_usage_info=None, host=None):
@@ -296,8 +216,8 @@ def notify_about_instance_usage(context, instance, event_suffix,
if not extra_usage_info:
extra_usage_info = {}
- usage_info = _usage_from_instance(context, instance, network_info,
- system_metadata, **extra_usage_info)
+ usage_info = notifications.usage_from_instance(context, instance,
+ network_info, system_metadata, **extra_usage_info)
notifier_api.notify(context, 'compute.%s' % host,
'compute.instance.%s' % event_suffix,