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:
parent
012056009f
commit
370f3c98c5
@ -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}
|
||||
|
@ -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):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user