diff options
author | Nikhil Komawar <nikhil.komawar@rackspace.com> | 2012-07-25 15:01:24 -0400 |
---|---|---|
committer | Nikhil Komawar <nikhil.komawar@rackspace.com> | 2012-07-27 11:35:31 -0400 |
commit | 19b54998bb5da2bf49190e22d6aa29da36d946b6 (patch) | |
tree | 6abba6f2c9d219e6899da1a911b5befb506a0bb5 /nova/notifications.py | |
parent | 5110f707dfc31ef756624c48ad7139397692350c (diff) | |
download | nova-19b54998bb5da2bf49190e22d6aa29da36d946b6.tar.gz nova-19b54998bb5da2bf49190e22d6aa29da36d946b6.tar.xz nova-19b54998bb5da2bf49190e22d6aa29da36d946b6.zip |
Implements notifications for more instance changes
Now sends a notification of other changes in the instance besides state
changes. Adds access_ip in notifications as well.
fixes bug 1028559
Change-Id: I664e6b858eda17dd732927f2c9b259212084a8fa
Diffstat (limited to 'nova/notifications.py')
-rw-r--r-- | nova/notifications.py | 126 |
1 files changed, 90 insertions, 36 deletions
diff --git a/nova/notifications.py b/nova/notifications.py index fdaf82f7a..d0374ac16 100644 --- a/nova/notifications.py +++ b/nova/notifications.py @@ -40,56 +40,111 @@ notify_state_opt = cfg.StrOpt('notify_on_state_change', default=None, '"vm_and_task_state" for notifications on VM and task state ' 'changes.') +notify_any_opt = cfg.BoolOpt('notify_on_any_change', default=False, + help='If set, send compute.instance.update notifications on instance ' + 'state changes. Valid values are False for no notifications, ' + 'True for notifications on any instance changes.') + FLAGS = flags.FLAGS FLAGS.register_opt(notify_state_opt) +FLAGS.register_opt(notify_any_opt) def send_update(context, old_instance, new_instance, service=None, host=None): - """Send compute.instance.update notification to report changes - in vm state and (optionally) task state + """Send compute.instance.update notification to report any changes occurred + in that instance """ - send_update_with_states(context, new_instance, old_instance["vm_state"], - new_instance["vm_state"], old_instance["task_state"], - new_instance["task_state"], service, host) + if not FLAGS.notify_on_any_change and not FLAGS.notify_on_state_change: + # skip all this if updates are disabled + return + + update_with_state_change = False + + old_vm_state = old_instance["vm_state"] + new_vm_state = new_instance["vm_state"] + old_task_state = old_instance["task_state"], + new_task_state = new_instance["task_state"] + + # we should check if we need to send a state change or a regular + # notification + if old_vm_state != new_vm_state: + # yes, the vm state is changing: + update_with_state_change = True + elif FLAGS.notify_on_state_change: + if (FLAGS.notify_on_state_change.lower() == "vm_and_task_state" and + old_task_state != new_task_state): + # yes, the task state is changing: + update_with_state_change = True + + if update_with_state_change: + # send a notification with state changes + # value of verify_states need not be True as the check for states is + # already done here + send_update_with_states(context, new_instance, old_vm_state, + new_vm_state, old_task_state, new_task_state, service, host) + + else: + try: + _send_instance_update_notification(context, new_instance, + service=service, host=host) + except Exception: + LOG.exception(_("Failed to send state update notification"), + instance=instance) def send_update_with_states(context, instance, old_vm_state, new_vm_state, - old_task_state, new_task_state, service=None, host=None): - """Send compute.instance.update notification to report changes - in vm state and (optionally) task state + old_task_state, new_task_state, service="compute", host=None, + verify_states=False): + """Send compute.instance.update notification to report changes if there + are any, in the instance """ if not FLAGS.notify_on_state_change: - # skip all this if state updates are disabled + # skip all this if updates are disabled return - fire_update = False - - if old_vm_state != new_vm_state: - # yes, the vm state is changing: - fire_update = True - elif (FLAGS.notify_on_state_change.lower() == "vm_and_task_state" and - old_task_state != new_task_state): - # yes, the task state is changing: - fire_update = True + fire_update = True + # send update notification by default + + if verify_states: + # check whether we need to send notification related to state changes + fire_update = False + # do not send notification if the confitions for vm and(or) task state + # are not satisfied + if old_vm_state != new_vm_state: + # yes, the vm state is changing: + fire_update = True + elif FLAGS.notify_on_state_change: + if (FLAGS.notify_on_state_change.lower() == "vm_and_task_state" and + old_task_state != new_task_state): + # yes, the task state is changing: + fire_update = True if fire_update: + # send either a state change or a regular notificaion try: - _send_instance_update_notification(context, instance, old_vm_state, - old_task_state, new_vm_state, new_task_state, service, - host) + _send_instance_update_notification(context, instance, + old_vm_state=old_vm_state, old_task_state=old_task_state, + new_vm_state=new_vm_state, new_task_state=new_task_state, + service=service, host=host) except Exception: LOG.exception(_("Failed to send state update notification"), instance=instance) -def _send_instance_update_notification(context, instance, old_vm_state, - old_task_state, new_vm_state, new_task_state, service=None, host=None): +def _send_instance_update_notification(context, instance, old_vm_state=None, + old_task_state=None, new_vm_state=None, new_task_state=None, + service="compute", host=None): """Send 'compute.instance.update' notification to inform observers about instance state changes""" - payload = usage_from_instance(context, instance, None, None) + payload = info_from_instance(context, instance, None, None) + + if not new_vm_state: + new_vm_state = instance["vm_state"] + if not new_task_state: + new_task_state = instance["task_state"] states_payload = { "old_state": old_vm_state, @@ -109,11 +164,6 @@ def _send_instance_update_notification(context, instance, old_vm_state, bw = bandwidth_usage(instance, audit_start) payload["bandwidth"] = bw - # if the service name (e.g. api/scheduler/compute) is not provided, default - # to "compute" - if not service: - service = "compute" - publisher_id = notifier_api.publisher_id(service, host) notifier_api.notify(context, publisher_id, 'compute.instance.update', @@ -194,9 +244,9 @@ def image_meta(system_metadata): return image_meta -def usage_from_instance(context, instance_ref, network_info, +def info_from_instance(context, instance_ref, network_info, system_metadata, **kw): - """Get usage information for an instance which is common to all + """Get detailed instance information for an instance which is common to all notifications. :param network_info: network_info provided if not None @@ -220,7 +270,7 @@ def usage_from_instance(context, instance_ref, network_info, except exception.NotFound: system_metadata = {} - usage_info = dict( + instance_info = dict( # Owner properties tenant_id=instance_ref['project_id'], user_id=instance_ref['user_id'], @@ -266,6 +316,10 @@ def usage_from_instance(context, instance_ref, network_info, # Status properties state=instance_ref['vm_state'], state_description=null_safe_str(instance_ref.get('task_state')), + + # accessIPs + access_ip_v4=instance_ref['access_ip_v4'], + access_ip_v6=instance_ref['access_ip_v6'], ) if network_info is not None: @@ -274,11 +328,11 @@ def usage_from_instance(context, instance_ref, network_info, for ip in vif.fixed_ips(): ip["label"] = vif["network"]["label"] fixed_ips.append(ip) - usage_info['fixed_ips'] = fixed_ips + instance_info['fixed_ips'] = fixed_ips # add image metadata image_meta_props = image_meta(system_metadata) - usage_info["image_meta"] = image_meta_props + instance_info["image_meta"] = image_meta_props - usage_info.update(kw) - return usage_info + instance_info.update(kw) + return instance_info |