diff --git a/nova/conductor/manager.py b/nova/conductor/manager.py index 8dc1637cb119..66b7048cb973 100644 --- a/nova/conductor/manager.py +++ b/nova/conductor/manager.py @@ -864,7 +864,7 @@ class ComputeTaskManager(base.Base): # in the API. try: scheduler_utils.claim_resources_on_destination( - self.report_client, instance, source_node, dest_node) + context, self.report_client, instance, source_node, dest_node) except exception.NoValidHost as ex: with excutils.save_and_reraise_exception(): self._set_vm_state_and_notify( diff --git a/nova/conductor/tasks/live_migrate.py b/nova/conductor/tasks/live_migrate.py index 258d38b5c94d..77400ea7a95f 100644 --- a/nova/conductor/tasks/live_migrate.py +++ b/nova/conductor/tasks/live_migrate.py @@ -91,8 +91,8 @@ class LiveMigrationTask(base.TaskBase): # This raises NoValidHost which will be handled in # ComputeTaskManager. scheduler_utils.claim_resources_on_destination( - self.scheduler_client.reportclient, self.instance, - source_node, dest_node, + self.context, self.scheduler_client.reportclient, + self.instance, source_node, dest_node, source_node_allocations=self._held_allocations) # dest_node is a ComputeNode object, so we need to get the actual diff --git a/nova/scheduler/client/report.py b/nova/scheduler/client/report.py index b372dc49d636..726cb5bb4ed8 100644 --- a/nova/scheduler/client/report.py +++ b/nova/scheduler/client/report.py @@ -1399,8 +1399,8 @@ class SchedulerReportClient(object): # checking that a move operation is in place. @safe_connect @retries - def claim_resources(self, consumer_uuid, alloc_request, project_id, - user_id, allocation_request_version=None): + def claim_resources(self, context, consumer_uuid, alloc_request, + project_id, user_id, allocation_request_version=None): """Creates allocation records for the supplied instance UUID against the supplied resource providers. @@ -1415,6 +1415,7 @@ class SchedulerReportClient(object): end up setting allocations for the instance only on the destination host thereby freeing up resources on the source host appropriately. + :param context: The security context :param consumer_uuid: The instance's UUID. :param alloc_request: The JSON body of the request to make to the placement's PUT /allocations API @@ -1462,7 +1463,8 @@ class SchedulerReportClient(object): payload['project_id'] = project_id payload['user_id'] = user_id - r = self.put(url, payload, version=allocation_request_version) + r = self.put(url, payload, version=allocation_request_version, + global_request_id=context.global_id) if r.status_code != 204: # NOTE(jaypipes): Yes, it sucks doing string comparison like this # but we have no error codes, only error messages. diff --git a/nova/scheduler/utils.py b/nova/scheduler/utils.py index b4d3f5fd6a52..01591c5d6432 100644 --- a/nova/scheduler/utils.py +++ b/nova/scheduler/utils.py @@ -339,7 +339,7 @@ def resources_from_request_spec(spec_obj): # TODO(mriedem): Remove this when select_destinations() in the scheduler takes # some sort of skip_filters flag. def claim_resources_on_destination( - reportclient, instance, source_node, dest_node, + context, reportclient, instance, source_node, dest_node, source_node_allocations=None): """Copies allocations from source node to dest node in Placement @@ -352,6 +352,7 @@ def claim_resources_on_destination( This is only appropriate when the instance flavor on the source node is the same on the destination node, i.e. don't use this for resize. + :param context: The request context. :param reportclient: An instance of the SchedulerReportClient. :param instance: The instance being moved. :param source_node: source ComputeNode where the instance currently @@ -379,7 +380,7 @@ def claim_resources_on_destination( # allocations for resources on the destination node before we move, # we use the existing resource allocations from the source node. if reportclient.claim_resources( - instance.uuid, alloc_request, + context, instance.uuid, alloc_request, instance.project_id, instance.user_id, allocation_request_version='1.12'): LOG.debug('Instance allocations successfully created on ' @@ -792,7 +793,7 @@ def claim_resources(ctx, client, spec_obj, instance_uuid, alloc_req, # the spec object? user_id = ctx.user_id - return client.claim_resources(instance_uuid, alloc_req, project_id, + return client.claim_resources(ctx, instance_uuid, alloc_req, project_id, user_id, allocation_request_version=allocation_request_version) diff --git a/nova/tests/unit/conductor/tasks/test_live_migrate.py b/nova/tests/unit/conductor/tasks/test_live_migrate.py index 7deacc30b372..b65f5c20f182 100644 --- a/nova/tests/unit/conductor/tasks/test_live_migrate.py +++ b/nova/tests/unit/conductor/tasks/test_live_migrate.py @@ -95,8 +95,8 @@ class LiveMigrationTaskTestCase(test.NoDBTestCase): else: allocs = None mock_claim.assert_called_once_with( - self.task.scheduler_client.reportclient, self.instance, - mock.sentinel.source_node, dest_node, + self.context, self.task.scheduler_client.reportclient, + self.instance, mock.sentinel.source_node, dest_node, source_node_allocations=allocs) mock_mig.assert_called_once_with( self.context, diff --git a/nova/tests/unit/conductor/test_conductor.py b/nova/tests/unit/conductor/test_conductor.py index 915422976ed1..d5f79ffa174f 100644 --- a/nova/tests/unit/conductor/test_conductor.py +++ b/nova/tests/unit/conductor/test_conductor.py @@ -2761,7 +2761,7 @@ class ConductorTaskTestCase(_BaseTaskTestCase, test_compute.BaseTestCase): get_dest_node.assert_called_once_with( self.ctxt, 'dest-host', use_slave=True) claim.assert_called_once_with( - self.conductor.scheduler_client.reportclient, instance, + self.ctxt, self.conductor.scheduler_client.reportclient, instance, get_source_node.return_value, get_dest_node.return_value) notify.assert_called_once_with( self.ctxt, instance.uuid, 'rebuild_server', diff --git a/nova/tests/unit/scheduler/client/test_report.py b/nova/tests/unit/scheduler/client/test_report.py index db7b018ca1d6..acf1fc2f8eaf 100644 --- a/nova/tests/unit/scheduler/client/test_report.py +++ b/nova/tests/unit/scheduler/client/test_report.py @@ -383,8 +383,8 @@ class TestPutAllocations(SchedulerReportClientTestCase): project_id = uuids.project_id user_id = uuids.user_id - res = self.client.claim_resources(consumer_uuid, alloc_req, project_id, - user_id) + res = self.client.claim_resources( + self.context, consumer_uuid, alloc_req, project_id, user_id) expected_url = "/allocations/%s" % consumer_uuid expected_payload = { @@ -399,7 +399,8 @@ class TestPutAllocations(SchedulerReportClientTestCase): expected_payload['user_id'] = user_id self.ks_adap_mock.put.assert_called_once_with( expected_url, microversion='1.12', json=expected_payload, - raise_exc=False, headers={}) + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) self.assertTrue(res) @@ -425,8 +426,9 @@ class TestPutAllocations(SchedulerReportClientTestCase): project_id = uuids.project_id user_id = uuids.user_id - res = self.client.claim_resources(consumer_uuid, alloc_req, project_id, - user_id, allocation_request_version='1.12') + res = self.client.claim_resources(self.context, consumer_uuid, + alloc_req, project_id, user_id, + allocation_request_version='1.12') expected_url = "/allocations/%s" % consumer_uuid expected_payload = {'allocations': { @@ -436,7 +438,8 @@ class TestPutAllocations(SchedulerReportClientTestCase): expected_payload['user_id'] = user_id self.ks_adap_mock.put.assert_called_once_with( expected_url, microversion='1.12', json=expected_payload, - raise_exc=False, headers={}) + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) self.assertTrue(res) @@ -476,8 +479,9 @@ class TestPutAllocations(SchedulerReportClientTestCase): project_id = uuids.project_id user_id = uuids.user_id - res = self.client.claim_resources(consumer_uuid, alloc_req, project_id, - user_id, allocation_request_version='1.12') + res = self.client.claim_resources(self.context, consumer_uuid, + alloc_req, project_id, user_id, + allocation_request_version='1.12') expected_url = "/allocations/%s" % consumer_uuid # New allocation should include resources claimed on both the source @@ -502,7 +506,8 @@ class TestPutAllocations(SchedulerReportClientTestCase): expected_payload['user_id'] = user_id self.ks_adap_mock.put.assert_called_once_with( expected_url, microversion='1.12', json=mock.ANY, - raise_exc=False, headers={}) + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) # We have to pull the json body from the mock call_args to validate # it separately otherwise hash seed issues get in the way. actual_payload = self.ks_adap_mock.put.call_args[1]['json'] @@ -560,8 +565,9 @@ class TestPutAllocations(SchedulerReportClientTestCase): project_id = uuids.project_id user_id = uuids.user_id - res = self.client.claim_resources(consumer_uuid, alloc_req, project_id, - user_id, allocation_request_version='1.12') + res = self.client.claim_resources(self.context, consumer_uuid, + alloc_req, project_id, user_id, + allocation_request_version='1.12') expected_url = "/allocations/%s" % consumer_uuid # New allocation should include resources claimed on both the source @@ -592,7 +598,8 @@ class TestPutAllocations(SchedulerReportClientTestCase): expected_payload['user_id'] = user_id self.ks_adap_mock.put.assert_called_once_with( expected_url, microversion='1.12', json=mock.ANY, - raise_exc=False, headers={}) + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) # We have to pull the allocations from the json body from the # mock call_args to validate it separately otherwise hash seed # issues get in the way. @@ -645,8 +652,9 @@ class TestPutAllocations(SchedulerReportClientTestCase): project_id = uuids.project_id user_id = uuids.user_id - res = self.client.claim_resources(consumer_uuid, alloc_req, project_id, - user_id, allocation_request_version='1.12') + res = self.client.claim_resources(self.context, consumer_uuid, + alloc_req, project_id, user_id, + allocation_request_version='1.12') expected_url = "/allocations/%s" % consumer_uuid # New allocation should include doubled resources claimed on the same @@ -667,7 +675,7 @@ class TestPutAllocations(SchedulerReportClientTestCase): expected_payload['user_id'] = user_id self.ks_adap_mock.put.assert_called_once_with( expected_url, microversion='1.12', json=mock.ANY, raise_exc=False, - headers={}) + headers={'X-Openstack-Request-Id': self.context.global_id}) # We have to pull the json body from the mock call_args to validate # it separately otherwise hash seed issues get in the way. actual_payload = self.ks_adap_mock.put.call_args[1]['json'] @@ -727,8 +735,9 @@ class TestPutAllocations(SchedulerReportClientTestCase): project_id = uuids.project_id user_id = uuids.user_id - res = self.client.claim_resources(consumer_uuid, alloc_req, project_id, - user_id, allocation_request_version='1.12') + res = self.client.claim_resources(self.context, consumer_uuid, + alloc_req, project_id, user_id, + allocation_request_version='1.12') expected_url = "/allocations/%s" % consumer_uuid # New allocation should include doubled resources claimed on the same @@ -752,7 +761,7 @@ class TestPutAllocations(SchedulerReportClientTestCase): expected_payload['user_id'] = user_id self.ks_adap_mock.put.assert_called_once_with( expected_url, microversion='1.12', json=mock.ANY, raise_exc=False, - headers={}) + headers={'X-Openstack-Request-Id': self.context.global_id}) # We have to pull the json body from the mock call_args to validate # it separately otherwise hash seed issues get in the way. actual_payload = self.ks_adap_mock.put.call_args[1]['json'] @@ -789,8 +798,9 @@ class TestPutAllocations(SchedulerReportClientTestCase): project_id = uuids.project_id user_id = uuids.user_id - res = self.client.claim_resources(consumer_uuid, alloc_req, project_id, - user_id, allocation_request_version='1.12') + res = self.client.claim_resources(self.context, consumer_uuid, + alloc_req, project_id, user_id, + allocation_request_version='1.12') expected_url = "/allocations/%s" % consumer_uuid expected_payload = { @@ -804,7 +814,9 @@ class TestPutAllocations(SchedulerReportClientTestCase): # identical since we're retrying the same HTTP request expected_calls = [ mock.call(expected_url, microversion='1.12', json=expected_payload, - raise_exc=False, headers={})] * 2 + raise_exc=False, + headers={'X-Openstack-Request-Id': + self.context.global_id})] * 2 self.assertEqual(len(expected_calls), self.ks_adap_mock.put.call_count) self.ks_adap_mock.put.assert_has_calls(expected_calls) @@ -834,8 +846,9 @@ class TestPutAllocations(SchedulerReportClientTestCase): project_id = uuids.project_id user_id = uuids.user_id - res = self.client.claim_resources(consumer_uuid, alloc_req, project_id, - user_id, allocation_request_version='1.12') + res = self.client.claim_resources(self.context, consumer_uuid, + alloc_req, project_id, user_id, + allocation_request_version='1.12') expected_url = "/allocations/%s" % consumer_uuid expected_payload = { @@ -847,7 +860,8 @@ class TestPutAllocations(SchedulerReportClientTestCase): expected_payload['user_id'] = user_id self.ks_adap_mock.put.assert_called_once_with( expected_url, microversion='1.12', json=expected_payload, - raise_exc=False, headers={}) + raise_exc=False, + headers={'X-Openstack-Request-Id': self.context.global_id}) self.assertFalse(res) self.assertTrue(mock_log.called) diff --git a/nova/tests/unit/scheduler/test_utils.py b/nova/tests/unit/scheduler/test_utils.py index 92e0f5e548b2..56d5aa737b60 100644 --- a/nova/tests/unit/scheduler/test_utils.py +++ b/nova/tests/unit/scheduler/test_utils.py @@ -25,6 +25,10 @@ from nova.tests import uuidsentinel as uuids class TestUtils(test.NoDBTestCase): + def setUp(self): + super(TestUtils, self).setUp() + self.context = nova_context.get_admin_context() + def assertResourceRequestsEqual(self, expected, observed): ex_by_id = expected._rg_by_id ob_by_id = observed._rg_by_id @@ -446,8 +450,7 @@ class TestUtils(test.NoDBTestCase): attempted on the destination compute node. """ reportclient = report.SchedulerReportClient() - instance = fake_instance.fake_instance_obj( - nova_context.get_admin_context()) + instance = fake_instance.fake_instance_obj(self.context) source_node = objects.ComputeNode( uuid=uuids.source_node, host=instance.host) dest_node = objects.ComputeNode(uuid=uuids.dest_node, host='dest-host') @@ -460,7 +463,7 @@ class TestUtils(test.NoDBTestCase): new_callable=mock.NonCallableMock) def test(mock_claim, mock_get_allocs): utils.claim_resources_on_destination( - reportclient, instance, source_node, dest_node) + self.context, reportclient, instance, source_node, dest_node) mock_get_allocs.assert_called_once_with( uuids.source_node, instance.uuid) @@ -471,8 +474,7 @@ class TestUtils(test.NoDBTestCase): on the destination compute node fails, resulting in an error. """ reportclient = report.SchedulerReportClient() - instance = fake_instance.fake_instance_obj( - nova_context.get_admin_context()) + instance = fake_instance.fake_instance_obj(self.context) source_node = objects.ComputeNode( uuid=uuids.source_node, host=instance.host) dest_node = objects.ComputeNode(uuid=uuids.dest_node, host='dest-host') @@ -500,11 +502,12 @@ class TestUtils(test.NoDBTestCase): # that they are fetched if needed. self.assertRaises(exception.NoValidHost, utils.claim_resources_on_destination, - reportclient, instance, source_node, dest_node) + self.context, reportclient, instance, + source_node, dest_node) mock_get_allocs.assert_called_once_with( uuids.source_node, instance.uuid) mock_claim.assert_called_once_with( - instance.uuid, dest_alloc_request, + self.context, instance.uuid, dest_alloc_request, instance.project_id, instance.user_id, allocation_request_version='1.12') @@ -513,8 +516,7 @@ class TestUtils(test.NoDBTestCase): def test_claim_resources_on_destination(self): """Happy path test where everything is successful.""" reportclient = report.SchedulerReportClient() - instance = fake_instance.fake_instance_obj( - nova_context.get_admin_context()) + instance = fake_instance.fake_instance_obj(self.context) source_node = objects.ComputeNode( uuid=uuids.source_node, host=instance.host) dest_node = objects.ComputeNode(uuid=uuids.dest_node, host='dest-host') @@ -538,11 +540,11 @@ class TestUtils(test.NoDBTestCase): 'claim_resources', return_value=True) def test(mock_claim, mock_get_allocs): utils.claim_resources_on_destination( - reportclient, instance, source_node, dest_node, + self.context, reportclient, instance, source_node, dest_node, source_res_allocs) self.assertFalse(mock_get_allocs.called) mock_claim.assert_called_once_with( - instance.uuid, dest_alloc_request, + self.context, instance.uuid, dest_alloc_request, instance.project_id, instance.user_id, allocation_request_version='1.12') @@ -564,9 +566,9 @@ class TestUtils(test.NoDBTestCase): res = utils.claim_resources(ctx, mock_client, spec_obj, instance_uuid, alloc_req) - mock_client.claim_resources.assert_called_once_with(uuids.instance, - mock.sentinel.alloc_req, uuids.project_id, uuids.user_id, - allocation_request_version=None) + mock_client.claim_resources.assert_called_once_with( + ctx, uuids.instance, mock.sentinel.alloc_req, uuids.project_id, + uuids.user_id, allocation_request_version=None) self.assertTrue(res) @mock.patch('nova.scheduler.client.report.SchedulerReportClient')