use already loaded BDM in instance.create

In I18e7483ec9a484a660e1d306fdc0986e1d5f952b BDM was added to the instance
notifications. In general to add BDM to the payload an exta DB query is
needed. However the BDM is already locaded before the
notify_about_instance_create is called to send the notification. In this cases
loading the BDM again is unnecessary as the already loaded BDM can be reused.

This patch makes sure that notify_about_instance_create is called with the
already loaded BDM.

The remaining instance related versioned notification calls does not have
BDM already loaded.

Change-Id: Ic25de45c18348206f0309da6d4997f4bf336acb2
Closes-Bug: #1718226
This commit is contained in:
Balazs Gibizer 2017-07-14 17:19:03 +02:00
parent 41a0f51341
commit ad33ae5771
4 changed files with 33 additions and 19 deletions

View File

@ -1933,7 +1933,8 @@ class ComputeManager(manager.Manager):
extra_usage_info={'image_name': image_name})
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.START)
phase=fields.NotificationPhase.START,
bdms=block_device_mapping)
# NOTE(mikal): cache the keystone roles associated with the instance
# at boot time for later reference
@ -1980,14 +1981,16 @@ class ComputeManager(manager.Manager):
'create.error', fault=e)
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.ERROR, exception=e)
phase=fields.NotificationPhase.ERROR, exception=e,
bdms=block_device_mapping)
except exception.ComputeResourcesUnavailable as e:
LOG.debug(e.format_message(), instance=instance)
self._notify_about_instance_usage(context, instance,
'create.error', fault=e)
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.ERROR, exception=e)
phase=fields.NotificationPhase.ERROR, exception=e,
bdms=block_device_mapping)
raise exception.RescheduledException(
instance_uuid=instance.uuid, reason=e.format_message())
except exception.BuildAbortException as e:
@ -1997,7 +2000,8 @@ class ComputeManager(manager.Manager):
'create.error', fault=e)
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.ERROR, exception=e)
phase=fields.NotificationPhase.ERROR, exception=e,
bdms=block_device_mapping)
except (exception.FixedIpLimitExceeded,
exception.NoMoreNetworks, exception.NoMoreFixedIps) as e:
LOG.warning('No more network or fixed IP to be allocated',
@ -2006,7 +2010,8 @@ class ComputeManager(manager.Manager):
'create.error', fault=e)
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.ERROR, exception=e)
phase=fields.NotificationPhase.ERROR, exception=e,
bdms=block_device_mapping)
msg = _('Failed to allocate the network(s) with error %s, '
'not rescheduling.') % e.format_message()
raise exception.BuildAbortException(instance_uuid=instance.uuid,
@ -2021,7 +2026,8 @@ class ComputeManager(manager.Manager):
'create.error', fault=e)
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.ERROR, exception=e)
phase=fields.NotificationPhase.ERROR, exception=e,
bdms=block_device_mapping)
msg = _('Failed to allocate the network(s), not rescheduling.')
raise exception.BuildAbortException(instance_uuid=instance.uuid,
reason=msg)
@ -2038,7 +2044,8 @@ class ComputeManager(manager.Manager):
'create.error', fault=e)
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.ERROR, exception=e)
phase=fields.NotificationPhase.ERROR, exception=e,
bdms=block_device_mapping)
raise exception.BuildAbortException(instance_uuid=instance.uuid,
reason=e.format_message())
except Exception as e:
@ -2046,7 +2053,8 @@ class ComputeManager(manager.Manager):
'create.error', fault=e)
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.ERROR, exception=e)
phase=fields.NotificationPhase.ERROR, exception=e,
bdms=block_device_mapping)
raise exception.RescheduledException(
instance_uuid=instance.uuid, reason=six.text_type(e))
@ -2080,14 +2088,16 @@ class ComputeManager(manager.Manager):
'create.error', fault=e)
compute_utils.notify_about_instance_create(
context, instance, self.host,
phase=fields.NotificationPhase.ERROR, exception=e)
phase=fields.NotificationPhase.ERROR, exception=e,
bdms=block_device_mapping)
self._update_scheduler_instance_info(context, instance)
self._notify_about_instance_usage(context, instance, 'create.end',
extra_usage_info={'message': _('Success')},
network_info=network_info)
compute_utils.notify_about_instance_create(context, instance,
self.host, phase=fields.NotificationPhase.END)
self.host, phase=fields.NotificationPhase.END,
bdms=block_device_mapping)
@contextlib.contextmanager
def _build_resources(self, context, instance, requested_networks,

View File

@ -384,7 +384,7 @@ def notify_about_instance_action(context, instance, host, action, phase=None,
@rpc.if_notifications_enabled
def notify_about_instance_create(context, instance, host, phase=None,
source=fields.NotificationSource.COMPUTE,
exception=None):
exception=None, bdms=None):
"""Send versioned notification about instance creation
:param context: the request context
@ -393,11 +393,14 @@ def notify_about_instance_create(context, instance, host, phase=None,
:param phase: the phase of the creation
:param source: the source of the notification
:param exception: the thrown exception (used in error notifications)
:param bdms: BlockDeviceMappingList object for the instance. If it is not
provided then we will load it from the db if so configured
"""
fault, priority = _get_fault_and_priority_from_exc(exception)
payload = instance_notification.InstanceCreatePayload(
instance=instance,
fault=fault)
fault=fault,
bdms=bdms)
notification = instance_notification.InstanceCreateNotification(
context=context,
priority=priority,

View File

@ -204,10 +204,11 @@ class InstanceCreatePayload(InstanceActionPayload):
'tags': fields.ListOfStringsField(),
}
def __init__(self, instance, fault):
def __init__(self, instance, fault, bdms):
super(InstanceCreatePayload, self).__init__(
instance=instance,
fault=fault)
instance=instance,
fault=fault,
bdms=bdms)
self.keypairs = [keypair_payload.KeypairPayload(keypair=keypair)
for keypair in instance.keypairs]
self.tags = [instance_tag.tag

View File

@ -4881,9 +4881,9 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
mock_notify.assert_has_calls([
mock.call(self.context, self.instance, 'fake-mini',
phase='start'),
phase='start', bdms=[]),
mock.call(self.context, self.instance, 'fake-mini',
phase='error', exception=exc)])
phase='error', exception=exc, bdms=[])])
save.assert_has_calls([
mock.call(),
@ -5348,9 +5348,9 @@ class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
mock_notify_instance_create.assert_has_calls([
mock.call(self.context, self.instance, 'fake-mini',
phase='start'),
phase='start', bdms=[]),
mock.call(self.context, self.instance, 'fake-mini',
phase='end')])
phase='end', bdms=[])])
def test_access_ip_set_when_instance_set_to_active(self):