Merge "Allow best effort sending of notifications"
This commit is contained in:
commit
7c2e79f762
@ -2261,11 +2261,12 @@ class ComputeManager(manager.Manager):
|
|||||||
|
|
||||||
def _notify_about_instance_usage(self, context, instance, event_suffix,
|
def _notify_about_instance_usage(self, context, instance, event_suffix,
|
||||||
network_info=None, extra_usage_info=None,
|
network_info=None, extra_usage_info=None,
|
||||||
fault=None):
|
fault=None, best_effort=False):
|
||||||
compute_utils.notify_about_instance_usage(
|
compute_utils.notify_about_instance_usage(
|
||||||
self.notifier, context, instance, event_suffix,
|
self.notifier, context, instance, event_suffix,
|
||||||
network_info=network_info,
|
network_info=network_info,
|
||||||
extra_usage_info=extra_usage_info, fault=fault)
|
extra_usage_info=extra_usage_info, fault=fault,
|
||||||
|
best_effort=best_effort)
|
||||||
|
|
||||||
def _deallocate_network(self, context, instance,
|
def _deallocate_network(self, context, instance,
|
||||||
requested_networks=None):
|
requested_networks=None):
|
||||||
@ -9358,11 +9359,12 @@ class ComputeManager(manager.Manager):
|
|||||||
|
|
||||||
self._notify_about_instance_usage(ctxt, instance,
|
self._notify_about_instance_usage(ctxt, instance,
|
||||||
"live_migration._post.start",
|
"live_migration._post.start",
|
||||||
network_info=network_info)
|
network_info=network_info,
|
||||||
|
best_effort=True)
|
||||||
compute_utils.notify_about_instance_action(
|
compute_utils.notify_about_instance_action(
|
||||||
ctxt, instance, self.host,
|
ctxt, instance, self.host,
|
||||||
action=fields.NotificationAction.LIVE_MIGRATION_POST,
|
action=fields.NotificationAction.LIVE_MIGRATION_POST,
|
||||||
phase=fields.NotificationPhase.START)
|
phase=fields.NotificationPhase.START, best_effort=True)
|
||||||
|
|
||||||
migration = objects.Migration(
|
migration = objects.Migration(
|
||||||
source_compute=self.host, dest_compute=dest,
|
source_compute=self.host, dest_compute=dest,
|
||||||
|
@ -406,7 +406,7 @@ def notify_usage_exists(notifier, context, instance_ref, host,
|
|||||||
|
|
||||||
def notify_about_instance_usage(notifier, context, instance, event_suffix,
|
def notify_about_instance_usage(notifier, context, instance, event_suffix,
|
||||||
network_info=None, extra_usage_info=None,
|
network_info=None, extra_usage_info=None,
|
||||||
fault=None):
|
fault=None, best_effort=False):
|
||||||
"""Send an unversioned legacy notification about an instance.
|
"""Send an unversioned legacy notification about an instance.
|
||||||
|
|
||||||
All new notifications should use notify_about_instance_action which sends
|
All new notifications should use notify_about_instance_action which sends
|
||||||
@ -435,7 +435,14 @@ def notify_about_instance_usage(notifier, context, instance, event_suffix,
|
|||||||
else:
|
else:
|
||||||
method = notifier.info
|
method = notifier.info
|
||||||
|
|
||||||
method(context, 'compute.instance.%s' % event_suffix, usage_info)
|
try:
|
||||||
|
method(context, 'compute.instance.%s' % event_suffix, usage_info)
|
||||||
|
except Exception as e:
|
||||||
|
if best_effort:
|
||||||
|
LOG.error('Exception during notification sending: %s. '
|
||||||
|
'Attempting to proceed with normal operation.', e)
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
def _get_fault_and_priority_from_exception(exception: Exception):
|
def _get_fault_and_priority_from_exception(exception: Exception):
|
||||||
@ -454,7 +461,7 @@ def _get_fault_and_priority_from_exception(exception: Exception):
|
|||||||
@rpc.if_notifications_enabled
|
@rpc.if_notifications_enabled
|
||||||
def notify_about_instance_action(context, instance, host, action, phase=None,
|
def notify_about_instance_action(context, instance, host, action, phase=None,
|
||||||
source=fields.NotificationSource.COMPUTE,
|
source=fields.NotificationSource.COMPUTE,
|
||||||
exception=None, bdms=None):
|
exception=None, bdms=None, best_effort=False):
|
||||||
"""Send versioned notification about the action made on the instance
|
"""Send versioned notification about the action made on the instance
|
||||||
:param instance: the instance which the action performed on
|
:param instance: the instance which the action performed on
|
||||||
:param host: the host emitting the notification
|
:param host: the host emitting the notification
|
||||||
@ -481,7 +488,14 @@ def notify_about_instance_action(context, instance, host, action, phase=None,
|
|||||||
action=action,
|
action=action,
|
||||||
phase=phase),
|
phase=phase),
|
||||||
payload=payload)
|
payload=payload)
|
||||||
notification.emit(context)
|
try:
|
||||||
|
notification.emit(context)
|
||||||
|
except Exception as e:
|
||||||
|
if best_effort:
|
||||||
|
LOG.error('Exception during notification sending: %s. '
|
||||||
|
'Attempting to proceed with normal operation.', e)
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
@rpc.if_notifications_enabled
|
@rpc.if_notifications_enabled
|
||||||
|
@ -255,7 +255,8 @@ class LiveMigrationNeutronInteractionsTest(
|
|||||||
the network_info from the instance info cache, and not Neutron.
|
the network_info from the instance info cache, and not Neutron.
|
||||||
"""
|
"""
|
||||||
def stub_notify(context, instance, event_suffix,
|
def stub_notify(context, instance, event_suffix,
|
||||||
network_info=None, extra_usage_info=None, fault=None):
|
network_info=None, extra_usage_info=None, fault=None,
|
||||||
|
best_effort=False):
|
||||||
vif = network_info[0]
|
vif = network_info[0]
|
||||||
# Make sure we have the correct VIF (the NeutronFixture
|
# Make sure we have the correct VIF (the NeutronFixture
|
||||||
# deterministically uses port_2 for networks=auto) and that the
|
# deterministically uses port_2 for networks=auto) and that the
|
||||||
|
@ -6675,7 +6675,8 @@ class ComputeTestCase(BaseTestCase,
|
|||||||
source_bdms=bdms)
|
source_bdms=bdms)
|
||||||
mock_notify.assert_has_calls([
|
mock_notify.assert_has_calls([
|
||||||
mock.call(c, instance, 'fake-mini',
|
mock.call(c, instance, 'fake-mini',
|
||||||
action='live_migration_post', phase='start'),
|
action='live_migration_post', phase='start',
|
||||||
|
best_effort=True),
|
||||||
mock.call(c, instance, 'fake-mini',
|
mock.call(c, instance, 'fake-mini',
|
||||||
action='live_migration_post', phase='end')])
|
action='live_migration_post', phase='end')])
|
||||||
self.assertEqual(2, mock_notify.call_count)
|
self.assertEqual(2, mock_notify.call_count)
|
||||||
|
@ -36,6 +36,7 @@ from nova import context
|
|||||||
from nova import exception
|
from nova import exception
|
||||||
from nova.image import glance
|
from nova.image import glance
|
||||||
from nova.network import model
|
from nova.network import model
|
||||||
|
from nova.notifications.objects import base as notifications_objects_base
|
||||||
from nova import objects
|
from nova import objects
|
||||||
from nova.objects import base
|
from nova.objects import base
|
||||||
from nova.objects import block_device as block_device_obj
|
from nova.objects import block_device as block_device_obj
|
||||||
@ -472,6 +473,31 @@ class UsageInfoTestCase(test.TestCase):
|
|||||||
glance.generate_glance_url(self.context), uuids.fake_image_ref)
|
glance.generate_glance_url(self.context), uuids.fake_image_ref)
|
||||||
self.assertEqual(payload['image_ref_url'], image_ref_url)
|
self.assertEqual(payload['image_ref_url'], image_ref_url)
|
||||||
|
|
||||||
|
def test_notify_about_instance_action_best_effort(self):
|
||||||
|
instance = create_instance(self.context)
|
||||||
|
bdms = block_device_obj.block_device_make_list(
|
||||||
|
self.context,
|
||||||
|
[fake_block_device.FakeDbBlockDeviceDict(
|
||||||
|
{'source_type': 'volume',
|
||||||
|
'device_name': '/dev/vda',
|
||||||
|
'instance_uuid': 'f8000000-0000-0000-0000-000000000000',
|
||||||
|
'destination_type': 'volume',
|
||||||
|
'boot_index': 0,
|
||||||
|
'volume_id': 'de8836ac-d75e-11e2-8271-5254009297d6'})])
|
||||||
|
with mock.patch.object(
|
||||||
|
notifications_objects_base.NotificationBase, 'emit',
|
||||||
|
side_effect=Exception()
|
||||||
|
) as mock_emit:
|
||||||
|
compute_utils.notify_about_instance_action(
|
||||||
|
self.context,
|
||||||
|
instance,
|
||||||
|
host='fake-compute',
|
||||||
|
action='delete',
|
||||||
|
phase='start',
|
||||||
|
bdms=bdms,
|
||||||
|
best_effort=True)
|
||||||
|
mock_emit.assert_called_once()
|
||||||
|
|
||||||
def test_notify_about_instance_action(self):
|
def test_notify_about_instance_action(self):
|
||||||
instance = create_instance(self.context)
|
instance = create_instance(self.context)
|
||||||
bdms = block_device_obj.block_device_make_list(
|
bdms = block_device_obj.block_device_make_list(
|
||||||
@ -873,6 +899,24 @@ class UsageInfoTestCase(test.TestCase):
|
|||||||
self.assertEqual(200, payload['write_bytes'])
|
self.assertEqual(200, payload['write_bytes'])
|
||||||
self.assertEqual(200, payload['writes'])
|
self.assertEqual(200, payload['writes'])
|
||||||
|
|
||||||
|
def test_notify_about_instance_usage_best_effort(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'}
|
||||||
|
notifier = rpc.get_notifier('compute')
|
||||||
|
with mock.patch.object(
|
||||||
|
notifier, 'info', side_effect=Exception()
|
||||||
|
) as mock_info:
|
||||||
|
compute_utils.notify_about_instance_usage(
|
||||||
|
notifier, self.context, instance, 'create.start',
|
||||||
|
extra_usage_info=extra_usage_info, best_effort=True)
|
||||||
|
mock_info.assert_called_once()
|
||||||
|
|
||||||
def test_notify_about_instance_usage(self):
|
def test_notify_about_instance_usage(self):
|
||||||
instance = create_instance(self.context)
|
instance = create_instance(self.context)
|
||||||
# Set some system metadata
|
# Set some system metadata
|
||||||
|
Loading…
Reference in New Issue
Block a user