diff --git a/nova/tests/unit/virt/ironic/test_driver.py b/nova/tests/unit/virt/ironic/test_driver.py index 28882f54a5..14506e6fa0 100644 --- a/nova/tests/unit/virt/ironic/test_driver.py +++ b/nova/tests/unit/virt/ironic/test_driver.py @@ -21,6 +21,7 @@ from oslo_config import cfg from oslo_serialization import jsonutils from oslo_utils import uuidutils import six +from testtools.matchers import HasLength from nova.api.metadata import base as instance_metadata from nova.compute import power_state as nova_states @@ -500,6 +501,15 @@ class IronicDriverTestCase(test.NoDBTestCase): self.assertEqual(['instance-00000000', 'instance-00000001'], sorted(response)) + @mock.patch.object(cw.IronicClientWrapper, 'call') + @mock.patch.object(objects.Instance, 'get_by_uuid') + def test_list_instances_fail(self, mock_inst_by_uuid, mock_call): + mock_call.side_effect = exception.NovaException + response = self.driver.list_instances() + mock_call.assert_called_with("node.list", associated=True, limit=0) + self.assertFalse(mock_inst_by_uuid.called) + self.assertThat(response, HasLength(0)) + @mock.patch.object(cw.IronicClientWrapper, 'call') def test_list_instance_uuids(self, mock_call): num_nodes = 2 diff --git a/nova/virt/ironic/driver.py b/nova/virt/ironic/driver.py index 84c69ab5a5..6bd0e07480 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -457,6 +457,20 @@ class IronicDriver(virt_driver.ComputeDriver): except exception.InstanceNotFound: return False + def _get_node_list(self, **kwargs): + """Helper function to return the list of nodes. + + If unable to connect ironic server, an empty list is returned. + + :returns: a list of raw node from ironic + + """ + try: + node_list = self.ironicclient.call("node.list", **kwargs) + except exception.NovaException: + node_list = [] + return node_list + def list_instances(self): """Return the names of all the instances provisioned. @@ -465,8 +479,7 @@ class IronicDriver(virt_driver.ComputeDriver): """ # NOTE(lucasagomes): limit == 0 is an indicator to continue # pagination until there're no more values to be returned. - node_list = self.ironicclient.call("node.list", associated=True, - limit=0) + node_list = self._get_node_list(associated=True, limit=0) context = nova_context.get_admin_context() return [objects.Instance.get_by_uuid(context, i.instance_uuid).name @@ -480,9 +493,8 @@ class IronicDriver(virt_driver.ComputeDriver): """ # NOTE(lucasagomes): limit == 0 is an indicator to continue # pagination until there're no more values to be returned. - node_list = self.ironicclient.call("node.list", associated=True, - limit=0) - return list(n.instance_uuid for n in node_list) + return list(n.instance_uuid + for n in self._get_node_list(associated=True, limit=0)) def node_is_available(self, nodename): """Confirms a Nova hypervisor node exists in the Ironic inventory. @@ -514,9 +526,8 @@ class IronicDriver(virt_driver.ComputeDriver): def _refresh_cache(self): # NOTE(lucasagomes): limit == 0 is an indicator to continue # pagination until there're no more values to be returned. - node_list = self.ironicclient.call('node.list', detail=True, limit=0) node_cache = {} - for node in node_list: + for node in self._get_node_list(detail=True, limit=0): node_cache[node.uuid] = node self.node_cache = node_cache self.node_cache_time = time.time()