From 220796807396ad6aa8cc8f1fc9ff905253681896 Mon Sep 17 00:00:00 2001 From: Matt Riedemann Date: Fri, 21 Sep 2018 10:44:51 -0400 Subject: [PATCH] Ignore VirtDriverNotReady in _sync_power_states periodic task Change Ib0ec1012b74e9a9e74c8879f3feed5f9332b711f introduced a new VirtDriverNotReady exception which the ironic driver raises when asked to retrieve a list of nodes and ironic-api is not available, like if nova-compute is started before ironic-api. This is normal and meant to be self-healing, but we can get it in other periodic tasks besides update_available_resource which leads to ugly exception traces on startup in the logs. This adds handling for the exception in the _sync_power_states periodic task. Change-Id: Iaf29b9e7a92705ac8a2e7ef338b92f7f1203506d Closes-Bug: #1793768 (cherry picked from commit 6eb32bc40340fed631b9fce1245326e0ebc1c540) --- nova/compute/manager.py | 9 ++++++++- nova/tests/unit/compute/test_compute_mgr.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 03722d44eadf..3704a6783ed3 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -7470,7 +7470,14 @@ class ComputeManager(manager.Manager): expected_attrs=[], use_slave=True) - num_vm_instances = self.driver.get_num_instances() + try: + num_vm_instances = self.driver.get_num_instances() + except exception.VirtDriverNotReady as e: + # If the virt driver is not ready, like ironic-api not being up + # yet in the case of ironic, just log it and exit. + LOG.info('Skipping _sync_power_states periodic task due to: %s', e) + return + num_db_instances = len(db_instances) if num_vm_instances != num_db_instances: diff --git a/nova/tests/unit/compute/test_compute_mgr.py b/nova/tests/unit/compute/test_compute_mgr.py index a36e5f4218d7..3f16418b2a7c 100644 --- a/nova/tests/unit/compute/test_compute_mgr.py +++ b/nova/tests/unit/compute/test_compute_mgr.py @@ -1742,6 +1742,20 @@ class ComputeManagerUnitTestCase(test.NoDBTestCase): use_slave=True) mock_spawn.assert_called_once_with(mock.ANY, instance) + @mock.patch('nova.objects.InstanceList.get_by_host', new=mock.Mock()) + @mock.patch('nova.compute.manager.ComputeManager.' + '_query_driver_power_state_and_sync', + new_callable=mock.NonCallableMock) + def test_sync_power_states_virt_driver_not_ready(self, _mock_sync): + """"Tests that the periodic task exits early if the driver raises + VirtDriverNotReady. + """ + with mock.patch.object( + self.compute.driver, 'get_num_instances', + side_effect=exception.VirtDriverNotReady) as gni: + self.compute._sync_power_states(mock.sentinel.context) + gni.assert_called_once_with() + def _get_sync_instance(self, power_state, vm_state, task_state=None, shutdown_terminate=False): instance = objects.Instance()