Target context for build notification in conductor
When sending notifications about an instance, it's possible the notification payload will have attributes not already loaded on the instance. In this case, a lazy-load will happen and if the load method needs to lookup the instance (example: in the _check_instance_exists_in_project method in the DB layer), the InstanceNotFound exception will be raised and the notification will fail to be sent. This targets the instance context to the instance's cell when calling the send notification method. Closes-Bug: #1721670 Change-Id: I6b9eb120b6e7fcbf919a3791afe2d1f6a7bd3b60
This commit is contained in:
parent
ec4e970412
commit
54cf9f5a90
|
@ -1109,12 +1109,14 @@ class ComputeTaskManager(base.Base):
|
|||
scheduler_utils.populate_retry(filter_props, instance.uuid)
|
||||
scheduler_utils.populate_filter_properties(filter_props,
|
||||
host)
|
||||
# send a state update notification for the initial create to
|
||||
# show it going from non-existent to BUILDING
|
||||
notifications.send_update_with_states(context, instance, None,
|
||||
vm_states.BUILDING, None, None, service="conductor")
|
||||
|
||||
# TODO(melwitt): Maybe we should set_target_cell on the contexts
|
||||
# once we map to a cell, and remove these separate with statements.
|
||||
with obj_target_cell(instance, cell) as cctxt:
|
||||
# send a state update notification for the initial create to
|
||||
# show it going from non-existent to BUILDING
|
||||
# This can lazy-load attributes on instance.
|
||||
notifications.send_update_with_states(cctxt, instance, None,
|
||||
vm_states.BUILDING, None, None, service="conductor")
|
||||
objects.InstanceAction.action_start(
|
||||
cctxt, instance.uuid, instance_actions.CREATE,
|
||||
want_result=False)
|
||||
|
|
|
@ -1454,7 +1454,22 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase):
|
|||
self.assertEqual(1, ephemeral[0].volume_size)
|
||||
return instance_uuid
|
||||
|
||||
def test_schedule_and_build_instances(self):
|
||||
@mock.patch('nova.notifications.send_update_with_states')
|
||||
def test_schedule_and_build_instances(self, mock_notify):
|
||||
# NOTE(melwitt): This won't work with call_args because the call
|
||||
# arguments are recorded as references and not as copies of objects.
|
||||
# So even though the notify method was called with Instance._context
|
||||
# targeted, by the time we assert with call_args, the target_cell
|
||||
# context manager has already exited and the referenced Instance
|
||||
# object's _context.db_connection has been restored to None.
|
||||
def fake_notify(ctxt, instance, *args, **kwargs):
|
||||
# Assert the instance object is targeted when going through the
|
||||
# notification code.
|
||||
self.assertIsNotNone(ctxt.db_connection)
|
||||
self.assertIsNotNone(instance._context.db_connection)
|
||||
|
||||
mock_notify.side_effect = fake_notify
|
||||
|
||||
instance_uuid = self._do_schedule_and_build_instances_test(
|
||||
self.params)
|
||||
cells = objects.CellMappingList.get_all(self.ctxt)
|
||||
|
|
Loading…
Reference in New Issue