Merge "Transform instance.rebuild_scheduled notification"

This commit is contained in:
Zuul 2018-07-14 17:20:16 +00:00 committed by Gerrit Code Review
commit 039f7e055e
13 changed files with 83 additions and 32 deletions

View File

@ -1,6 +1,8 @@
{ {
"$ref": "InstanceActionPayload.json", "$ref": "InstanceActionPayload.json",
"nova_object.data": { "nova_object.data": {
"architecture": null,
"image_uuid": "a2459075-d96c-40d5-893e-577ff92e721c",
"trusted_image_certificates": [ "trusted_image_certificates": [
"rebuild-cert-id-1", "rebuild-cert-id-1",
"rebuild-cert-id-2" "rebuild-cert-id-2"

View File

@ -1,12 +1,6 @@
{ {
"event_type": "instance.rebuild.end", "event_type": "instance.rebuild.end",
"publisher_id": "nova-compute:compute", "publisher_id": "nova-compute:compute",
"payload": { "payload": {"$ref": "common_payloads/InstanceActionRebuildPayload.json#"},
"$ref":"common_payloads/InstanceActionRebuildPayload.json#",
"nova_object.data": {
"architecture": null,
"image_uuid": "a2459075-d96c-40d5-893e-577ff92e721c"
}
},
"priority": "INFO" "priority": "INFO"
} }

View File

@ -15,8 +15,6 @@
"nova_object.version": "1.1", "nova_object.version": "1.1",
"nova_object.namespace": "nova" "nova_object.namespace": "nova"
}, },
"architecture": null,
"image_uuid": "a2459075-d96c-40d5-893e-577ff92e721c",
"task_state": "rebuilding" "task_state": "rebuilding"
} }
}, },

View File

@ -3,10 +3,8 @@
"event_type": "instance.rebuild.start", "event_type": "instance.rebuild.start",
"publisher_id": "nova-compute:compute", "publisher_id": "nova-compute:compute",
"payload": { "payload": {
"$ref":"common_payloads/InstanceActionRebuildPayload.json#", "$ref": "common_payloads/InstanceActionRebuildPayload.json#",
"nova_object.data": { "nova_object.data": {
"architecture": null,
"image_uuid": "a2459075-d96c-40d5-893e-577ff92e721c",
"task_state": "rebuilding" "task_state": "rebuilding"
} }
} }

View File

@ -0,0 +1,11 @@
{
"priority": "INFO",
"event_type": "instance.rebuild_scheduled",
"publisher_id": "nova-conductor:compute",
"payload": {
"$ref": "common_payloads/InstanceActionRebuildPayload.json#",
"nova_object.data": {
"task_state": "rebuilding"
}
}
}

View File

@ -723,13 +723,18 @@ def notify_about_server_group_add_member(context, group_id):
@rpc.if_notifications_enabled @rpc.if_notifications_enabled
def notify_about_instance_rebuild(context, instance, host, phase=None, def notify_about_instance_rebuild(context, instance, host,
action=fields.NotificationAction.REBUILD,
phase=None,
source=fields.NotificationSource.COMPUTE,
exception=None, bdms=None, tb=None): exception=None, bdms=None, tb=None):
"""Send versioned notification about instance rebuild """Send versioned notification about instance rebuild
: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
:param action: the name of the action
:param phase: the phase of the action :param phase: the phase of the action
:param source: the source of the notification
:param exception: the thrown exception (used in error notifications) :param exception: the thrown exception (used in error notifications)
:param bdms: BlockDeviceMappingList object for the instance. If it is not :param bdms: BlockDeviceMappingList object for the instance. If it is not
provided then we will load it from the db if so configured provided then we will load it from the db if so configured
@ -745,10 +750,10 @@ def notify_about_instance_rebuild(context, instance, host, phase=None,
context=context, context=context,
priority=priority, priority=priority,
publisher=notification_base.NotificationPublisher( publisher=notification_base.NotificationPublisher(
host=host, source=fields.NotificationSource.COMPUTE), host=host, source=source),
event_type=notification_base.EventType( event_type=notification_base.EventType(
object='instance', object='instance',
action=fields.NotificationAction.REBUILD, action=action,
phase=phase), phase=phase),
payload=payload) payload=payload)
notification.emit(context) notification.emit(context)

View File

