Update resources once in update_available_resource
This change ensures that resources are updated only once per update_available_resource() call. Compute resources were previously updated during host object initialization and at the end of update_available_resource(). It could cause inconsistencies in resource tracking between compute host and DB for couple of second when final _update() at the end of update_available_resource() is being called. For example: nova-api shows that host uses 10GB of RAM, but in fact its 12GB because DB doesn't have resources that belongs to shutdown instance. Because of that fact nova-scheduler (CachingScheduler) could choose (based on imcomplete information) host which is already full. For more informations please see realted bug: #1729621 Change-Id: I120a98cc4c11772f24099081ef3ac44a50daf71d Closes-Bug: #1729621
This commit is contained in:
parent
f9ad40d35d
commit
c9b74bcfa0
|
@ -561,7 +561,6 @@ class ResourceTracker(object):
|
||||||
cn = self.compute_nodes[nodename]
|
cn = self.compute_nodes[nodename]
|
||||||
self._copy_resources(cn, resources)
|
self._copy_resources(cn, resources)
|
||||||
self._setup_pci_tracker(context, cn, resources)
|
self._setup_pci_tracker(context, cn, resources)
|
||||||
self._update(context, cn)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# now try to get the compute node record from the
|
# now try to get the compute node record from the
|
||||||
|
@ -571,7 +570,6 @@ class ResourceTracker(object):
|
||||||
self.compute_nodes[nodename] = cn
|
self.compute_nodes[nodename] = cn
|
||||||
self._copy_resources(cn, resources)
|
self._copy_resources(cn, resources)
|
||||||
self._setup_pci_tracker(context, cn, resources)
|
self._setup_pci_tracker(context, cn, resources)
|
||||||
self._update(context, cn)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._check_for_nodes_rebalance(context, resources, nodename):
|
if self._check_for_nodes_rebalance(context, resources, nodename):
|
||||||
|
@ -590,7 +588,6 @@ class ResourceTracker(object):
|
||||||
{'host': self.host, 'node': nodename, 'uuid': cn.uuid})
|
{'host': self.host, 'node': nodename, 'uuid': cn.uuid})
|
||||||
|
|
||||||
self._setup_pci_tracker(context, cn, resources)
|
self._setup_pci_tracker(context, cn, resources)
|
||||||
self._update(context, cn)
|
|
||||||
|
|
||||||
def _setup_pci_tracker(self, context, compute_node, resources):
|
def _setup_pci_tracker(self, context, compute_node, resources):
|
||||||
if not self.pci_tracker:
|
if not self.pci_tracker:
|
||||||
|
|
|
@ -573,6 +573,7 @@ class TestUpdateAvailableResources(BaseTestCase):
|
||||||
actual_resources = update_mock.call_args[0][1]
|
actual_resources = update_mock.call_args[0][1]
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
||||||
actual_resources))
|
actual_resources))
|
||||||
|
update_mock.assert_called_once()
|
||||||
|
|
||||||
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
||||||
return_value=objects.InstancePCIRequests(requests=[]))
|
return_value=objects.InstancePCIRequests(requests=[]))
|
||||||
|
@ -613,6 +614,7 @@ class TestUpdateAvailableResources(BaseTestCase):
|
||||||
actual_resources = update_mock.call_args[0][1]
|
actual_resources = update_mock.call_args[0][1]
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
||||||
actual_resources))
|
actual_resources))
|
||||||
|
update_mock.assert_called_once()
|
||||||
|
|
||||||
@mock.patch('nova.compute.utils.is_volume_backed_instance')
|
@mock.patch('nova.compute.utils.is_volume_backed_instance')
|
||||||
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
||||||
|
@ -662,6 +664,7 @@ class TestUpdateAvailableResources(BaseTestCase):
|
||||||
actual_resources = update_mock.call_args[0][1]
|
actual_resources = update_mock.call_args[0][1]
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
||||||
actual_resources))
|
actual_resources))
|
||||||
|
update_mock.assert_called_once()
|
||||||
|
|
||||||
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
||||||
return_value=objects.InstancePCIRequests(requests=[]))
|
return_value=objects.InstancePCIRequests(requests=[]))
|
||||||
|
@ -725,6 +728,7 @@ class TestUpdateAvailableResources(BaseTestCase):
|
||||||
actual_resources = update_mock.call_args[0][1]
|
actual_resources = update_mock.call_args[0][1]
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
||||||
actual_resources))
|
actual_resources))
|
||||||
|
update_mock.assert_called_once()
|
||||||
|
|
||||||
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
||||||
return_value=objects.InstancePCIRequests(requests=[]))
|
return_value=objects.InstancePCIRequests(requests=[]))
|
||||||
|
@ -787,6 +791,7 @@ class TestUpdateAvailableResources(BaseTestCase):
|
||||||
actual_resources = update_mock.call_args[0][1]
|
actual_resources = update_mock.call_args[0][1]
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
||||||
actual_resources))
|
actual_resources))
|
||||||
|
update_mock.assert_called_once()
|
||||||
|
|
||||||
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
||||||
return_value=objects.InstancePCIRequests(requests=[]))
|
return_value=objects.InstancePCIRequests(requests=[]))
|
||||||
|
@ -846,6 +851,7 @@ class TestUpdateAvailableResources(BaseTestCase):
|
||||||
actual_resources = update_mock.call_args[0][1]
|
actual_resources = update_mock.call_args[0][1]
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
||||||
actual_resources))
|
actual_resources))
|
||||||
|
update_mock.assert_called_once()
|
||||||
|
|
||||||
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
||||||
return_value=objects.InstancePCIRequests(requests=[]))
|
return_value=objects.InstancePCIRequests(requests=[]))
|
||||||
|
@ -902,6 +908,7 @@ class TestUpdateAvailableResources(BaseTestCase):
|
||||||
actual_resources = update_mock.call_args[0][1]
|
actual_resources = update_mock.call_args[0][1]
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
||||||
actual_resources))
|
actual_resources))
|
||||||
|
update_mock.assert_called_once()
|
||||||
|
|
||||||
@mock.patch('nova.compute.utils.is_volume_backed_instance')
|
@mock.patch('nova.compute.utils.is_volume_backed_instance')
|
||||||
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
@mock.patch('nova.objects.InstancePCIRequests.get_by_instance',
|
||||||
|
@ -973,6 +980,7 @@ class TestUpdateAvailableResources(BaseTestCase):
|
||||||
actual_resources = update_mock.call_args[0][1]
|
actual_resources = update_mock.call_args[0][1]
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
self.assertTrue(obj_base.obj_equal_prims(expected_resources,
|
||||||
actual_resources))
|
actual_resources))
|
||||||
|
update_mock.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
class TestInitComputeNode(BaseTestCase):
|
class TestInitComputeNode(BaseTestCase):
|
||||||
|
@ -998,7 +1006,7 @@ class TestInitComputeNode(BaseTestCase):
|
||||||
self.assertFalse(get_mock.called)
|
self.assertFalse(get_mock.called)
|
||||||
self.assertFalse(create_mock.called)
|
self.assertFalse(create_mock.called)
|
||||||
self.assertTrue(pci_mock.called)
|
self.assertTrue(pci_mock.called)
|
||||||
self.assertTrue(update_mock.called)
|
self.assertFalse(update_mock.called)
|
||||||
|
|
||||||
@mock.patch('nova.objects.PciDeviceList.get_by_compute_node',
|
@mock.patch('nova.objects.PciDeviceList.get_by_compute_node',
|
||||||
return_value=objects.PciDeviceList())
|
return_value=objects.PciDeviceList())
|
||||||
|
@ -1022,7 +1030,7 @@ class TestInitComputeNode(BaseTestCase):
|
||||||
get_mock.assert_called_once_with(mock.sentinel.ctx, _HOSTNAME,
|
get_mock.assert_called_once_with(mock.sentinel.ctx, _HOSTNAME,
|
||||||
_NODENAME)
|
_NODENAME)
|
||||||
self.assertFalse(create_mock.called)
|
self.assertFalse(create_mock.called)
|
||||||
self.assertTrue(update_mock.called)
|
self.assertFalse(update_mock.called)
|
||||||
|
|
||||||
@mock.patch('nova.objects.ComputeNodeList.get_by_hypervisor')
|
@mock.patch('nova.objects.ComputeNodeList.get_by_hypervisor')
|
||||||
@mock.patch('nova.objects.PciDeviceList.get_by_compute_node',
|
@mock.patch('nova.objects.PciDeviceList.get_by_compute_node',
|
||||||
|
@ -1187,7 +1195,7 @@ class TestInitComputeNode(BaseTestCase):
|
||||||
self.assertTrue(obj_base.obj_equal_prims(expected_compute, cn))
|
self.assertTrue(obj_base.obj_equal_prims(expected_compute, cn))
|
||||||
pci_tracker_mock.assert_called_once_with(mock.sentinel.ctx,
|
pci_tracker_mock.assert_called_once_with(mock.sentinel.ctx,
|
||||||
42)
|
42)
|
||||||
self.assertTrue(update_mock.called)
|
self.assertFalse(update_mock.called)
|
||||||
|
|
||||||
@mock.patch('nova.objects.ComputeNodeList.get_by_hypervisor')
|
@mock.patch('nova.objects.ComputeNodeList.get_by_hypervisor')
|
||||||
@mock.patch('nova.objects.PciDeviceList.get_by_compute_node',
|
@mock.patch('nova.objects.PciDeviceList.get_by_compute_node',
|
||||||
|
|
Loading…
Reference in New Issue