Use the stored property values of LaunchConfig

When we read from the LaunchConfig in order to e.g. scale up an
InstanceGroup or AWS AutoscalingGroup, we want to use the properties as
they were last set by a stack update. We don't want to re-resolve functions
using live data, since any changes would result in changes to existing
members when we generate the template for scaling up, and that can possibly
result in the replacement of said existing members.

Instead, use the property values that are stored in the database from the
last update. In the case of a stack update in convergence, we need to load
them when doing Stack.resource_by_refid(), since they're not included in
the cache_data.

Change-Id: I9da5efb2559f10b2dfe44281e2ba1e615a8c618b
Partially-Implements: blueprint stack-definition
This commit is contained in:
Zane Bitter 2017-07-19 17:35:39 -04:00
parent 0f5deef8bb
commit 9a21b8a5f3
2 changed files with 14 additions and 5 deletions

View File

@ -228,13 +228,14 @@ class InstanceGroup(stack_resource.StackResource):
def _get_conf_properties(self):
conf_refid = self.properties[self.LAUNCH_CONFIGURATION_NAME]
conf = self.stack.resource_by_refid(conf_refid)
props = dict((k, v) for k, v in conf.properties.items()
if k in conf.properties.data)
c_props = conf.frozen_definition().properties(conf.properties_schema,
conf.context)
props = {k: v for k, v in c_props.items() if k in c_props.data}
for key in [conf.BLOCK_DEVICE_MAPPINGS, conf.NOVA_SCHEDULER_HINTS]:
if props.get(key) is not None:
props[key] = list(dict((k, v) for k, v in prop.items()
if k in conf.properties.data[key][idx])
for idx, prop in enumerate(props[key]))
props[key] = [{k: v for k, v in prop.items()
if k in c_props.data[key][idx]}
for idx, prop in enumerate(props[key])]
if 'InstanceId' in props:
props = conf.rebuild_lc_properties(props['InstanceId'])
props['Tags'] = self._tags()

View File

@ -770,6 +770,14 @@ class Stack(collections.Mapping):
(r.UPDATE, r.COMPLETE),
(r.CHECK, r.COMPLETE)) and
(r.FnGetRefId() == refid or r.name == refid)):
if self.cache_data is not None and r.id is not None:
# We don't have resources loaded from the database at this
# point, so load the data for just this one from the DB.
db_res = resource_objects.Resource.get_obj(self.context,
r.id)
if db_res is not None:
r._load_data(db_res)
return r
def register_access_allowed_handler(self, credential_id, handler):