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, old_display_name=None): """Send 'compute.instance.update' notification to inform observers about instance state changes. """ payload = info_from_instance(context, instance, None, None) # determine how we'll report states payload.update( _compute_states_payload( instance, old_vm_state, old_task_state, new_vm_state, new_task_state)) # add audit fields: (audit_start, audit_end) = audit_period_bounds(current_period=True) payload["audit_period_beginning"] = audit_start payload["audit_period_ending"] = audit_end # add bw usage info: bw = bandwidth_usage(instance, audit_start) payload["bandwidth"] = bw # add old display name if it is changed if old_display_name: payload["old_display_name"] = old_display_name rpc.get_notifier(service, host).info(context, 'compute.instance.update', payload)
def get_session(self, host=None): """Returns a connection to the LXD hypervisor This method should be used to create a connection to the LXD hypervisor via the pylxd API call. :param host: host is the LXD daemon to connect to :return: pylxd object """ try: if host is None: conn = api.API() elif host == CONF.host: conn = api.API() else: conn = api.API(host=host) except Exception as ex: # notify the compute host that the connection failed # via an rpc call LOG.exception(_LE('Connection to LXD failed')) payload = dict(ip=CONF.host, method='_connect', reason=ex) rpc.get_notifier('compute').error(nova_context.get_admin_context, 'compute.nova_lxd.error', payload) raise exception.HypervisorUnavailable(host=CONF.host) return conn
def handle_schedule_error(context, ex, instance_uuid, request_spec): """On run_instance failure, update instance state and send notifications. """ if isinstance(ex, exception.NoValidHost): LOG.warning(_LW("NoValidHost exception with message: \'%s\'"), ex.format_message().strip(), instance_uuid=instance_uuid) else: LOG.exception(_LE("Exception during scheduler.run_instance")) state = vm_states.ERROR.upper() LOG.warning(_LW('Setting instance to %s state.'), state, instance_uuid=instance_uuid) (old_ref, new_ref) = db.instance_update_and_get_original(context, instance_uuid, {'vm_state': vm_states.ERROR, 'task_state': None}) notifications.send_update(context, old_ref, new_ref, service="scheduler") compute_utils.add_instance_fault_from_exc(context, new_ref, ex, sys.exc_info()) properties = request_spec.get('instance_properties', {}) payload = dict(request_spec=request_spec, instance_properties=properties, instance_id=instance_uuid, state=vm_states.ERROR, method='run_instance', reason=ex) rpc.get_notifier('scheduler').error(context, 'scheduler.run_instance', payload)
def send_api_fault(url, status, exception): """Send an api.fault notification.""" if not CONF.notify_api_faults: return payload = {"url": url, "exception": str(exception), "status": status} rpc.get_notifier("api").error(None, "api.fault", payload)
def send_api_fault(url, status, exception): """Send an api.fault notification.""" if not CONF.notify_api_faults: return payload = {'url': url, 'exception': str(exception), 'status': status} rpc.get_notifier('api').error(None, 'api.fault', payload)
def send_api_fault(url, status, exception): """Send an api.fault notification.""" if not CONF.notify_api_faults: return payload = {"url": url, "exception": six.text_type(exception), "status": status} rpc.get_notifier("api").error( common_context.get_current() or nova.context.get_admin_context(), "api.fault", payload )
def _test_set_vm_state_and_notify(self, request_spec, expected_uuids): updates = dict(vm_state='fake-vm-state') service = 'fake-service' method = 'fake-method' exc_info = 'exc_info' self.mox.StubOutWithMock(compute_utils, 'add_instance_fault_from_exc') self.mox.StubOutWithMock(notifications, 'send_update') self.mox.StubOutWithMock(db, 'instance_update_and_get_original') self.mox.StubOutWithMock(rpc, 'get_notifier') notifier = self.mox.CreateMockAnything() rpc.get_notifier(service).AndReturn(notifier) old_ref = 'old_ref' new_ref = 'new_ref' inst_obj = 'inst_obj' for _uuid in expected_uuids: db.instance_update_and_get_original( self.context, _uuid, updates, columns_to_join=['system_metadata']).AndReturn( (old_ref, new_ref)) notifications.send_update(self.context, old_ref, inst_obj, service=service) compute_utils.add_instance_fault_from_exc( self.context, new_ref, exc_info, mox.IsA(tuple)) payload = dict(request_spec=request_spec, instance_properties=request_spec.get( 'instance_properties', {}), instance_id=_uuid, state='fake-vm-state', method=method, reason=exc_info) event_type = '%s.%s' % (service, method) notifier.error(self.context, event_type, payload) self.mox.ReplayAll() with mock.patch.object(objects.Instance, '_from_db_object', return_value=inst_obj): scheduler_utils.set_vm_state_and_notify(self.context, service, method, updates, exc_info, request_spec, db)
def send_api_fault(url, status, exception): """Send an api.fault notification.""" if not CONF.notify_api_faults: return payload = {'url': url, 'exception': six.text_type(exception), 'status': status} rpc.get_notifier('api').error(common_context.get_current() or nova.context.get_admin_context(), 'api.fault', payload)
def test_handle_schedule_error_adds_instance_fault(self): instance = {"uuid": "fake-uuid"} self.mox.StubOutWithMock(db, "instance_update_and_get_original") self.mox.StubOutWithMock(db, "instance_fault_create") db.instance_update_and_get_original(self.context, instance["uuid"], mox.IgnoreArg()).AndReturn((None, instance)) db.instance_fault_create(self.context, mox.IgnoreArg()) self.mox.StubOutWithMock(rpc, "get_notifier") notifier = self.mox.CreateMockAnything() rpc.get_notifier("conductor", CONF.host).AndReturn(notifier) rpc.get_notifier("scheduler").AndReturn(notifier) notifier.error(self.context, "scheduler.run_instance", mox.IgnoreArg()) self.mox.ReplayAll() driver.handle_schedule_error(self.context, exception.NoValidHost("test"), instance["uuid"], {})
def _test_set_vm_state_and_notify(self, request_spec, expected_uuids): updates = dict(vm_state='fake-vm-state') service = 'fake-service' method = 'fake-method' exc_info = 'exc_info' self.mox.StubOutWithMock(compute_utils, 'add_instance_fault_from_exc') self.mox.StubOutWithMock(notifications, 'send_update') self.mox.StubOutWithMock(db, 'instance_update_and_get_original') self.mox.StubOutWithMock(rpc, 'get_notifier') notifier = self.mox.CreateMockAnything() rpc.get_notifier('conductor', CONF.host).AndReturn(notifier) rpc.get_notifier(service).AndReturn(notifier) old_ref = 'old_ref' new_ref = 'new_ref' for uuid in expected_uuids: db.instance_update_and_get_original( self.context, uuid, updates).AndReturn((old_ref, new_ref)) notifications.send_update(self.context, old_ref, new_ref, service=service) compute_utils.add_instance_fault_from_exc( self.context, mox.IsA(conductor_api.LocalAPI), new_ref, exc_info, mox.IsA(tuple)) payload = dict(request_spec=request_spec, instance_properties=request_spec.get( 'instance_properties', {}), instance_id=uuid, state='fake-vm-state', method=method, reason=exc_info) event_type = '%s.%s' % (service, method) notifier.error(self.context, event_type, payload) self.mox.ReplayAll() scheduler_utils.set_vm_state_and_notify(self.context, service, method, updates, exc_info, request_spec, db)
def test_notify_usage_exists_instance_not_found(self): # Ensure 'exists' notification generates appropriate usage data. instance_id = self._create_instance() instance = instance_obj.Instance.get_by_id(self.context, instance_id, expected_attrs=['metadata', 'system_metadata', 'info_cache']) self.compute.terminate_instance(self.context, instance, [], []) compute_utils.notify_usage_exists( rpc.get_notifier('compute'), self.context, instance) msg = fake_notifier.NOTIFICATIONS[-1] self.assertEqual(msg.priority, 'INFO') self.assertEqual(msg.event_type, 'compute.instance.exists') payload = msg.payload self.assertEqual(payload['tenant_id'], self.project_id) self.assertEqual(payload['user_id'], self.user_id) self.assertEqual(payload['instance_id'], instance['uuid']) self.assertEqual(payload['instance_type'], 'm1.tiny') type_id = flavors.get_flavor_by_name('m1.tiny')['id'] self.assertEqual(str(payload['instance_type_id']), str(type_id)) flavor_id = flavors.get_flavor_by_name('m1.tiny')['flavorid'] self.assertEqual(str(payload['instance_flavor_id']), str(flavor_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.assertEqual(payload['image_meta'], {}) image_ref_url = "%s/images/1" % glance.generate_glance_url() self.assertEqual(payload['image_ref_url'], image_ref_url)
def set_vm_state_and_notify(context, service, method, updates, ex, request_spec, db): """changes VM state and notifies.""" LOG.warning(_("Failed to %(service)s_%(method)s: %(ex)s"), {"service": service, "method": method, "ex": ex}) vm_state = updates["vm_state"] properties = request_spec.get("instance_properties", {}) # NOTE(vish): We shouldn't get here unless we have a catastrophic # failure, so just set all instances to error. if uuid # is not set, instance_uuids will be set to [None], this # is solely to preserve existing behavior and can # be removed along with the 'if instance_uuid:' if we can # verify that uuid is always set. uuids = [properties.get("uuid")] notifier = rpc.get_notifier(service) for instance_uuid in request_spec.get("instance_uuids") or uuids: if instance_uuid: state = vm_state.upper() LOG.warning(_("Setting instance to %s state."), state, instance_uuid=instance_uuid) # update instance state and notify on the transition (old_ref, new_ref) = db.instance_update_and_get_original(context, instance_uuid, updates) notifications.send_update(context, old_ref, new_ref, service=service) compute_utils.add_instance_fault_from_exc(context, new_ref, ex, sys.exc_info()) payload = dict( request_spec=request_spec, instance_properties=properties, instance_id=instance_uuid, state=vm_state, method=method, reason=ex, ) event_type = "%s.%s" % (service, method) notifier.error(context, event_type, payload)
def set_instance_error_state_and_notify(instance): """ Set an instance to ERROR state and send out a notification """ # set instance to error state. Instance # could be a dictionary when this method is called during # virtual machine delete process. instance['vm_state'] = vm_states.ERROR conductor.API().instance_update( context.get_admin_context(), instance['uuid'], vm_state=vm_states.ERROR, task_state=None) instance_name = instance['name'] host_name = instance['host'] LOG.warn(_('Unable to find virtual machine %(inst_name)s ' 'on host %(host)s. Set state to ERROR') % {'inst_name': instance_name, 'host': host_name}) # Send event notification note = {'event_type': 'compute.instance.log', 'msg': _('Unable to find virtual machine {instance_name} on ' 'host {host_name}. An operation might have been ' 'performed on the virtual machine outside of PowerVC or' ' the deploy of the virtual machine failed.' 'The virtual machine is now set to Error state in the ' 'database.'), 'instance_name': instance_name, 'host_name': host_name} notifier = rpc.get_notifier(service='compute', host=host_name) notifier.warn(context.get_admin_context(), 'compute.instance.log', note)
def __init__(self, *args, **kwargs): super(FilterScheduler, self).__init__(*args, **kwargs) self.notifier = rpc.get_notifier('scheduler') # TODO(sbauza): It seems weird that we load a scheduler client for # the FilterScheduler but it will be the PlacementClient later on once # we split the needed methods into a separate library. self.scheduler_client = scheduler_client.SchedulerClient()
def test_notify_usage_exists_instance_not_found(self): # Ensure 'exists' notification generates appropriate usage data. instance = create_instance(self.context) self.compute.terminate_instance(self.context, instance, [], []) compute_utils.notify_usage_exists(rpc.get_notifier("compute"), self.context, instance) msg = fake_notifier.NOTIFICATIONS[-1] self.assertEqual(msg.priority, "INFO") self.assertEqual(msg.event_type, "compute.instance.exists") payload = msg.payload self.assertEqual(payload["tenant_id"], self.project_id) self.assertEqual(payload["user_id"], self.user_id) self.assertEqual(payload["instance_id"], instance["uuid"]) self.assertEqual(payload["instance_type"], "m1.tiny") type_id = flavors.get_flavor_by_name("m1.tiny")["id"] self.assertEqual(str(payload["instance_type_id"]), str(type_id)) flavor_id = flavors.get_flavor_by_name("m1.tiny")["flavorid"] self.assertEqual(str(payload["instance_flavor_id"]), str(flavor_id)) for attr in ( "display_name", "created_at", "launched_at", "state", "state_description", "bandwidth", "audit_period_beginning", "audit_period_ending", "image_meta", ): self.assertIn(attr, payload, "Key %s not in payload" % attr) self.assertEqual(payload["image_meta"], {}) image_ref_url = "%s/images/1" % glance.generate_glance_url() self.assertEqual(payload["image_ref_url"], image_ref_url)
def test_notify_about_instance_usage(self): instance = create_instance(self.context) # Set some system metadata sys_metadata = {"image_md_key1": "val1", "image_md_key2": "val2", "other_data": "meow"} instance.system_metadata.update(sys_metadata) instance.save() extra_usage_info = {"image_name": "fake_name"} compute_utils.notify_about_instance_usage( rpc.get_notifier("compute"), self.context, instance, "create.start", extra_usage_info=extra_usage_info ) self.assertEqual(len(fake_notifier.NOTIFICATIONS), 1) msg = fake_notifier.NOTIFICATIONS[0] self.assertEqual(msg.priority, "INFO") self.assertEqual(msg.event_type, "compute.instance.create.start") payload = msg.payload self.assertEqual(payload["tenant_id"], self.project_id) self.assertEqual(payload["user_id"], self.user_id) self.assertEqual(payload["instance_id"], instance["uuid"]) self.assertEqual(payload["instance_type"], "m1.tiny") type_id = flavors.get_flavor_by_name("m1.tiny")["id"] self.assertEqual(str(payload["instance_type_id"]), str(type_id)) flavor_id = flavors.get_flavor_by_name("m1.tiny")["flavorid"] self.assertEqual(str(payload["instance_flavor_id"]), str(flavor_id)) for attr in ("display_name", "created_at", "launched_at", "state", "state_description", "image_meta"): self.assertIn(attr, payload, "Key %s not in payload" % attr) self.assertEqual(payload["image_meta"], {"md_key1": "val1", "md_key2": "val2"}) self.assertEqual(payload["image_name"], "fake_name") image_ref_url = "%s/images/1" % glance.generate_glance_url() self.assertEqual(payload["image_ref_url"], image_ref_url) self.compute.terminate_instance(self.context, instance, [], [])
def test_notify_about_instance_usage(self): instance = create_instance(self.context) # Set some system metadata sys_metadata = {'image_md_key1': 'val1', 'image_md_key2': 'val2', 'other_data': 'meow'} instance.system_metadata.update(sys_metadata) instance.save() extra_usage_info = {'image_name': 'fake_name'} compute_utils.notify_about_instance_usage( rpc.get_notifier('compute'), self.context, instance, 'create.start', extra_usage_info=extra_usage_info) self.assertEqual(len(fake_notifier.NOTIFICATIONS), 1) msg = fake_notifier.NOTIFICATIONS[0] self.assertEqual(msg.priority, 'INFO') self.assertEqual(msg.event_type, 'compute.instance.create.start') payload = msg.payload self.assertEqual(payload['tenant_id'], self.project_id) self.assertEqual(payload['user_id'], self.user_id) self.assertEqual(payload['instance_id'], instance['uuid']) self.assertEqual(payload['instance_type'], 'm1.tiny') type_id = flavors.get_flavor_by_name('m1.tiny')['id'] self.assertEqual(str(payload['instance_type_id']), str(type_id)) flavor_id = flavors.get_flavor_by_name('m1.tiny')['flavorid'] self.assertEqual(str(payload['instance_flavor_id']), str(flavor_id)) for attr in ('display_name', 'created_at', 'launched_at', 'state', 'state_description', 'image_meta'): self.assertIn(attr, payload, "Key %s not in payload" % attr) self.assertEqual(payload['image_meta'], {'md_key1': 'val1', 'md_key2': 'val2'}) self.assertEqual(payload['image_name'], 'fake_name') image_ref_url = "%s/images/1" % glance.generate_glance_url() self.assertEqual(payload['image_ref_url'], image_ref_url) self.compute.terminate_instance(self.context, instance, [], [])
def test_notify_usage_exists_deleted_instance(self): # Ensure 'exists' notification generates appropriate usage data. instance = create_instance(self.context) # Set some system metadata sys_metadata = {'image_md_key1': 'val1', 'image_md_key2': 'val2', 'other_data': 'meow'} instance.system_metadata.update(sys_metadata) instance.save() self.compute.terminate_instance(self.context, instance, [], []) compute_utils.notify_usage_exists( rpc.get_notifier('compute'), self.context, instance) msg = fake_notifier.NOTIFICATIONS[-1] self.assertEqual(msg.priority, 'INFO') self.assertEqual(msg.event_type, 'compute.instance.exists') payload = msg.payload self.assertEqual(payload['tenant_id'], self.project_id) self.assertEqual(payload['user_id'], self.user_id) self.assertEqual(payload['instance_id'], instance['uuid']) self.assertEqual(payload['instance_type'], 'm1.tiny') type_id = flavors.get_flavor_by_name('m1.tiny')['id'] self.assertEqual(str(payload['instance_type_id']), str(type_id)) flavor_id = flavors.get_flavor_by_name('m1.tiny')['flavorid'] self.assertEqual(str(payload['instance_flavor_id']), str(flavor_id)) for attr in ('display_name', 'created_at', 'launched_at', 'state', 'state_description', 'bandwidth', 'audit_period_beginning', 'audit_period_ending', 'image_meta'): self.assertIn(attr, payload, "Key %s not in payload" % attr) self.assertEqual(payload['image_meta'], {'md_key1': 'val1', 'md_key2': 'val2'}) image_ref_url = "%s/images/%s" % (glance.generate_glance_url(), uuids.fake_image_ref) self.assertEqual(payload['image_ref_url'], image_ref_url)
def send_migration_notification(context, instance, priority, message): """ Sends a general live migration notification to the GUI :param context: security context :param instance: The instance that was migrating :param priority: The level of message (DEBUG, WARN, INFO, ERROR, CRITICAL) :param message: The message to print """ # Send event notification info = {'msg': '{message}', 'instance_id': instance['uuid'], 'instance_name': instance['display_name'], 'message': message} notifier = rpc.get_notifier(service='compute', host=CONF.host) if priority == 'error': notifier.error(context, 'compute.instance.log', info) elif priority == 'info': notifier.info(context, 'compute.instance.log', info) elif priority == 'critical': notifier.critical(context, 'compute.instance.log', info) elif priority == 'warn': notifier.warn(context, 'compute.instance.log', info) elif priority == 'debug': notifier.debug(context, 'compute.instance.log', info)
def set_vm_state_and_notify(context, instance_uuid, service, method, updates, ex, request_spec): """changes VM state and notifies.""" LOG.warning(_LW("Failed to %(service)s_%(method)s: %(ex)s"), {'service': service, 'method': method, 'ex': ex}) vm_state = updates['vm_state'] properties = request_spec.get('instance_properties', {}) # NOTE(vish): We shouldn't get here unless we have a catastrophic # failure, so just set the instance to its internal state notifier = rpc.get_notifier(service) state = vm_state.upper() LOG.warning(_LW('Setting instance to %s state.'), state, instance_uuid=instance_uuid) instance = objects.Instance(context=context, uuid=instance_uuid, **updates) instance.obj_reset_changes(['uuid']) instance.save() compute_utils.add_instance_fault_from_exc(context, instance, ex, sys.exc_info()) payload = dict(request_spec=request_spec, instance_properties=properties, instance_id=instance_uuid, state=vm_state, method=method, reason=ex) event_type = '%s.%s' % (service, method) notifier.error(context, event_type, payload)
def send_migration_failure_notification(context, instance, tgt_host, exception): """ Sends a notification of live migration failure to the GUI :param context: security context :param instance: The instance that was migrating :param tgt_host: The target host name :param exception: The exception that was thrown """ if hasattr(exception, 'message'): err_msg = _('%s') % exception.message else: err_msg = _('%s') % exception # Send error notification info = {'msg': _('Migration of virtual machine {instance_name} ' 'to host {host_name} failed. ' '{error}'), 'instance_id': instance['uuid'], 'instance_name': instance['display_name'], 'host_name': tgt_host, 'error': err_msg} notifier = rpc.get_notifier(service='compute', host=CONF.host) notifier.error(context, 'compute.instance.log', info)
def test_wrap_exception_with_notifier(self): wrapped = exception_wrapper.wrap_exception(rpc.get_notifier('fake'), binary='fake-binary') ctxt = context.get_admin_context() self.assertRaises(test.TestingException, wrapped(bad_function_exception), 1, ctxt, 3, zoo=3) self.assertEqual(1, len(fake_notifier.NOTIFICATIONS)) notification = fake_notifier.NOTIFICATIONS[0] self.assertEqual('bad_function_exception', notification.event_type) self.assertEqual(ctxt, notification.context) self.assertEqual(3, notification.payload['args']['extra']) for key in ['exception', 'args']: self.assertIn(key, notification.payload.keys()) self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS)) notification = fake_notifier.VERSIONED_NOTIFICATIONS[0] self.assertEqual('compute.exception', notification['event_type']) self.assertEqual('fake-binary:fake-mini', notification['publisher_id']) self.assertEqual('ERROR', notification['priority']) payload = notification['payload'] self.assertEqual('ExceptionPayload', payload['nova_object.name']) self.assertEqual('1.0', payload['nova_object.version']) payload = payload['nova_object.data'] self.assertEqual('TestingException', payload['exception']) self.assertEqual('bad things happened', payload['exception_message']) self.assertEqual('bad_function_exception', payload['function_name']) self.assertEqual('nova.tests.unit.test_exception', payload['module_name'])
def __init__(self): super(ComputeTaskManager, self).__init__() self.compute_rpcapi = compute_rpcapi.ComputeAPI() self.image_api = image.API() self.servicegroup_api = servicegroup.API() self.scheduler_client = scheduler_client.SchedulerClient() self.notifier = rpc.get_notifier('compute', CONF.host)
def __init__(self, *args, **kwargs): super(FilterScheduler, self).__init__(*args, **kwargs) self.options = scheduler_options.SchedulerOptions() self.compute_rpcapi = compute_rpcapi.ComputeAPI() self.notifier = rpc.get_notifier("scheduler") self._supports_affinity = scheduler_utils.validate_filter("ServerGroupAffinityFilter") self._supports_anti_affinity = scheduler_utils.validate_filter("ServerGroupAntiAffinityFilter")
def test_set_vm_state_and_notify_adds_instance_fault(self): request = {"instance_properties": {"uuid": "fake-uuid"}} updates = {"vm_state": "foo"} fake_inst = {"uuid": "fake-uuid"} self.mox.StubOutWithMock(db, "instance_update_and_get_original") self.mox.StubOutWithMock(db, "instance_fault_create") self.mox.StubOutWithMock(rpc, "get_notifier") notifier = self.mox.CreateMockAnything() rpc.get_notifier("conductor", CONF.host).AndReturn(notifier) rpc.get_notifier("scheduler").AndReturn(notifier) db.instance_update_and_get_original(self.context, "fake-uuid", updates).AndReturn((None, fake_inst)) db.instance_fault_create(self.context, mox.IgnoreArg()) notifier.error(self.context, "scheduler.foo", mox.IgnoreArg()) self.mox.ReplayAll() self.manager._set_vm_state_and_notify("foo", {"vm_state": "foo"}, self.context, None, request)
def get_connection(self): """Returns a connection to the hypervisor This method should be used to create and return a well configured connection to the hypervisor. :returns: a libvirt.virConnect object """ try: conn = self._get_connection() except libvirt.libvirtError as ex: LOG.exception(_LE("Connection to libvirt failed: %s"), ex) payload = dict(ip=CONF.my_ip, method="_connect", reason=ex) rpc.get_notifier("compute").error(nova_context.get_admin_context(), "compute.libvirt.error", payload) raise exception.HypervisorUnavailable(host=CONF.host) return conn
def test_handle_schedule_error_adds_instance_fault(self): instance = {'uuid': 'fake-uuid'} self.mox.StubOutWithMock(db, 'instance_update_and_get_original') self.mox.StubOutWithMock(db, 'instance_fault_create') db.instance_update_and_get_original(self.context, instance['uuid'], mox.IgnoreArg()).AndReturn( (None, instance)) db.instance_fault_create(self.context, mox.IgnoreArg()).AndReturn( test_instance_fault.fake_faults['fake-uuid'][0]) self.mox.StubOutWithMock(rpc, 'get_notifier') notifier = self.mox.CreateMockAnything() rpc.get_notifier('scheduler').AndReturn(notifier) notifier.error(self.context, 'scheduler.run_instance', mox.IgnoreArg()) self.mox.ReplayAll() driver.handle_schedule_error(self.context, exception.NoValidHost('test'), instance['uuid'], {})
def notify_about_server_group_update(context, event_suffix, sg_payload): """Send a notification about server group update. :param event_suffix: Event type like "create.start" or "create.end" :param sg_payload: payload for server group update """ notifier = rpc.get_notifier(service='servergroup') notifier.info(context, 'servergroup.%s' % event_suffix, sg_payload)
def __init__(self, host=None, db_driver=None, service_name='undefined'): if not host: host = CONF.host self.host = host self.backdoor_port = None self.service_name = service_name self.notifier = rpc.get_notifier(self.service_name, self.host) self.additional_endpoints = [] super(Manager, self).__init__(db_driver)
def _notify(exception_msg=None): payload = {} payload['msg'] = '' payload['instance_id'] = lpar_uuid payload['instance_name'] = lpar_name payload['host_name'] = CONF.host_display_name if volume_id is not None: payload['volume_id'] = volume_id notifier = rpc.get_notifier(service='compute', host=CONF.host) try: if migrate_op: payload['source_host_name'] = source_host payload['target_host_name'] = target_host if exception_msg is not None: if error_message is not None: payload['msg'] = error_message payload['error'] = exception_msg if log_exception: try: # Convert the brackets to replacement # variables log_exception_msg = error_message.replace( "{", "%(").replace("}", ")s") LOG.exception(log_exception_msg % payload) except Exception as exc: LOG.debug('LOG.exception failed with ' 'exception: %s' % exc) if error_event_type is EVENT_TYPE_ERROR: notifier.error(context, 'compute.instance.log', payload) elif error_event_type is EVENT_TYPE_WARN: notifier.warn(context, 'compute.instance.log', payload) else: LOG.debug('Exception was handled, but the ' 'error_event_type parameter was not ' 'set to a supported value. No GUI ' 'notification sent.') else: LOG.debug('Operation failed, but no error_message ' 'was provided. No GUI notification ' 'sent.') else: if success_message is not None: payload['msg'] = success_message notifier.info(context, 'compute.instance.log', payload) else: LOG.debug('Operation completed successfully, but ' 'no success_message was provided. No GUI' ' notification sent.') except Exception as exc: LOG.debug('Notify failed with exception: %s' % exc)
def test_notify_about_instance_usage(self): instance_id = self._create_instance() instance = objects.Instance.get_by_id( self.context, instance_id, expected_attrs=['metadata', 'system_metadata', 'info_cache']) # Set some system metadata sys_metadata = { 'image_md_key1': 'val1', 'image_md_key2': 'val2', 'other_data': 'meow' } instance.system_metadata.update(sys_metadata) instance.save() extra_usage_info = {'image_name': 'fake_name'} compute_utils.notify_about_instance_usage( rpc.get_notifier('compute'), self.context, instance, 'create.start', extra_usage_info=extra_usage_info) self.assertEqual(len(fake_notifier.NOTIFICATIONS), 1) msg = fake_notifier.NOTIFICATIONS[0] self.assertEqual(msg.priority, 'INFO') self.assertEqual(msg.event_type, 'compute.instance.create.start') payload = msg.payload self.assertEqual(payload['tenant_id'], self.project_id) self.assertEqual(payload['user_id'], self.user_id) self.assertEqual(payload['instance_id'], instance['uuid']) self.assertEqual(payload['instance_type'], 'm1.tiny') type_id = flavors.get_flavor_by_name('m1.tiny')['id'] self.assertEqual(str(payload['instance_type_id']), str(type_id)) flavor_id = flavors.get_flavor_by_name('m1.tiny')['flavorid'] self.assertEqual(str(payload['instance_flavor_id']), str(flavor_id)) for attr in ('display_name', 'created_at', 'launched_at', 'state', 'state_description', 'image_meta'): self.assertIn(attr, payload, "Key %s not in payload" % attr) self.assertEqual(payload['image_meta'], { 'md_key1': 'val1', 'md_key2': 'val2' }) self.assertEqual(payload['image_name'], 'fake_name') image_ref_url = "%s/images/1" % glance.generate_glance_url() self.assertEqual(payload['image_ref_url'], image_ref_url) self.compute.terminate_instance(self.context, instance, [], [])
def set_vm_state_and_notify(context, service, method, updates, ex, request_spec, db): """changes VM state and notifies.""" LOG.warning(_LW("Failed to %(service)s_%(method)s: %(ex)s"), { 'service': service, 'method': method, 'ex': ex }) vm_state = updates['vm_state'] properties = request_spec.get('instance_properties', {}) # NOTE(vish): We shouldn't get here unless we have a catastrophic # failure, so just set all instances to error. if uuid # is not set, instance_uuids will be set to [None], this # is solely to preserve existing behavior and can # be removed along with the 'if instance_uuid:' if we can # verify that uuid is always set. uuids = [properties.get('uuid')] notifier = rpc.get_notifier(service) for instance_uuid in request_spec.get('instance_uuids') or uuids: if instance_uuid: state = vm_state.upper() LOG.warning(_LW('Setting instance to %s state.'), state, instance_uuid=instance_uuid) # update instance state and notify on the transition (old_ref, new_ref) = db.instance_update_and_get_original( context, instance_uuid, updates) notifications.send_update(context, old_ref, new_ref, service=service) compute_utils.add_instance_fault_from_exc(context, new_ref, ex, sys.exc_info()) payload = dict(request_spec=request_spec, instance_properties=properties, instance_id=instance_uuid, state=vm_state, method=method, reason=ex) event_type = '%s.%s' % (service, method) notifier.error(context, event_type, payload)
def test_notify_usage_exists_deleted_instance(self): # Ensure 'exists' notification generates appropriate usage data. instance_id = self._create_instance() instance = objects.Instance.get_by_id( self.context, instance_id, expected_attrs=['metadata', 'system_metadata', 'info_cache']) # Set some system metadata sys_metadata = { 'image_md_key1': 'val1', 'image_md_key2': 'val2', 'other_data': 'meow' } instance.system_metadata.update(sys_metadata) instance.save() self.compute.terminate_instance(self.context, instance, [], []) instance = objects.Instance.get_by_id( self.context.elevated(read_deleted='yes'), instance_id, expected_attrs=['system_metadata']) compute_utils.notify_usage_exists(rpc.get_notifier('compute'), self.context, instance) msg = fake_notifier.NOTIFICATIONS[-1] self.assertEqual(msg.priority, 'INFO') self.assertEqual(msg.event_type, 'compute.instance.exists') payload = msg.payload self.assertEqual(payload['tenant_id'], self.project_id) self.assertEqual(payload['user_id'], self.user_id) self.assertEqual(payload['instance_id'], instance['uuid']) self.assertEqual(payload['instance_type'], 'm1.tiny') type_id = flavors.get_flavor_by_name('m1.tiny')['id'] self.assertEqual(str(payload['instance_type_id']), str(type_id)) flavor_id = flavors.get_flavor_by_name('m1.tiny')['flavorid'] self.assertEqual(str(payload['instance_flavor_id']), str(flavor_id)) for attr in ('display_name', 'created_at', 'launched_at', 'state', 'state_description', 'bandwidth', 'audit_period_beginning', 'audit_period_ending', 'image_meta'): self.assertIn(attr, payload, "Key %s not in payload" % attr) self.assertEqual(payload['image_meta'], { 'md_key1': 'val1', 'md_key2': 'val2' }) image_ref_url = "%s/images/1" % glance.generate_glance_url() self.assertEqual(payload['image_ref_url'], image_ref_url)
def __init__(self, host, driver, nodename): self.host = host self.driver = driver self.pci_tracker = None self.pci_filter = pci_whitelist.get_pci_devices_filter() self.nodename = nodename self.compute_node = None self.stats = importutils.import_object(CONF.compute_stats_class) self.tracked_instances = {} self.tracked_migrations = {} self.conductor_api = conductor.API() monitor_handler = monitors.ResourceMonitorHandler() self.monitors = monitor_handler.choose_monitors(self) self.ext_resources_handler = \ ext_resources.ResourceHandler(CONF.compute_resources) self.notifier = rpc.get_notifier() self.old_resources = {} self.scheduler_client = scheduler_client.SchedulerClient()
def notify_about_aggregate_update(context, event_suffix, aggregate_payload): """Send a notification about aggregate update. :param event_suffix: Event type like "create.start" or "create.end" :param aggregate_payload: payload for aggregate update """ aggregate_identifier = aggregate_payload.get('aggregate_id', None) if not aggregate_identifier: aggregate_identifier = aggregate_payload.get('name', None) if not aggregate_identifier: LOG.debug("No aggregate id or name specified for this " "notification and it will be ignored") return notifier = rpc.get_notifier(service='aggregate', host=aggregate_identifier) notifier.info(context, 'aggregate.%s' % event_suffix, aggregate_payload)
def notify_about_host_update(context, event_suffix, host_payload): """Send a notification about host update. :param event_suffix: Event type like "create.start" or "create.end" :param host_payload: payload for host update. It is a dict and there should be at least the 'host_name' key in this dict. """ host_identifier = host_payload.get('host_name') if not host_identifier: LOG.warn( _("No host name specified for the notification of " "HostAPI.%s and it will be ignored"), event_suffix) return notifier = rpc.get_notifier(service='api', host=host_identifier) notifier.info(context, 'HostAPI.%s' % event_suffix, host_payload)
def wrapped_func(*args, **kwarg): body = {} body['args'] = [] body['kwarg'] = {} for arg in args: body['args'].append(arg) for key in kwarg: body['kwarg'][key] = kwarg[key] ctxt = common_context.get_context_from_function_and_args( fn, args, kwarg) notifier = rpc.get_notifier( publisher_id=(CONF.default_publisher_id or CONF.host)) method = notifier.getattr(CONF.default_notification_level.lower(), 'info') method(ctxt, name, body) return fn(*args, **kwarg)
def _get_host_metrics(self, context, nodename): """Get the metrics from monitors and notify information to message bus. """ metrics = [] metrics_info = {} for monitor in self.monitors: try: metrics += monitor.get_metrics(nodename=nodename) except Exception: LOG.warn(_("Cannot get the metrics from %s."), monitors) if metrics: metrics_info['nodename'] = nodename metrics_info['metrics'] = metrics metrics_info['host'] = self.host metrics_info['host_ip'] = CONF.my_ip notifier = rpc.get_notifier(service='compute', host=nodename) notifier.info(context, 'compute.metrics.update', metrics_info) return metrics
def set_vm_state_and_notify(context, instance_uuid, service, method, updates, ex, request_spec, db): """changes VM state and notifies.""" LOG.warning(_LW("Failed to %(service)s_%(method)s: %(ex)s"), { 'service': service, 'method': method, 'ex': ex }) vm_state = updates['vm_state'] properties = request_spec.get('instance_properties', {}) # NOTE(vish): We shouldn't get here unless we have a catastrophic # failure, so just set the instance to its internal state notifier = rpc.get_notifier(service) state = vm_state.upper() LOG.warning(_LW('Setting instance to %s state.'), state, instance_uuid=instance_uuid) # update instance state and notify on the transition # NOTE(hanlind): the send_update() call below is going to want to # know about the flavor, so we need to join the appropriate things # here and objectify the results. (old_ref, new_ref) = db.instance_update_and_get_original( context, instance_uuid, updates, columns_to_join=['system_metadata']) inst_obj = objects.Instance._from_db_object( context, objects.Instance(), new_ref, expected_attrs=['system_metadata']) notifications.send_update(context, old_ref, inst_obj, service=service) compute_utils.add_instance_fault_from_exc(context, new_ref, ex, sys.exc_info()) payload = dict(request_spec=request_spec, instance_properties=properties, instance_id=instance_uuid, state=vm_state, method=method, reason=ex) event_type = '%s.%s' % (service, method) notifier.error(context, event_type, payload)
def wrapped_func(*args, **kwarg): body = {} body['args'] = [] body['kwarg'] = {} for arg in args: body['args'].append(arg) for key in kwarg: body['kwarg'][key] = kwarg[key] ctxt = (common_context.get_context_from_function_and_args( fn, args, kwarg) or common_context.get_current() or nova.context.RequestContext()) notifier = rpc.get_notifier('api', publisher_id=(CONF.default_publisher_id or CONF.host)) method = getattr(notifier, CONF.default_notification_level.lower(), notifier.info) method(ctxt, name, body) return fn(*args, **kwarg)
def _get_host_metrics(self, context, nodename): """Get the metrics from monitors and notify information to message bus. """ metrics = objects.MonitorMetricList() metrics_info = {} for monitor in self.monitors: try: monitor.add_metrics_to_list(metrics) except Exception: LOG.warning(_LW("Cannot get the metrics from %s."), monitor) # TODO(jaypipes): Remove this when compute_node.metrics doesn't need # to be populated as a JSON-ified string. metrics = metrics.to_list() if len(metrics): metrics_info['nodename'] = nodename metrics_info['metrics'] = metrics metrics_info['host'] = self.host metrics_info['host_ip'] = CONF.my_ip notifier = rpc.get_notifier(service='compute', host=nodename) notifier.info(context, 'compute.metrics.update', metrics_info) return metrics
def test_wrap_exception_with_notifier(self): wrapped = exception_wrapper.wrap_exception(rpc.get_notifier('fake'), binary='nova-compute') ctxt = context.get_admin_context() self.assertRaises(test.TestingException, wrapped(bad_function_exception), 1, ctxt, 3, zoo=3) self.assertEqual(1, len(fake_notifier.NOTIFICATIONS)) notification = fake_notifier.NOTIFICATIONS[0] self.assertEqual('bad_function_exception', notification.event_type) self.assertEqual(ctxt, notification.context) self.assertEqual(3, notification.payload['args']['extra']) for key in ['exception', 'args']: self.assertIn(key, notification.payload.keys()) self.assertNotIn('context', notification.payload['args'].keys()) self.assertEqual(1, len(fake_notifier.VERSIONED_NOTIFICATIONS)) notification = fake_notifier.VERSIONED_NOTIFICATIONS[0] self.assertEqual('compute.exception', notification['event_type']) self.assertEqual('nova-compute:fake-mini', notification['publisher_id']) self.assertEqual('ERROR', notification['priority']) payload = notification['payload'] self.assertEqual('ExceptionPayload', payload['nova_object.name']) self.assertEqual('1.1', payload['nova_object.version']) payload = payload['nova_object.data'] self.assertEqual('TestingException', payload['exception']) self.assertEqual('bad things happened', payload['exception_message']) self.assertEqual('bad_function_exception', payload['function_name']) self.assertEqual('nova.tests.unit.test_exception', payload['module_name']) self.assertIn('bad_function_exception', payload['traceback'])
def __init__(self): super(ComputeTaskManager, self).__init__() self.compute_rpcapi = compute_rpcapi.ComputeAPI() self.image_api = image.API() self.scheduler_client = scheduler_client.SchedulerClient() self.notifier = rpc.get_notifier('compute', CONF.host)
def __init__(self, *args, **kwargs): super(FilterScheduler, self).__init__(*args, **kwargs) self.notifier = rpc.get_notifier('scheduler') scheduler_client = client.SchedulerClient() self.placement_client = scheduler_client.reportclient
def _emit_legacy_exception_notification( context, exception, service, function_name, args, ): notifier = rpc.get_notifier(service) payload = {'exception': exception, 'args': args} notifier.error(context, function_name, payload)
def __init__(self, *args, **kwargs): super(FilterScheduler, self).__init__(*args, **kwargs) self.notifier = rpc.get_notifier('scheduler')
def __init__(self, *args, **kwargs): super(FilterScheduler, self).__init__(*args, **kwargs) self.options = scheduler_options.SchedulerOptions() self.compute_rpcapi = compute_rpcapi.ComputeAPI() self.notifier = rpc.get_notifier('scheduler')
def test_wrap_exception_good_return(self): wrapped = exception_wrapper.wrap_exception(rpc.get_notifier('fake')) self.assertEqual(99, wrapped(good_function)(1, 2)) self.assertEqual(0, len(fake_notifier.NOTIFICATIONS)) self.assertEqual(0, len(fake_notifier.VERSIONED_NOTIFICATIONS))