Pass the correct image to build_request_spec in conductor.rebuild_instance

If we're calling build_request_spec in conductor.rebuild_instance,
it's because we are evacuating and the instance is so old it does
not have a request spec. We need the request_spec to pass to the
scheduler to pick a destination host for the evacuation.

For evacuate, nova-api does not pass any image reference parameters,
and even if it did, those are image IDs, not an image meta dict that
build_request_spec expects, so this code has just always been wrong.

This change fixes the problem by passing a primitive version of
the instance.image_meta which build_request_spec will then return
back to conductor and that gets used to build a RequestSpec object
from primitives.

It's important to use the correct image meta so that the scheduler
can properly filter hosts using things like the
AggregateImagePropertiesIsolation and ImagePropertiesFilter filters.

Conflicts:
      nova/conductor/manager.py

NOTE(mriedem): Conflict is due to e211fca55a
not being in Ocata.

Change-Id: I0c8ce65016287de7be921c312493667a8c7f762e
Closes-Bug: #1727855
(cherry picked from commit d2690d6b03)
(cherry picked from commit dc44c48943)
This commit is contained in:
Matt Riedemann 2017-10-26 17:33:35 -04:00
parent 31f214af4e
commit ea53d9f1ea
2 changed files with 7 additions and 1 deletions

View File

@ -712,8 +712,11 @@ class ComputeTaskManager(base.Base):
# RequestSpec object - probably because the instance is old
# We need to mock that the old way
filter_properties = {'ignore_hosts': [instance.host]}
# build_request_spec expects a primitive image dict
image_meta = nova_object.obj_to_primitive(
instance.image_meta)
request_spec = scheduler_utils.build_request_spec(
context, image_ref, [instance])
context, image_meta, [instance])
elif recreate:
# NOTE(sbauza): Augment the RequestSpec object by excluding
# the source host for avoiding the scheduler to pick it

View File

@ -1239,6 +1239,9 @@ class _BaseTaskTestCase(object):
self.conductor_manager.rebuild_instance(context=self.context,
instance=inst_obj,
**rebuild_args)
bs_mock.assert_called_once_with(
self.context, obj_base.obj_to_primitive(inst_obj.image_meta),
[inst_obj])
fp_mock.assert_called_once_with(self.context, request_spec,
filter_properties)
select_dest_mock.assert_called_once_with(self.context, fake_spec)