Fix update on failed stack

In the case of a dependant resource failing, a nested stack will not get
created, so we need to at least create an empty nested stack to allow
the update to work.

Change-Id: I2e83546801bce0da566ec8ef1322e30d695ff02a
Closes-bug: 1411103
This commit is contained in:
Angus Salkeld 2015-02-03 15:31:47 +10:00
parent 5bf2409ab7
commit aafbf6025c
2 changed files with 61 additions and 3 deletions

View File

@ -21,6 +21,7 @@ from heat.common import exception
from heat.common.i18n import _
from heat.common.i18n import _LI
from heat.common.i18n import _LW
from heat.common import template_format
from heat.engine import attributes
from heat.engine import environment
from heat.engine import resource
@ -255,12 +256,21 @@ class StackResource(resource.Resource):
def update_with_template(self, child_template, user_params=None,
timeout_mins=None):
"""Update the nested stack with the new template."""
if self.id is None:
self._store()
name = self.physical_resource_name()
nested_stack = self.nested()
if nested_stack is None:
raise exception.Error(_('Cannot update %s, stack not created')
% self.name)
# if the create failed for some reason and the nested
# stack was not created, we need to create an empty stack
# here so that the update will work.
empty_temp = template_format.parse(
"heat_template_version: '2013-05-23'")
stack_creator = self.create_with_template(empty_temp, {})
stack_creator.run_to_completion()
nested_stack = self.nested()
name = self.physical_resource_name()
stack = self._parse_nested_stack(name, child_template, user_params,
timeout_mins)
stack.validate()

View File

@ -337,6 +337,54 @@ Outputs:
self._stack_output(stack, 'value'))
class TemplateResourceUpdateFailedTest(test.HeatIntegrationTest):
"""Prove that we can do updates on a nested stack to fix a stack."""
main_template = '''
HeatTemplateFormatVersion: '2012-12-12'
Resources:
keypair:
Type: OS::Nova::KeyPair
Properties:
name: replace-this
save_private_key: false
server:
Type: server_fail.yaml
DependsOn: keypair
'''
nested_templ = '''
HeatTemplateFormatVersion: '2012-12-12'
Resources:
RealRandom:
Type: OS::Heat::RandomString
'''
def setUp(self):
super(TemplateResourceUpdateFailedTest, self).setUp()
self.client = self.orchestration_client
if self.conf.keypair_name:
self.keypair_name = self.conf.keypair_name
else:
self.keypair = self.create_keypair()
self.keypair_name = self.keypair.id
def test_update_on_failed_create(self):
# create a stack with "server" dependant on "keypair", but
# keypair fails, so "server" is not created properly.
# We then fix the template and it should succeed.
broken_templ = self.main_template.replace('replace-this',
self.keypair_name)
stack_identifier = self.stack_create(
template=broken_templ,
files={'server_fail.yaml': self.nested_templ},
expected_status='CREATE_FAILED')
fixed_templ = self.main_template.replace('replace-this',
test.rand_name())
self.update_stack(stack_identifier,
fixed_templ,
files={'server_fail.yaml': self.nested_templ})
class TemplateResourceAdoptTest(test.HeatIntegrationTest):
"""Prove that we can do template resource adopt/abandon."""