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 6eb32bc403)
This commit is contained in:
Matt Riedemann 2018-09-21 10:44:51 -04:00
parent 24531a3583
commit 2207968073
2 changed files with 22 additions and 1 deletions

View File

@ -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:

View File

@ -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()