summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-03-19 21:09:46 +0000
committerGerrit Code Review <review@openstack.org>2020-03-19 21:09:46 +0000
commit105626f650902476f8149b2032ed6e3551346516 (patch)
treeef20841d60e3c517a67acd4919f080c664f0bdbf
parent97b7f2bc7e265e0f4aa952220f08bde374f42803 (diff)
parent9f8ff3960cd8915af4017da64dbeaf3a74383074 (diff)
downloadnova-stable/ocata.tar.gz
Merge "Hook resource_tracker to remove stale node information" into stable/ocataocata-eolstable/ocata
-rw-r--r--nova/compute/manager.py2
-rw-r--r--nova/compute/resource_tracker.py10
-rw-r--r--nova/tests/unit/compute/test_compute_mgr.py5
-rw-r--r--nova/tests/unit/compute/test_resource_tracker.py22
4 files changed, 38 insertions, 1 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index bc7c9eade6..2e82b90003 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -6663,6 +6663,7 @@ class ComputeManager(manager.Manager):
for nodename in nodenames:
self.update_available_resource_for_node(context, nodename)
+ rt = self._get_resource_tracker()
# Delete orphan compute node not reported by driver but still in db
for cn in compute_nodes_in_db:
if cn.hypervisor_hostname not in nodenames:
@@ -6672,6 +6673,7 @@ class ComputeManager(manager.Manager):
{'id': cn.id, 'hh': cn.hypervisor_hostname,
'nodes': nodenames})
cn.destroy()
+ rt.remove_node(cn.hypervisor_hostname)
# Delete the corresponding resource provider in placement,
# along with any associated allocations and inventory.
# TODO(cdent): Move use of reportclient into resource tracker.
diff --git a/nova/compute/resource_tracker.py b/nova/compute/resource_tracker.py
index 30ddaa6ddc..bd6125e041 100644
--- a/nova/compute/resource_tracker.py
+++ b/nova/compute/resource_tracker.py
@@ -542,6 +542,16 @@ class ResourceTracker(object):
# now copy rest to compute_node
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):
"""Get the metrics from monitors and
notify information to message bus.
diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py
index 2d3d8bc7c4..f5b1df0664 100644
--- a/nova/tests/unit/compute/test_compute_mgr.py
+++ b/nova/tests/unit/compute/test_compute_mgr.py
@@ -212,6 +212,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
self.assertTrue(log_mock.info.called)
self.assertIsNone(self.compute._resource_tracker)
+ @mock.patch.object(manager.ComputeManager, '_get_resource_tracker')
@mock.patch('nova.scheduler.client.report.SchedulerReportClient.'
'delete_resource_provider')
@mock.patch.object(manager.ComputeManager,
@@ -219,7 +220,7 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
@mock.patch.object(fake_driver.FakeDriver, 'get_available_nodes')
@mock.patch.object(manager.ComputeManager, '_get_compute_nodes_in_db')
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)
for i in range(1, 5)]
avail_nodes = set(['node2', 'node3', 'node4', 'node5'])
@@ -239,6 +240,8 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase):
db_node.destroy.assert_called_once_with()
del_rp_mock.assert_called_once_with(self.context, db_node,
cascade=True)
+ mock_get_rt.return_value.remove_node.assert_called_once_with(
+ 'node1')
else:
self.assertFalse(db_node.destroy.called)
diff --git a/nova/tests/unit/compute/test_resource_tracker.py b/nova/tests/unit/compute/test_resource_tracker.py
index c26d69c903..52b451b763 100644
--- a/nova/tests/unit/compute/test_resource_tracker.py
+++ b/nova/tests/unit/compute/test_resource_tracker.py
@@ -1162,6 +1162,28 @@ class TestInitComputeNode(BaseTestCase):
42)
self.assertTrue(self.sched_client_mock.update_resource_stats.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):