From 09e678ee142ea297640e44ce9af630402871c38a Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Wed, 30 May 2018 12:07:53 -0400 Subject: [PATCH] Use instance project/user when creating RequestSpec during resize reschedule When rescheduling from a failed cold migrate / resize, the compute service does not pass the request spec back to conductor so we create one based on the in-scope variables. This introduces a problem for some scheduler filters like the AggregateMultiTenancyIsolation filter since it will create the RequestSpec using the project and user information from the current context, which for a cold migrate is the admin and might not be the owner of the instance (which could be in some other project). So the AggregateMultiTenancyIsolation filter might reject the request or select a host that fits an aggregate for the admin but not the end user. This fixes the problem by using the instance project/user information when constructing the RequestSpec which will take priority over the context in RequestSpec.from_components(). Long-term we need the compute service to pass the request spec back to the conductor during a reschedule, but we do this first since we can backport it. NOTE(mriedem): RequestSpec.user_id was added in Rocky in commit 6e49019fae80586c4bbb8a7281600cf6140c176a so we have to remove its usage in this backport. NOTE(mriedem): Some existing tests in test_conductor.py had to be updated to set a project_id on the fake instance since change I34b1d99a9d0d2aca80f094a79ec1656abaf762dc is not in Ocata. Change-Id: Iaaf7f68d6874fd5d6e737e7d2bc589ea4a048fee Closes-Bug: #1774205 (cherry picked from commit 8c216608194c89d281e8d2b66abd1e50e2405b01) (cherry picked from commit 1162902280d06eb6201738ef54ff8300f974b374) (cherry picked from commit ce7ad878093e5730b8dcec5ca717b831db8965eb) --- nova/conductor/manager.py | 3 ++- nova/tests/unit/conductor/test_conductor.py | 14 +++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 6927e7e4a5e6..db3b887993d7 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -266,7 +266,8 @@ class ComputeTaskManager(base.Base): request_spec = objects.RequestSpec.from_components( context, instance.uuid, image, flavor, instance.numa_topology, instance.pci_requests, - filter_properties, None, instance.availability_zone) + filter_properties, None, instance.availability_zone, + project_id=instance.project_id) else: # NOTE(sbauza): Resizes means new flavor, so we need to update the # original RequestSpec object for make sure the scheduler verifies diff --git a/nova/tests/unit/conductor/test_conductor.py b/nova/tests/unit/conductor/test_conductor.py index b88d9f546e73..b84602d36acf 100644 --- a/nova/tests/unit/conductor/test_conductor.py +++ b/nova/tests/unit/conductor/test_conductor.py @@ -1952,7 +1952,8 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): flavor=flavor, availability_zone=None, pci_requests=None, - numa_topology=None) + numa_topology=None, + project_id=self.context.project_id) resvs = 'fake-resvs' image = 'fake-image' fake_spec = objects.RequestSpec(image=objects.ImageMeta()) @@ -2005,7 +2006,8 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): flavor=flavor, numa_topology=None, pci_requests=None, - availability_zone=None) + availability_zone=None, + project_id=self.context.project_id) image = 'fake-image' resvs = 'fake-resvs' @@ -2085,6 +2087,7 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): instance_type_id=flavor['id'], system_metadata={}, uuid=uuids.instance, + project_id=fakes.FAKE_PROJECT_ID, user_id=fakes.FAKE_USER_ID, flavor=flavor, numa_topology=None, @@ -2108,6 +2111,10 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): set_vm_mock.assert_called_once_with(self.context, inst_obj.uuid, 'migrate_server', updates, exception, legacy_request_spec) + spec_fc_mock.assert_called_once_with( + self.context, inst_obj.uuid, image, flavor, inst_obj.numa_topology, + inst_obj.pci_requests, {}, None, inst_obj.availability_zone, + project_id=inst_obj.project_id) @mock.patch.object(scheduler_utils, 'setup_instance_group') @mock.patch.object(objects.RequestSpec, 'from_components') @@ -2133,7 +2140,8 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): flavor=flavor, availability_zone=None, pci_requests=None, - numa_topology=None) + numa_topology=None, + project_id=self.context.project_id) image = 'fake-image' resvs = 'fake-resvs' fake_spec = objects.RequestSpec(image=objects.ImageMeta())