From cce06a1e9855d9eed3f7c653200853f23466d791 Mon Sep 17 00:00:00 2001 From: Zhenzan Zhou Date: Wed, 15 Apr 2015 13:27:51 +0800 Subject: [PATCH] Bypass ironic server not available issue The ironic driver needs enhancement for exception handling. This patch is a workaround to make devstack with ironic enabled success. A more elegant patch should be made later in ironic driver for exception handling. Change-Id: Ibace25ad905a8278ecea4b02c69c59737a490d3a Closes-Bug: #1430616 --- nova/tests/unit/virt/ironic/test_driver.py | 10 +++++++++ nova/virt/ironic/driver.py | 25 ++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/nova/tests/unit/virt/ironic/test_driver.py b/nova/tests/unit/virt/ironic/test_driver.py index dfa6b5285c26..7c9d78435ff1 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 @@ -440,6 +441,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 a342e4ea982b..ba93ee89c3db 100644 --- a/nova/virt/ironic/driver.py +++ b/nova/virt/ironic/driver.py @@ -435,6 +435,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. @@ -443,8 +457,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 @@ -458,9 +471,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. @@ -492,9 +504,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()