Ignore errors on old properties during update

When an update fails on a template resource, we still store the template
in the stack environment. Retrying the update will fail because of
missing parameters, but we can ignore those as they should be harmless
and only matter in this broken case.

Change-Id: I859ea72b1cc95162b6f498b6af65e4d9fdd9458f
Closes-Bug: #1543685
(cherry picked from commit 1cfde62b2f)
This commit is contained in:
Thomas Herve 2016-02-09 18:33:19 +01:00 committed by Jay Dobies
parent 7609d19468
commit 37c9f45663
2 changed files with 108 additions and 3 deletions

View File

@ -414,10 +414,24 @@ class Resource(object):
if psv.immutable():
immutable_set.add(psk)
def prop_changed(key):
try:
before = before_props.get(key)
except ValueError as exc:
# We shouldn't get here usually, but there is a known issue
# with template resources and new parameters in non-convergence
# stacks (see bug 1543685). The error should be harmless
# because we're on the before properties, which have presumably
# already been validated.
LOG.warning(_LW('Ignoring error in old property value '
'%(prop_name)s: %(msg)s'),
{'prop_name': key, 'msg': six.text_type(exc)})
return True
return before != after_props.get(key)
# Create a set of keys which differ (or are missing/added)
changed_properties_set = set(k for k in after_props
if before_props.get(k) !=
after_props.get(k))
changed_properties_set = set(k for k in after_props if prop_changed(k))
# Create a list of updated properties offending property immutability
update_replace_forbidden = [k for k in changed_properties_set

View File

@ -700,3 +700,94 @@ Resources:
exp = 'Resource CREATE failed: ValueError: %s: %s' % (exp_path,
exp_msg)
self.assertEqual(exp, stack.stack_status_reason)
class TemplateResourceNewParamTest(test.HeatIntegrationTest):
main_template = '''
heat_template_version: 2013-05-23
resources:
my_resource:
type: resource.yaml
properties:
value1: foo
'''
nested_templ = '''
heat_template_version: 2013-05-23
parameters:
value1:
type: string
resources:
test:
type: OS::Heat::TestResource
properties:
value: {get_param: value1}
'''
main_template_update = '''
heat_template_version: 2013-05-23
resources:
my_resource:
type: resource.yaml
properties:
value1: foo
value2: foo
'''
nested_templ_update_fail = '''
heat_template_version: 2013-05-23
parameters:
value1:
type: string
value2:
type: string
resources:
test:
type: OS::Heat::TestResource
properties:
fail: True
value:
str_replace:
template: VAL1-VAL2
params:
VAL1: {get_param: value1}
VAL2: {get_param: value2}
'''
nested_templ_update = '''
heat_template_version: 2013-05-23
parameters:
value1:
type: string
value2:
type: string
resources:
test:
type: OS::Heat::TestResource
properties:
value:
str_replace:
template: VAL1-VAL2
params:
VAL1: {get_param: value1}
VAL2: {get_param: value2}
'''
def setUp(self):
super(TemplateResourceNewParamTest, self).setUp()
self.client = self.orchestration_client
def test_update(self):
stack_identifier = self.stack_create(
template=self.main_template,
files={'resource.yaml': self.nested_templ})
# Make the update fails with the new parameter inserted.
self.update_stack(
stack_identifier,
self.main_template_update,
files={'resource.yaml': self.nested_templ_update_fail},
expected_status='UPDATE_FAILED')
# Fix the update, it should succeed now.
self.update_stack(
stack_identifier,
self.main_template_update,
files={'resource.yaml': self.nested_templ_update})