Hook resource_tracker to remove stale node information
When we remove a node from a host due to rebalance or decommission, we need to tell the resource tracker so it stops keeping track of the details for that node. This adds a hook for doing that and calls it from the place in compute manager where we purge the record from the database. Change-Id: Ie6b6bb2a9e8a4ad33675fccb3827e8197fa16398 Closes-Bug: #1784874
This commit is contained in:
parent
b5b7d86bb0
commit
99db9faae5
|
@ -7756,6 +7756,7 @@ class ComputeManager(manager.Manager):
|
||||||
LOG.warning("Virt driver is not ready.")
|
LOG.warning("Virt driver is not ready.")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
rt = self._get_resource_tracker()
|
||||||
# Delete orphan compute node not reported by driver but still in db
|
# Delete orphan compute node not reported by driver but still in db
|
||||||
for cn in compute_nodes_in_db:
|
for cn in compute_nodes_in_db:
|
||||||
if cn.hypervisor_hostname not in nodenames:
|
if cn.hypervisor_hostname not in nodenames:
|
||||||
|
@ -7765,6 +7766,7 @@ class ComputeManager(manager.Manager):
|
||||||
{'id': cn.id, 'hh': cn.hypervisor_hostname,
|
{'id': cn.id, 'hh': cn.hypervisor_hostname,
|
||||||
'nodes': nodenames})
|
'nodes': nodenames})
|
||||||
cn.destroy()
|
cn.destroy()
|
||||||
|
rt.remove_node(cn.hypervisor_hostname)
|
||||||
# Delete the corresponding resource provider in placement,
|
# Delete the corresponding resource provider in placement,
|
||||||
# along with any associated allocations and inventory.
|
# along with any associated allocations and inventory.
|
||||||
# TODO(cdent): Move use of reportclient into resource tracker.
|
# TODO(cdent): Move use of reportclient into resource tracker.
|
||||||
|
|
|
@ -627,6 +627,16 @@ class ResourceTracker(object):
|
||||||
# now copy rest to compute_node
|
# now copy rest to compute_node
|
||||||
compute_node.update_from_virt_driver(resources)
|
compute_node.update_from_virt_driver(resources)
|
||||||
|
|
||||||
|
def remove_node(self, nodename):
|
||||||
|
"""Handle node removal/rebalance.
|
||||||
|
|
||||||
|
Clean up any stored data about a compute node no longer
|
||||||
|
managed by this host.
|
||||||
|
"""
|
||||||
|
self.stats.pop(nodename, None)
|
||||||
|
self.compute_nodes.pop(nodename, None)
|
||||||
|
self.old_resources.pop(nodename, None)
|
||||||
|
|
||||||
def _get_host_metrics(self, context, nodename):
|
def _get_host_metrics(self, context, nodename):
|
||||||
"""Get the metrics from monitors and
|
"""Get the metrics from monitors and
|
||||||
notify information to message bus.
|
notify information to message bus.
|
||||||
|
|
|
@ -285,6 +285,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
|
||||||
self.assertTrue(log_mock.info.called)
|
self.assertTrue(log_mock.info.called)
|
||||||
self.assertIsNone(self.compute._resource_tracker)
|
self.assertIsNone(self.compute._resource_tracker)
|
||||||
|
|
||||||
|
@mock.patch.object(manager.ComputeManager, '_get_resource_tracker')
|
||||||
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
|
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
|
||||||
'delete_resource_provider')
|
'delete_resource_provider')
|
||||||
@mock.patch.object(manager.ComputeManager,
|
@mock.patch.object(manager.ComputeManager,
|
||||||
|
@ -292,7 +293,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
|
||||||
@mock.patch.object(fake_driver.FakeDriver, 'get_available_nodes')
|
@mock.patch.object(fake_driver.FakeDriver, 'get_available_nodes')
|
||||||
@mock.patch.object(manager.ComputeManager, '_get_compute_nodes_in_db')
|
@mock.patch.object(manager.ComputeManager, '_get_compute_nodes_in_db')
|
||||||
def test_update_available_resource(self, get_db_nodes, get_avail_nodes,
|
def test_update_available_resource(self, get_db_nodes, get_avail_nodes,
|
||||||
update_mock, del_rp_mock):
|
update_mock, del_rp_mock, mock_get_rt):
|
||||||
db_nodes = [self._make_compute_node('node%s' % i, i)
|
db_nodes = [self._make_compute_node('node%s' % i, i)
|
||||||
for i in range(1, 5)]
|
for i in range(1, 5)]
|
||||||
avail_nodes = set(['node2', 'node3', 'node4', 'node5'])
|
avail_nodes = set(['node2', 'node3', 'node4', 'node5'])
|
||||||
|
@ -313,6 +314,8 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
|
||||||
db_node.destroy.assert_called_once_with()
|
db_node.destroy.assert_called_once_with()
|
||||||
del_rp_mock.assert_called_once_with(self.context, db_node,
|
del_rp_mock.assert_called_once_with(self.context, db_node,
|
||||||
cascade=True)
|
cascade=True)
|
||||||
|
mock_get_rt.return_value.remove_node.assert_called_once_with(
|
||||||
|
'node1')
|
||||||
else:
|
else:
|
||||||
self.assertFalse(db_node.destroy.called)
|
self.assertFalse(db_node.destroy.called)
|
||||||
|
|
||||||
|
|
|
@ -1189,6 +1189,28 @@ class TestInitComputeNode(BaseTestCase):
|
||||||
42)
|
42)
|
||||||
self.assertTrue(update_mock.called)
|
self.assertTrue(update_mock.called)
|
||||||
|
|
||||||
|
@mock.patch('nova.objects.ComputeNodeList.get_by_hypervisor')
|
||||||
|
@mock.patch('nova.objects.PciDeviceList.get_by_compute_node',
|
||||||
|
return_value=objects.PciDeviceList(objects=[]))
|
||||||
|
@mock.patch('nova.objects.ComputeNode.create')
|
||||||
|
@mock.patch('nova.objects.ComputeNode.get_by_host_and_nodename')
|
||||||
|
@mock.patch('nova.compute.resource_tracker.ResourceTracker.'
|
||||||
|
'_update')
|
||||||
|
def test_node_removed(self, update_mock, get_mock,
|
||||||
|
create_mock, pci_tracker_mock,
|
||||||
|
get_by_hypervisor_mock):
|
||||||
|
self._test_compute_node_created(update_mock, get_mock, create_mock,
|
||||||
|
pci_tracker_mock,
|
||||||
|
get_by_hypervisor_mock)
|
||||||
|
self.rt.old_resources[_NODENAME] = mock.sentinel.foo
|
||||||
|
self.assertIn(_NODENAME, self.rt.compute_nodes)
|
||||||
|
self.assertIn(_NODENAME, self.rt.stats)
|
||||||
|
self.assertIn(_NODENAME, self.rt.old_resources)
|
||||||
|
self.rt.remove_node(_NODENAME)
|
||||||
|
self.assertNotIn(_NODENAME, self.rt.compute_nodes)
|
||||||
|
self.assertNotIn(_NODENAME, self.rt.stats)
|
||||||
|
self.assertNotIn(_NODENAME, self.rt.old_resources)
|
||||||
|
|
||||||
|
|
||||||
class TestUpdateComputeNode(BaseTestCase):
|
class TestUpdateComputeNode(BaseTestCase):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue