[placement] Add sending global request ID in put (2)

Add the 'X-Openstack-Request-Id' header
in the request of PUT in SchedulerReportClient.
When claiming resources, the header is added.

Subsequent patches will add the header in the other cases.

Change-Id: I73d5aceed399ae906ee577e91c80551284faf21e
Partial-Bug: #1734625
This commit is contained in:
Takashi NATSUME 2018-01-05 08:05:15 +09:00
parent 5d928ae2e0
commit cf375d2ef3
8 changed files with 69 additions and 50 deletions

View File

@ -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(

View File

@ -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

View File

@ -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.

View File

@ -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)

View File

@ -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,

View File

@ -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',

View File

@ -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)

View File

@ -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')