Merge "[placement] Add sending global request ID in delete (3)"

This commit is contained in:
Zuul 2018-01-31 00:29:34 +00:00 committed by Gerrit Code Review
commit 97c0665bef
7 changed files with 49 additions and 30 deletions

View File

@ -872,6 +872,7 @@ class ResourceTracker(object):
inv_data = self.driver.get_inventory(nodename) inv_data = self.driver.get_inventory(nodename)
_normalize_inventory_from_cn_obj(inv_data, compute_node) _normalize_inventory_from_cn_obj(inv_data, compute_node)
self.scheduler_client.set_inventory_for_provider( self.scheduler_client.set_inventory_for_provider(
context,
compute_node.uuid, compute_node.uuid,
compute_node.hypervisor_hostname, compute_node.hypervisor_hostname,
inv_data, inv_data,
@ -880,7 +881,7 @@ class ResourceTracker(object):
# Eventually all virt drivers will return an inventory dict in the # Eventually all virt drivers will return an inventory dict in the
# format that the placement API expects and we'll be able to remove # format that the placement API expects and we'll be able to remove
# this code branch # this code branch
self.scheduler_client.update_compute_node(compute_node) self.scheduler_client.update_compute_node(context, compute_node)
if self.pci_tracker: if self.pci_tracker:
self.pci_tracker.save(context) self.pci_tracker.save(context)

View File

@ -58,17 +58,18 @@ class SchedulerClient(object):
def delete_aggregate(self, context, aggregate): def delete_aggregate(self, context, aggregate):
self.queryclient.delete_aggregate(context, aggregate) self.queryclient.delete_aggregate(context, aggregate)
def set_inventory_for_provider(self, rp_uuid, rp_name, inv_data, def set_inventory_for_provider(self, context, rp_uuid, rp_name, inv_data,
parent_provider_uuid=None): parent_provider_uuid=None):
self.reportclient.set_inventory_for_provider( self.reportclient.set_inventory_for_provider(
context,
rp_uuid, rp_uuid,
rp_name, rp_name,
inv_data, inv_data,
parent_provider_uuid=parent_provider_uuid, parent_provider_uuid=parent_provider_uuid,
) )
def update_compute_node(self, compute_node): def update_compute_node(self, context, compute_node):
self.reportclient.update_compute_node(compute_node) self.reportclient.update_compute_node(context, compute_node)
def update_instance_info(self, context, host_name, instance_info): def update_instance_info(self, context, host_name, instance_info):
self.queryclient.update_instance_info(context, host_name, self.queryclient.update_instance_info(context, host_name,

View File

@ -870,7 +870,7 @@ class SchedulerReportClient(object):
return False return False
@safe_connect @safe_connect
def _delete_inventory(self, rp_uuid): def _delete_inventory(self, context, rp_uuid):
"""Deletes all inventory records for a resource provider with the """Deletes all inventory records for a resource provider with the
supplied UUID. supplied UUID.
@ -894,7 +894,8 @@ class SchedulerReportClient(object):
cur_gen = curr['resource_provider_generation'] cur_gen = curr['resource_provider_generation']
url = '/resource_providers/%s/inventories' % rp_uuid url = '/resource_providers/%s/inventories' % rp_uuid
r = self.delete(url, version="1.5") r = self.delete(url, version="1.5",
global_request_id=context.global_id)
placement_req_id = get_placement_request_id(r) placement_req_id = get_placement_request_id(r)
msg_args = { msg_args = {
'rp_uuid': rp_uuid, 'rp_uuid': rp_uuid,
@ -956,11 +957,12 @@ class SchedulerReportClient(object):
msg_args['err'] = r.text msg_args['err'] = r.text
LOG.error(msg, msg_args) LOG.error(msg, msg_args)
def set_inventory_for_provider(self, rp_uuid, rp_name, inv_data, def set_inventory_for_provider(self, context, rp_uuid, rp_name, inv_data,
parent_provider_uuid=None): parent_provider_uuid=None):
"""Given the UUID of a provider, set the inventory records for the """Given the UUID of a provider, set the inventory records for the
provider to the supplied dict of resources. provider to the supplied dict of resources.
:param context: The security context
:param rp_uuid: UUID of the resource provider to set inventory for :param rp_uuid: UUID of the resource provider to set inventory for
:param rp_name: Name of the resource provider in case we need to create :param rp_name: Name of the resource provider in case we need to create
a record for it in the placement API a record for it in the placement API
@ -985,7 +987,7 @@ class SchedulerReportClient(object):
if inv_data: if inv_data:
self._update_inventory(rp_uuid, inv_data) self._update_inventory(rp_uuid, inv_data)
else: else:
self._delete_inventory(rp_uuid) self._delete_inventory(context, rp_uuid)
@safe_connect @safe_connect
def _ensure_traits(self, traits): def _ensure_traits(self, traits):
@ -1195,9 +1197,10 @@ class SchedulerReportClient(object):
LOG.error(msg, args) LOG.error(msg, args)
raise exception.InvalidResourceClass(resource_class=name) raise exception.InvalidResourceClass(resource_class=name)
def update_compute_node(self, compute_node): def update_compute_node(self, context, compute_node):
"""Creates or updates stats for the supplied compute node. """Creates or updates stats for the supplied compute node.
:param context: The security context
:param compute_node: updated nova.objects.ComputeNode to report :param compute_node: updated nova.objects.ComputeNode to report
:raises `exception.InventoryInUse` if the compute node has had changes :raises `exception.InventoryInUse` if the compute node has had changes
to its inventory but there are still active allocations for to its inventory but there are still active allocations for
@ -1210,7 +1213,7 @@ class SchedulerReportClient(object):
if inv_data: if inv_data:
self._update_inventory(compute_node.uuid, inv_data) self._update_inventory(compute_node.uuid, inv_data)
else: else:
self._delete_inventory(compute_node.uuid) self._delete_inventory(context, compute_node.uuid)
@safe_connect @safe_connect
def get_allocations_for_consumer(self, consumer): def get_allocations_for_consumer(self, consumer):

View File

@ -110,7 +110,7 @@ class SchedulerReportClientTests(test.TestCase):
self.assertEqual([], rps) self.assertEqual([], rps)
# Now let's update status for our compute node. # Now let's update status for our compute node.
self.client.update_compute_node(self.compute_node) self.client.update_compute_node(self.context, self.compute_node)
# So now we have a resource provider # So now we have a resource provider
rp = self.client._get_resource_provider(self.compute_uuid) rp = self.client._get_resource_provider(self.compute_uuid)
@ -171,7 +171,7 @@ class SchedulerReportClientTests(test.TestCase):
self.compute_node.vcpus = 0 self.compute_node.vcpus = 0
self.compute_node.memory_mb = 0 self.compute_node.memory_mb = 0
self.compute_node.local_gb = 0 self.compute_node.local_gb = 0
self.client.update_compute_node(self.compute_node) self.client.update_compute_node(self.context, self.compute_node)
# Check there's no more inventory records # Check there's no more inventory records
resp = self.client.get(inventory_url) resp = self.client.get(inventory_url)
@ -192,7 +192,8 @@ class SchedulerReportClientTests(test.TestCase):
} }
self.assertRaises(exception.InvalidResourceClass, self.assertRaises(exception.InvalidResourceClass,
self.client.set_inventory_for_provider, self.client.set_inventory_for_provider,
self.compute_uuid, self.compute_name, inv_data) self.context, self.compute_uuid,
self.compute_name, inv_data)
@mock.patch('keystoneauth1.session.Session.get_endpoint', @mock.patch('keystoneauth1.session.Session.get_endpoint',
return_value='http://localhost:80/placement') return_value='http://localhost:80/placement')

View File

@ -1201,7 +1201,7 @@ class TestUpdateComputeNode(BaseTestCase):
# implemented. # implemented.
self.driver_mock.get_inventory.assert_called_once_with(_NODENAME) self.driver_mock.get_inventory.assert_called_once_with(_NODENAME)
ucn_mock = self.sched_client_mock.update_compute_node ucn_mock = self.sched_client_mock.update_compute_node
ucn_mock.assert_called_once_with(new_compute) ucn_mock.assert_called_once_with(mock.sentinel.ctx, new_compute)
@mock.patch('nova.objects.ComputeNode.save') @mock.patch('nova.objects.ComputeNode.save')
def test_existing_compute_node_updated_diff_updated_at(self, save_mock): def test_existing_compute_node_updated_diff_updated_at(self, save_mock):
@ -1249,7 +1249,7 @@ class TestUpdateComputeNode(BaseTestCase):
# _normalize_inventory_from_cn_obj but call update_compute_node(). # _normalize_inventory_from_cn_obj but call update_compute_node().
self.assertFalse(norm_mock.called) self.assertFalse(norm_mock.called)
ucn_mock = self.sched_client_mock.update_compute_node ucn_mock = self.sched_client_mock.update_compute_node
ucn_mock.assert_called_once_with(new_compute) ucn_mock.assert_called_once_with(mock.sentinel.ctx, new_compute)
@mock.patch('nova.compute.resource_tracker.' @mock.patch('nova.compute.resource_tracker.'
'_normalize_inventory_from_cn_obj') '_normalize_inventory_from_cn_obj')
@ -1282,6 +1282,7 @@ class TestUpdateComputeNode(BaseTestCase):
self.rt._update(mock.sentinel.ctx, new_compute) self.rt._update(mock.sentinel.ctx, new_compute)
save_mock.assert_called_once_with() save_mock.assert_called_once_with()
sifp_mock.assert_called_once_with( sifp_mock.assert_called_once_with(
mock.sentinel.ctx,
new_compute.uuid, new_compute.uuid,
new_compute.hypervisor_hostname, new_compute.hypervisor_hostname,
mock.sentinel.inv_data, mock.sentinel.inv_data,

View File

@ -2269,7 +2269,7 @@ class TestInventory(SchedulerReportClientTestCase):
'_update_inventory') '_update_inventory')
def test_update_compute_node(self, mock_ui, mock_delete, mock_erp): def test_update_compute_node(self, mock_ui, mock_delete, mock_erp):
cn = self.compute_node cn = self.compute_node
self.client.update_compute_node(cn) self.client.update_compute_node(self.context, cn)
mock_erp.assert_called_once_with(cn.uuid, cn.hypervisor_hostname) mock_erp.assert_called_once_with(cn.uuid, cn.hypervisor_hostname)
expected_inv_data = { expected_inv_data = {
'VCPU': { 'VCPU': {
@ -2318,9 +2318,9 @@ class TestInventory(SchedulerReportClientTestCase):
cn.vcpus = 0 cn.vcpus = 0
cn.memory_mb = 0 cn.memory_mb = 0
cn.local_gb = 0 cn.local_gb = 0
self.client.update_compute_node(cn) self.client.update_compute_node(self.context, cn)
mock_erp.assert_called_once_with(cn.uuid, cn.hypervisor_hostname) mock_erp.assert_called_once_with(cn.uuid, cn.hypervisor_hostname)
mock_delete.assert_called_once_with(cn.uuid) mock_delete.assert_called_once_with(self.context, cn.uuid)
self.assertFalse(mock_ui.called) self.assertFalse(mock_ui.called)
@mock.patch.object(report.LOG, 'info') @mock.patch.object(report.LOG, 'info')
@ -2346,11 +2346,14 @@ class TestInventory(SchedulerReportClientTestCase):
mock_delete.return_value.status_code = 204 mock_delete.return_value.status_code = 204
mock_delete.return_value.headers = {'x-openstack-request-id': mock_delete.return_value.headers = {'x-openstack-request-id':
uuids.request_id} uuids.request_id}
result = self.client._delete_inventory(cn.uuid) result = self.client._delete_inventory(self.context, cn.uuid)
self.assertIsNone(result) self.assertIsNone(result)
self.assertFalse(mock_put.called) self.assertFalse(mock_put.called)
self.assertEqual(uuids.request_id, self.assertEqual(uuids.request_id,
mock_info.call_args[0][1]['placement_req_id']) mock_info.call_args[0][1]['placement_req_id'])
mock_delete.assert_called_once_with(
'/resource_providers/%s/inventories' % cn.uuid,
version='1.5', global_request_id=self.context.global_id)
@mock.patch('nova.scheduler.client.report._extract_inventory_in_use') @mock.patch('nova.scheduler.client.report._extract_inventory_in_use')
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.' @mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
@ -2368,7 +2371,7 @@ class TestInventory(SchedulerReportClientTestCase):
'inventories': { 'inventories': {
} }
} }
result = self.client._delete_inventory(cn.uuid) result = self.client._delete_inventory(self.context, cn.uuid)
self.assertIsNone(result) self.assertIsNone(result)
self.assertFalse(mock_delete.called) self.assertFalse(mock_delete.called)
self.assertFalse(mock_extract.called) self.assertFalse(mock_extract.called)
@ -2403,7 +2406,7 @@ class TestInventory(SchedulerReportClientTestCase):
} }
mock_put.return_value.headers = {'x-openstack-request-id': mock_put.return_value.headers = {'x-openstack-request-id':
uuids.request_id} uuids.request_id}
result = self.client._delete_inventory(cn.uuid) result = self.client._delete_inventory(self.context, cn.uuid)
self.assertIsNone(result) self.assertIsNone(result)
self.assertTrue(mock_debug.called) self.assertTrue(mock_debug.called)
self.assertTrue(mock_put.called) self.assertTrue(mock_put.called)
@ -2433,7 +2436,7 @@ class TestInventory(SchedulerReportClientTestCase):
} }
mock_delete.return_value.status_code = 406 mock_delete.return_value.status_code = 406
mock_put.return_value.status_code = 200 mock_put.return_value.status_code = 200
self.client._delete_inventory(cn.uuid) self.client._delete_inventory(self.context, cn.uuid)
self.assertTrue(mock_debug.called) self.assertTrue(mock_debug.called)
exp_url = '/resource_providers/%s/inventories' % cn.uuid exp_url = '/resource_providers/%s/inventories' % cn.uuid
payload = { payload = {
@ -2475,7 +2478,7 @@ class TestInventory(SchedulerReportClientTestCase):
} }
mock_put.return_value.headers = {'x-openstack-request-id': mock_put.return_value.headers = {'x-openstack-request-id':
uuids.request_id} uuids.request_id}
self.client._delete_inventory(cn.uuid) self.client._delete_inventory(self.context, cn.uuid)
self.assertTrue(mock_debug.called) self.assertTrue(mock_debug.called)
exp_url = '/resource_providers/%s/inventories' % cn.uuid exp_url = '/resource_providers/%s/inventories' % cn.uuid
payload = { payload = {
@ -2527,7 +2530,7 @@ There was a conflict when trying to complete your request.
'inventories': { 'inventories': {
} }
} }
result = self.client._delete_inventory(cn.uuid) result = self.client._delete_inventory(self.context, cn.uuid)
self.assertIsNone(result) self.assertIsNone(result)
self.assertTrue(mock_warn.called) self.assertTrue(mock_warn.called)
self.assertEqual(uuids.request_id, self.assertEqual(uuids.request_id,
@ -2562,7 +2565,7 @@ There was a conflict when trying to complete your request.
mock_delete.return_value.status_code = 404 mock_delete.return_value.status_code = 404
mock_delete.return_value.headers = {'x-openstack-request-id': mock_delete.return_value.headers = {'x-openstack-request-id':
uuids.request_id} uuids.request_id}
result = self.client._delete_inventory(cn.uuid) result = self.client._delete_inventory(self.context, cn.uuid)
self.assertIsNone(result) self.assertIsNone(result)
self.assertFalse(self.client._provider_tree.exists(cn.uuid)) self.assertFalse(self.client._provider_tree.exists(cn.uuid))
self.assertTrue(mock_debug.called) self.assertTrue(mock_debug.called)
@ -2602,7 +2605,7 @@ There was a conflict when trying to complete your request.
} }
mock_delete.return_value.headers = {'x-openstack-request-id': mock_delete.return_value.headers = {'x-openstack-request-id':
uuids.request_id} uuids.request_id}
result = self.client._delete_inventory(cn.uuid) result = self.client._delete_inventory(self.context, cn.uuid)
self.assertIsNone(result) self.assertIsNone(result)
self.assertFalse(mock_warn.called) self.assertFalse(mock_warn.called)
self.assertTrue(mock_error.called) self.assertTrue(mock_error.called)
@ -3076,6 +3079,7 @@ There was a conflict when trying to complete your request.
}, },
} }
self.client.set_inventory_for_provider( self.client.set_inventory_for_provider(
self.context,
mock.sentinel.rp_uuid, mock.sentinel.rp_uuid,
mock.sentinel.rp_name, mock.sentinel.rp_name,
inv_data, inv_data,
@ -3111,6 +3115,7 @@ There was a conflict when trying to complete your request.
""" """
inv_data = {} inv_data = {}
self.client.set_inventory_for_provider( self.client.set_inventory_for_provider(
self.context,
mock.sentinel.rp_uuid, mock.sentinel.rp_uuid,
mock.sentinel.rp_name, mock.sentinel.rp_name,
inv_data, inv_data,
@ -3123,7 +3128,7 @@ There was a conflict when trying to complete your request.
self.assertFalse(mock_gocr.called) self.assertFalse(mock_gocr.called)
self.assertFalse(mock_erc.called) self.assertFalse(mock_erc.called)
self.assertFalse(mock_upd.called) self.assertFalse(mock_upd.called)
mock_del.assert_called_once_with(mock.sentinel.rp_uuid) mock_del.assert_called_once_with(self.context, mock.sentinel.rp_uuid)
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.' @mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'_update_inventory') '_update_inventory')
@ -3177,6 +3182,7 @@ There was a conflict when trying to complete your request.
} }
self.client.set_inventory_for_provider( self.client.set_inventory_for_provider(
self.context,
mock.sentinel.rp_uuid, mock.sentinel.rp_uuid,
mock.sentinel.rp_name, mock.sentinel.rp_name,
inv_data, inv_data,
@ -3203,7 +3209,8 @@ There was a conflict when trying to complete your request.
def test_set_inventory_for_provider_with_parent(self, mock_erp): def test_set_inventory_for_provider_with_parent(self, mock_erp):
"""Ensure parent UUID is sent through.""" """Ensure parent UUID is sent through."""
self.client.set_inventory_for_provider( self.client.set_inventory_for_provider(
uuids.child, 'junior', {}, parent_provider_uuid=uuids.parent) self.context, uuids.child, 'junior', {},
parent_provider_uuid=uuids.parent)
mock_erp.assert_called_once_with( mock_erp.assert_called_once_with(
uuids.child, 'junior', parent_provider_uuid=uuids.parent) uuids.child, 'junior', parent_provider_uuid=uuids.parent)

View File

@ -99,20 +99,23 @@ class SchedulerClientTestCase(test.NoDBTestCase):
def test_update_compute_node(self, mock_update_compute_node): def test_update_compute_node(self, mock_update_compute_node):
self.assertIsNone(self.client.reportclient.instance) self.assertIsNone(self.client.reportclient.instance)
self.client.update_compute_node(mock.sentinel.cn) self.client.update_compute_node(mock.sentinel.ctx, mock.sentinel.cn)
self.assertIsNotNone(self.client.reportclient.instance) self.assertIsNotNone(self.client.reportclient.instance)
mock_update_compute_node.assert_called_once_with(mock.sentinel.cn) mock_update_compute_node.assert_called_once_with(
mock.sentinel.ctx, mock.sentinel.cn)
@mock.patch.object(scheduler_report_client.SchedulerReportClient, @mock.patch.object(scheduler_report_client.SchedulerReportClient,
'set_inventory_for_provider') 'set_inventory_for_provider')
def test_set_inventory_for_provider(self, mock_set): def test_set_inventory_for_provider(self, mock_set):
self.client.set_inventory_for_provider( self.client.set_inventory_for_provider(
mock.sentinel.ctx,
mock.sentinel.rp_uuid, mock.sentinel.rp_uuid,
mock.sentinel.rp_name, mock.sentinel.rp_name,
mock.sentinel.inv_data, mock.sentinel.inv_data,
) )
mock_set.assert_called_once_with( mock_set.assert_called_once_with(
mock.sentinel.ctx,
mock.sentinel.rp_uuid, mock.sentinel.rp_uuid,
mock.sentinel.rp_name, mock.sentinel.rp_name,
mock.sentinel.inv_data, mock.sentinel.inv_data,
@ -121,12 +124,14 @@ class SchedulerClientTestCase(test.NoDBTestCase):
# Pass the optional parent_provider_uuid # Pass the optional parent_provider_uuid
mock_set.reset_mock() mock_set.reset_mock()
self.client.set_inventory_for_provider( self.client.set_inventory_for_provider(
mock.sentinel.ctx,
mock.sentinel.child_uuid, mock.sentinel.child_uuid,
mock.sentinel.child_name, mock.sentinel.child_name,
mock.sentinel.inv_data2, mock.sentinel.inv_data2,
parent_provider_uuid=mock.sentinel.rp_uuid, parent_provider_uuid=mock.sentinel.rp_uuid,
) )
mock_set.assert_called_once_with( mock_set.assert_called_once_with(
mock.sentinel.ctx,
mock.sentinel.child_uuid, mock.sentinel.child_uuid,
mock.sentinel.child_name, mock.sentinel.child_name,
mock.sentinel.inv_data2, mock.sentinel.inv_data2,