Don't re-bind environment for get_file during stack update

While we're in the process of updating a stack, we set the stack's
environment to the new, updated values. However, we don't want to change
existing resources' idea of their own values until we have explivitly done
an update of them to bring them into line with the new
template/environment. So when parsing a template snippet containing the
get_file intrinsic, store the files dict to which it will refer. get_file
will resolve to the new file only when the template has been updated.

Closes-Bug: #1445170
Change-Id: I8ec32b0e38389cd314e4b2b2d8c65f61f8a9c41e
(cherry picked from commit e4447e7b66)
This commit is contained in:
Zane Bitter 2015-04-16 17:20:05 -04:00 committed by Angus Salkeld
parent 012056009f
commit 370f3c98c5
2 changed files with 50 additions and 1 deletions

View File

@ -204,13 +204,18 @@ class GetFile(function.Function):
key.
"""
def __init__(self, stack, fn_name, args):
super(GetFile, self).__init__(stack, fn_name, args)
self.files = self.stack.t.files
def result(self):
args = function.resolve(self.args)
if not (isinstance(args, six.string_types)):
raise TypeError(_('Argument to "%s" must be a string') %
self.fn_name)
f = self.stack.t.files.get(args)
f = self.files.get(args)
if f is None:
fmt_data = {'fn_name': self.fn_name,
'file_key': args}

View File

@ -1083,6 +1083,50 @@ class HotStackTest(common.HeatTestCase):
self.assertEqual('xyz', self.stack['AResource'].properties['Foo'])
self.m.VerifyAll()
def test_update_modify_files_ok_replace(self):
tmpl = {
'heat_template_version': '2013-05-23',
'parameters': {},
'resources': {
'AResource': {
'type': 'ResourceWithPropsType',
'properties': {'Foo': {'get_file': 'foo'}}
}
}
}
self.m.StubOutWithMock(generic_rsrc.ResourceWithProps,
'update_template_diff')
self.stack = parser.Stack(self.ctx, 'update_test_stack',
template.Template(tmpl,
files={'foo': 'abc'}))
self.stack.store()
self.stack.create()
self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE),
self.stack.state)
updated_stack = parser.Stack(self.ctx, 'updated_stack',
template.Template(tmpl,
files={'foo': 'xyz'}))
def check_props(*args):
self.assertEqual('abc', self.stack['AResource'].properties['Foo'])
generic_rsrc.ResourceWithProps.update_template_diff(
{'Type': 'ResourceWithPropsType',
'Properties': {'Foo': 'xyz'}},
{'Type': 'ResourceWithPropsType',
'Properties': {'Foo': 'abc'}}
).WithSideEffects(check_props).AndRaise(resource.UpdateReplace)
self.m.ReplayAll()
self.stack.update(updated_stack)
self.assertEqual((parser.Stack.UPDATE, parser.Stack.COMPLETE),
self.stack.state)
self.assertEqual('xyz', self.stack['AResource'].properties['Foo'])
self.m.VerifyAll()
class StackAttributesTest(common.HeatTestCase):
"""