From c2d33c3271370358d48553233b41bf9119d834fb Mon Sep 17 00:00:00 2001 From: EdLeafe Date: Wed, 26 Jul 2017 23:07:38 +0000 Subject: [PATCH] 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 Closes-Bug: #1706772 Change-Id: I4ebebcf221dfe29e2aa125f5956aec10108f8fbe --- nova/tests/unit/virt/ironic/test_driver.py | 11 +++++++++++ nova/virt/ironic/driver.py | 9 +++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/nova/tests/unit/virt/ironic/test_driver.py b/nova/tests/unit/virt/ironic/test_driver.py index dd608f2f3030..3330ddabf598 100644 --- a/nova/tests/unit/virt/ironic/test_driver.py +++ b/nova/tests/unit/virt/ironic/test_driver.py @@ -2077,6 +2077,17 @@ class IronicDriverTestCase(test.NoDBTestCase): mock_node.list_volume_connectors.assert_called_once_with( node_uuid, detail=True) + @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) + class IronicDriverSyncTestCase(IronicDriverTestCase): diff --git a/nova/virt/ironic/driver.py b/nova/virt/ironic/driver.py index ec30635d036b..940652e59426 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -589,10 +589,15 @@ 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("Failed to get the list of nodes from the Ironic " + "inventory. Error: %s", e) + except Exception as e: + LOG.error("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):