From 82a11ceb727b3c8b93fd1e3bf82767f476ad973c Mon Sep 17 00:00:00 2001 From: huangtianhua Date: Mon, 12 Dec 2016 09:45:05 +0800 Subject: [PATCH] Do not replace failed server always Overrides needs_replace_failed() to decide whether to replace the server resource if it's in *_FAILED (except CHECK_FAILED). Blueprint: custom-update-replace-for-failed-resources Change-Id: I3e389fb7fb0762cbdada1e4c1da4cc8eac5e7214 --- .../engine/resources/openstack/nova/server.py | 10 ++++++++++ heat/tests/openstack/nova/test_server.py | 20 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/heat/engine/resources/openstack/nova/server.py b/heat/engine/resources/openstack/nova/server.py index 0c75ea8c37..5def99cdf8 100644 --- a/heat/engine/resources/openstack/nova/server.py +++ b/heat/engine/resources/openstack/nova/server.py @@ -1184,6 +1184,16 @@ class Server(server_base.BaseServer, sh.SchedulerHintsMixin, before_props.get(self.USER_DATA_UPDATE_POLICY)) return ud_update_policy == 'REPLACE' + def needs_replace_failed(self): + if not self.resource_id: + return True + + with self.client_plugin().ignore_not_found: + server = self.client().servers.get(self.resource_id) + return server.status in ('ERROR', 'DELETED', 'SOFT_DELETED') + + return True + def handle_update(self, json_snippet, tmpl_diff, prop_diff): updaters = super(Server, self).handle_update( json_snippet, diff --git a/heat/tests/openstack/nova/test_server.py b/heat/tests/openstack/nova/test_server.py index 9d762bc414..9aafeeaf30 100644 --- a/heat/tests/openstack/nova/test_server.py +++ b/heat/tests/openstack/nova/test_server.py @@ -2021,6 +2021,26 @@ class ServersTest(common.HeatTestCase): updater = scheduler.TaskRunner(server.update, update_template) self.assertRaises(resource.UpdateReplace, updater) + @mock.patch.object(nova.NovaClientPlugin, '_create') + def test_update_failed_server_not_replace(self, mock_create): + stack_name = 'update_failed_server_not_replace' + (tmpl, stack) = self._setup_test_stack(stack_name) + resource_defns = tmpl.resource_definitions(stack) + server = servers.Server('failed_not_replace', + resource_defns['WebServer'], stack) + update_props = tmpl.t['Resources']['WebServer']['Properties'].copy() + update_props['name'] = 'my_server' + update_template = server.t.freeze(properties=update_props) + server.action = server.CREATE + server.status = server.FAILED + server.resource_id = '6a953104-b874-44d2-a29a-26e7c367dc5c' + nova_server = self.fc.servers.list()[1] + nova_server.status = 'ACTIVE' + server.client = mock.Mock() + server.client().servers.get.return_value = nova_server + scheduler.TaskRunner(server.update, update_template)() + self.assertEqual((server.UPDATE, server.COMPLETE), server.state) + @mock.patch.object(servers.Server, 'prepare_for_replace') @mock.patch.object(nova.NovaClientPlugin, '_create') def test_server_update_server_userdata_ignore(self, mock_create,