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
This commit is contained in:
huangtianhua 2016-12-12 09:45:05 +08:00
parent 947eaac03f
commit 82a11ceb72
2 changed files with 30 additions and 0 deletions

View File

@ -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,

View File

@ -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,