@ -45,6 +45,7 @@ from nova import network
from nova import notifications from nova import notifications
from nova import objects from nova import objects
from nova.objects import base as nova_object from nova.objects import base as nova_object
from nova.objects import fields
from nova import profiler from nova import profiler
from nova import rpc from nova import rpc
from nova.scheduler import client as scheduler_client from nova.scheduler import client as scheduler_client
@ -975,6 +976,10 @@ class ComputeTaskManager(base.Base):
compute_utils.notify_about_instance_usage( compute_utils.notify_about_instance_usage(
self.notifier, context, instance, "rebuild.scheduled") self.notifier, context, instance, "rebuild.scheduled")
compute_utils.notify_about_instance_rebuild(
context, instance, host,
action=fields.NotificationAction.REBUILD_SCHEDULED,
source=fields.NotificationSource.CONDUCTOR)
instance.availability_zone = ( instance.availability_zone = (
availability_zones.get_host_availability_zone( availability_zones.get_host_availability_zone(

View File

@ -59,7 +59,9 @@ class EventType(NotificationObject):
# NotificationActionField enum # NotificationActionField enum
# Version 1.11: LOCK is added to NotificationActionField enum # Version 1.11: LOCK is added to NotificationActionField enum
# Version 1.12: UNLOCK is added to NotificationActionField enum # Version 1.12: UNLOCK is added to NotificationActionField enum
VERSION = '1.12' # Version 1.13: REBUILD_SCHEDULED value is added to the
# NotificationActionField enum
VERSION = '1.13'
fields = { fields = {
'object': fields.StringField(nullable=False), 'object': fields.StringField(nullable=False),

View File

@ -660,6 +660,7 @@ class InstanceActionRescueNotification(base.NotificationBase):
} }
@base.notification_sample('instance-rebuild_scheduled.json')
@base.notification_sample('instance-rebuild-start.json') @base.notification_sample('instance-rebuild-start.json')
@base.notification_sample('instance-rebuild-end.json') @base.notification_sample('instance-rebuild-end.json')
@base.notification_sample('instance-rebuild-error.json') @base.notification_sample('instance-rebuild-error.json')

View File

@ -808,6 +808,7 @@ class NotificationAction(BaseNovaEnum):
LIVE_MIGRATION_ROLLBACK_DEST = 'live_migration_rollback_dest' LIVE_MIGRATION_ROLLBACK_DEST = 'live_migration_rollback_dest'
LIVE_MIGRATION_ROLLBACK = 'live_migration_rollback' LIVE_MIGRATION_ROLLBACK = 'live_migration_rollback'
REBUILD = 'rebuild' REBUILD = 'rebuild'
REBUILD_SCHEDULED = 'rebuild_scheduled'
INTERFACE_DETACH = 'interface_detach' INTERFACE_DETACH = 'interface_detach'
RESIZE_CONFIRM = 'resize_confirm' RESIZE_CONFIRM = 'resize_confirm'
RESIZE_PREP = 'resize_prep' RESIZE_PREP = 'resize_prep'
@ -833,7 +834,8 @@ class NotificationAction(BaseNovaEnum):
LIVE_MIGRATION_ROLLBACK_DEST, REBUILD, INTERFACE_DETACH, LIVE_MIGRATION_ROLLBACK_DEST, REBUILD, INTERFACE_DETACH,
RESIZE_CONFIRM, RESIZE_PREP, RESIZE_REVERT, SHELVE_OFFLOAD, RESIZE_CONFIRM, RESIZE_PREP, RESIZE_REVERT, SHELVE_OFFLOAD,
SOFT_DELETE, TRIGGER_CRASH_DUMP, UNRESCUE, UNSHELVE, ADD_HOST, SOFT_DELETE, TRIGGER_CRASH_DUMP, UNRESCUE, UNSHELVE, ADD_HOST,
REMOVE_HOST, ADD_MEMBER, UPDATE_METADATA, LOCK, UNLOCK) REMOVE_HOST, ADD_MEMBER, UPDATE_METADATA, LOCK, UNLOCK,
REBUILD_SCHEDULED)
# TODO(rlrossit): These should be changed over to be a StateMachine enum from # TODO(rlrossit): These should be changed over to be a StateMachine enum from

View File

@ -1042,15 +1042,28 @@ class TestInstanceNotificationSample(
self._wait_for_state_change(self.api, server, self._wait_for_state_change(self.api, server,
expected_status='ACTIVE') expected_status='ACTIVE')
# 0. instance.rebuild_scheduled
# 1. instance.exists
# 2. instance.rebuild.start
# 3. instance.detach.start
# 4. instance.detach.end
# 5. instance.rebuild.end
# The compute/manager will detach every volume during rebuild # The compute/manager will detach every volume during rebuild
self.assertEqual(5, len(fake_notifier.VERSIONED_NOTIFICATIONS)) self.assertEqual(6, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self._verify_notification(
'instance-rebuild_scheduled',
replacements={
'reservation_id': server['reservation_id'],
'uuid': server['id'],
'trusted_image_certificates': None},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[0])
self._verify_notification( self._verify_notification(
'instance-rebuild-start', 'instance-rebuild-start',
replacements={ replacements={
'reservation_id': server['reservation_id'], 'reservation_id': server['reservation_id'],
'uuid': server['id'], 'uuid': server['id'],
'trusted_image_certificates': None}, 'trusted_image_certificates': None},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[1]) actual=fake_notifier.VERSIONED_NOTIFICATIONS[2])
self._verify_notification( self._verify_notification(
'instance-volume_detach-start', 'instance-volume_detach-start',
replacements={ replacements={
@ -1059,7 +1072,7 @@ class TestInstanceNotificationSample(
'architecture': None, 'architecture': None,
'image_uuid': 'a2459075-d96c-40d5-893e-577ff92e721c', 'image_uuid': 'a2459075-d96c-40d5-893e-577ff92e721c',
'uuid': server['id']}, 'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[2]) actual=fake_notifier.VERSIONED_NOTIFICATIONS[3])
self._verify_notification( self._verify_notification(
'instance-volume_detach-end', 'instance-volume_detach-end',
replacements={ replacements={
@ -1068,14 +1081,14 @@ class TestInstanceNotificationSample(
'architecture': None, 'architecture': None,
'image_uuid': 'a2459075-d96c-40d5-893e-577ff92e721c', 'image_uuid': 'a2459075-d96c-40d5-893e-577ff92e721c',
'uuid': server['id']}, 'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[3]) actual=fake_notifier.VERSIONED_NOTIFICATIONS[4])
self._verify_notification( self._verify_notification(
'instance-rebuild-end', 'instance-rebuild-end',
replacements={ replacements={
'reservation_id': server['reservation_id'], 'reservation_id': server['reservation_id'],
'uuid': server['id'], 'uuid': server['id'],
'trusted_image_certificates': None}, 'trusted_image_certificates': None},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[4]) actual=fake_notifier.VERSIONED_NOTIFICATIONS[5])
def test_rebuild_server_with_trusted_cert(self): def test_rebuild_server_with_trusted_cert(self):
# NOTE(gabor_antal): Rebuild changes the image used by the instance, # NOTE(gabor_antal): Rebuild changes the image used by the instance,
@ -1107,14 +1120,26 @@ class TestInstanceNotificationSample(
self._wait_for_state_change(self.api, server, self._wait_for_state_change(self.api, server,
expected_status='ACTIVE') expected_status='ACTIVE')
# 0. instance.rebuild_scheduled
# 1. instance.exists
# 2. instance.rebuild.start
# 3. instance.detach.start
# 4. instance.detach.end
# 5. instance.rebuild.end
# The compute/manager will detach every volume during rebuild # The compute/manager will detach every volume during rebuild
self.assertEqual(5, len(fake_notifier.VERSIONED_NOTIFICATIONS)) self.assertEqual(6, len(fake_notifier.VERSIONED_NOTIFICATIONS))
self._verify_notification(
'instance-rebuild_scheduled',
replacements={
'reservation_id': server['reservation_id'],
'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[0])
self._verify_notification( self._verify_notification(
'instance-rebuild-start', 'instance-rebuild-start',
replacements={ replacements={
'reservation_id': server['reservation_id'], 'reservation_id': server['reservation_id'],
'uuid': server['id']}, 'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[1]) actual=fake_notifier.VERSIONED_NOTIFICATIONS[2])
self._verify_notification( self._verify_notification(
'instance-volume_detach-start', 'instance-volume_detach-start',
replacements={ replacements={
@ -1123,7 +1148,7 @@ class TestInstanceNotificationSample(
'architecture': None, 'architecture': None,
'image_uuid': 'a2459075-d96c-40d5-893e-577ff92e721c', 'image_uuid': 'a2459075-d96c-40d5-893e-577ff92e721c',
'uuid': server['id']}, 'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[2]) actual=fake_notifier.VERSIONED_NOTIFICATIONS[3])
self._verify_notification( self._verify_notification(
'instance-volume_detach-end', 'instance-volume_detach-end',
replacements={ replacements={
@ -1132,13 +1157,13 @@ class TestInstanceNotificationSample(
'architecture': None, 'architecture': None,
'image_uuid': 'a2459075-d96c-40d5-893e-577ff92e721c', 'image_uuid': 'a2459075-d96c-40d5-893e-577ff92e721c',
'uuid': server['id']}, 'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[3]) actual=fake_notifier.VERSIONED_NOTIFICATIONS[4])
self._verify_notification( self._verify_notification(
'instance-rebuild-end', 'instance-rebuild-end',
replacements={ replacements={
'reservation_id': server['reservation_id'], 'reservation_id': server['reservation_id'],
'uuid': server['id']}, 'uuid': server['id']},
actual=fake_notifier.VERSIONED_NOTIFICATIONS[4]) actual=fake_notifier.VERSIONED_NOTIFICATIONS[5])
@mock.patch('nova.compute.manager.ComputeManager.' @mock.patch('nova.compute.manager.ComputeManager.'
'_do_rebuild_instance_with_claim') '_do_rebuild_instance_with_claim')
@ -1165,8 +1190,8 @@ class TestInstanceNotificationSample(
notification = self._get_notifications('instance.rebuild.error') notification = self._get_notifications('instance.rebuild.error')
self.assertEqual(1, len(notification)) self.assertEqual(1, len(notification))
tb = fake_notifier.VERSIONED_NOTIFICATIONS[0]['payload'][ tb = notification[0]['payload']['nova_object.data']['fault'][
'nova_object.data']['fault']['nova_object.data']['traceback'] 'nova_object.data']['traceback']
self.assertIn('raise exception.VirtualInterfaceCreateException()', tb) self.assertIn('raise exception.VirtualInterfaceCreateException()', tb)
self._verify_notification( self._verify_notification(

View File

@ -1255,7 +1255,8 @@ class _BaseTaskTestCase(object):
instance=inst_obj, instance=inst_obj,
**compute_args) **compute_args)
def test_rebuild_instance_with_scheduler(self): @mock.patch('nova.compute.utils.notify_about_instance_rebuild')
def test_rebuild_instance_with_scheduler(self, mock_notify):
inst_obj = self._create_fake_instance_obj() inst_obj = self._create_fake_instance_obj()
inst_obj.host = 'noselect' inst_obj.host = 'noselect'
expected_host = 'thebesthost' expected_host = 'thebesthost'
@ -1299,6 +1300,9 @@ class _BaseTaskTestCase(object):
self.assertEqual(inst_obj.project_id, fake_spec.project_id) self.assertEqual(inst_obj.project_id, fake_spec.project_id)
self.assertEqual('compute.instance.rebuild.scheduled', self.assertEqual('compute.instance.rebuild.scheduled',
fake_notifier.NOTIFICATIONS[0].event_type) fake_notifier.NOTIFICATIONS[0].event_type)
mock_notify.assert_called_once_with(
self.context, inst_obj, 'thebesthost', action='rebuild_scheduled',
source='nova-conductor')
def test_rebuild_instance_with_scheduler_no_host(self): def test_rebuild_instance_with_scheduler_no_host(self):
inst_obj = self._create_fake_instance_obj() inst_obj = self._create_fake_instance_obj()
@ -1414,7 +1418,8 @@ class _BaseTaskTestCase(object):
instance=inst_obj, instance=inst_obj,
**compute_args) **compute_args)
def test_rebuild_instance_with_request_spec(self): @mock.patch('nova.compute.utils.notify_about_instance_rebuild')
def test_rebuild_instance_with_request_spec(self, mock_notify):
inst_obj = self._create_fake_instance_obj() inst_obj = self._create_fake_instance_obj()
inst_obj.host = 'noselect' inst_obj.host = 'noselect'
expected_host = 'thebesthost' expected_host = 'thebesthost'
@ -1453,6 +1458,9 @@ class _BaseTaskTestCase(object):
**compute_args) **compute_args)
self.assertEqual('compute.instance.rebuild.scheduled', self.assertEqual('compute.instance.rebuild.scheduled',
fake_notifier.NOTIFICATIONS[0].event_type) fake_notifier.NOTIFICATIONS[0].event_type)
mock_notify.assert_called_once_with(
self.context, inst_obj, 'thebesthost', action='rebuild_scheduled',
source='nova-conductor')
class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):

View File

@ -370,7 +370,7 @@ notification_object_data = {
'AuditPeriodPayload': '1.0-2b429dd307b8374636703b843fa3f9cb', 'AuditPeriodPayload': '1.0-2b429dd307b8374636703b843fa3f9cb',
'BandwidthPayload': '1.0-ee2616a7690ab78406842a2b68e34130', 'BandwidthPayload': '1.0-ee2616a7690ab78406842a2b68e34130',
'BlockDevicePayload': '1.0-29751e1b6d41b1454e36768a1e764df8', 'BlockDevicePayload': '1.0-29751e1b6d41b1454e36768a1e764df8',
'EventType': '1.12-db573dfb0e85f269194dcd3b1628b0d2', 'EventType': '1.13-38edd755949d09025d66261f9ff46549',
'ExceptionNotification': '1.0-a73147b93b520ff0061865849d3dfa56', 'ExceptionNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
'ExceptionPayload': '1.1-6c43008bd81885a63bc7f7c629f0793b', 'ExceptionPayload': '1.1-6c43008bd81885a63bc7f7c629f0793b',
'FlavorNotification': '1.0-a73147b93b520ff0061865849d3dfa56', 'FlavorNotification': '1.0-a73147b93b520ff0061865849d3dfa56',