Handle ironicclient failures in Ironic driver

The ironic driver uses ironicclient to get the list of nodes from the
Ironic service. If that service is not running, or something otherwise
prevents the ironicclient's call from succeeding, and unhandled
exception will occur. This patch adds a generic exception handler for
this call, logging an error and continuing.

Co-Authored-By: Lucas Alvares Gomes <lucasagomes@gmail.com>

Closes-Bug: #1706772

Conflicts:
      nova/tests/unit/virt/ironic/test_driver.py

NOTE(mriedem): The conflicts in the tests can be ignored since they
were just around some boot from volume and flavor migration tests
in Pike which don't exist in Ocata. Also, the _LE translation marker
has to be added back in for LOG.error in Ocata due to hacking checks.

Change-Id: I4ebebcf221dfe29e2aa125f5956aec10108f8fbe
(cherry picked from commit c2d33c3271)
This commit is contained in:
EdLeafe 2017-07-26 23:07:38 +00:00 committed by Matt Riedemann
parent c95cd011d0
commit c46f037a0f
2 changed files with 19 additions and 2 deletions

View File

@ -1745,6 +1745,17 @@ class IronicDriverTestCase(test.NoDBTestCase):
host_id = self.driver.network_binding_host_id(self.ctx, instance)
self.assertIsNone(host_id)
@mock.patch.object(FAKE_CLIENT, 'node')
@mock.patch.object(ironic_driver.LOG, 'error')
def test_ironicclient_bad_response(self, mock_error, mock_node):
mock_node.list.side_effect = [["node1", "node2"], Exception()]
result = self.driver._get_node_list()
mock_error.assert_not_called()
self.assertEqual(["node1", "node2"], result)
result = self.driver._get_node_list()
mock_error.assert_called_once()
self.assertEqual([], result)
@mock.patch.object(instance_metadata, 'InstanceMetadata')
@mock.patch.object(configdrive, 'ConfigDriveBuilder')

View File

@ -477,10 +477,16 @@ class IronicDriver(virt_driver.ComputeDriver):
:returns: a list of raw node from ironic
"""
node_list = []
try:
node_list = self.ironicclient.call("node.list", **kwargs)
except exception.NovaException:
node_list = []
except exception.NovaException as e:
LOG.error(_LE("Failed to get the list of nodes from the Ironic "
"inventory. Error: %s"), e)
except Exception as e:
LOG.error(_LE("An unknown error has occurred when trying "
"to get the list of nodes from the Ironic "
"inventory. Error: %s"), e)
return node_list
def list_instances(self):