diff options
author | Zane Bitter <zbitter@redhat.com> | 2017-02-17 13:33:06 -0500 |
---|---|---|
committer | Zane Bitter <zbitter@redhat.com> | 2017-04-05 12:39:46 -0400 |
commit | 666930d1958cc34a85da9712a7e09200ad0ec030 (patch) | |
tree | 8d33938fc43af24734c04b9a91e8ffea43dc4e34 | |
parent | b5359cedf10dab59a11effb0ebed383ad23c73a6 (diff) | |
download | heat-666930d1958cc34a85da9712a7e09200ad0ec030.tar.gz |
Update NodeData in legacy path
In convergence stacks, we obtain the NodeData for the resources the current
resource depends on from the RPC message triggering the resource check. For
the legacy path, this change updates the NodeData in the StackDefinition
after each resource is created or updated.
This means that the legacy and convergence paths will be able to access
data about other resources in essentially the same way.
Change-Id: I61c61745d864de99b0127f4103a6c3a83379c516
Partially-Implements: blueprint stack-definition
-rw-r--r-- | heat/engine/stack.py | 6 | ||||
-rw-r--r-- | heat/engine/stk_defn.py | 11 | ||||
-rw-r--r-- | heat/engine/update.py | 9 | ||||
-rw-r--r-- | heat/tests/test_metadata_refresh.py | 9 |
4 files changed, 33 insertions, 2 deletions
diff --git a/heat/engine/stack.py b/heat/engine/stack.py index 097af9667..f89cfc9f4 100644 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -1092,11 +1092,15 @@ class Stack(collections.Mapping): lambda x: {}) @functools.wraps(getattr(resource.Resource, action_method)) + @scheduler.wrappertask def resource_action(r): # Find e.g resource.create and call it handle = getattr(r, action_method) - return handle(**handle_kwargs(r)) + yield handle(**handle_kwargs(r)) + + if action == self.CREATE: + stk_defn.update_resource_data(self.defn, r.name, r.node_data()) def get_error_wait_time(resource): return resource.cancel_grace_period() diff --git a/heat/engine/stk_defn.py b/heat/engine/stk_defn.py index bc96d7c0f..c07039bdb 100644 --- a/heat/engine/stk_defn.py +++ b/heat/engine/stk_defn.py @@ -219,6 +219,17 @@ class ResourceProxy(status.ResourceStatus): if k != attributes.SHOW_ATTR) +def update_resource_data(stack_definition, resource_name, resource_data): + """Store new resource state data for the specified resource. + + This function enables the legacy (non-convergence) path to store updated + NodeData as resources are created/updated in a single StackDefinition + that lasts for the entire lifetime of the stack operation. + """ + stack_definition._resource_data[resource_name] = resource_data + stack_definition._resources.pop(resource_name, None) + + def add_resource(stack_definition, resource_definition): """Insert the given resource definition into the stack definition. diff --git a/heat/engine/update.py b/heat/engine/update.py index de1599ccc..d6faeadf7 100644 --- a/heat/engine/update.py +++ b/heat/engine/update.py @@ -19,6 +19,7 @@ from heat.common.i18n import repr_wrapper from heat.engine import dependencies from heat.engine import resource from heat.engine import scheduler +from heat.engine import stk_defn from heat.objects import resource as resource_objects LOG = logging.getLogger(__name__) @@ -173,12 +174,20 @@ class StackUpdate(object): "%(stack_name)s updated", {'res_name': res_name, 'stack_name': self.existing_stack.name}) + + stk_defn.update_resource_data(self.existing_stack.defn, + res_name, + existing_res.node_data()) return else: self._check_replace_restricted(new_res) yield self._create_resource(new_res) + node_data = self.existing_stack[res_name].node_data() + stk_defn.update_resource_data(self.existing_stack.defn, res_name, + node_data) + def _update_in_place(self, existing_res, new_res, is_substituted=False): existing_snippet = self.existing_snippets[existing_res.name] prev_res = self.previous_stack.get(new_res.name) diff --git a/heat/tests/test_metadata_refresh.py b/heat/tests/test_metadata_refresh.py index 0675b735f..23720f4c0 100644 --- a/heat/tests/test_metadata_refresh.py +++ b/heat/tests/test_metadata_refresh.py @@ -150,7 +150,7 @@ class MetadataRefreshTest(common.HeatTestCase): @mock.patch.object(glance.GlanceClientPlugin, 'find_image_by_name_or_id') @mock.patch.object(instance.Instance, 'handle_create') @mock.patch.object(instance.Instance, 'check_create_complete') - @mock.patch.object(instance.Instance, 'FnGetAtt') + @mock.patch.object(instance.Instance, '_resolve_attribute') def test_FnGetAtt_metadata_updated(self, mock_get, mock_check, mock_handle, *args): """Tests that metadata gets updated when FnGetAtt return changes.""" @@ -172,6 +172,7 @@ class MetadataRefreshTest(common.HeatTestCase): # Initial resolution of the metadata stack.create() + self.assertEqual((stack.CREATE, stack.COMPLETE), stack.state) # Sanity check on S2 s2 = stack['S2'] @@ -182,6 +183,12 @@ class MetadataRefreshTest(common.HeatTestCase): content = self._get_metadata_content(s1.metadata_get()) self.assertEqual('s2-ip=10.0.0.1', content) + # This is not a terribly realistic test - the metadata updates below + # happen in run_alarm_action() in service_stack_watch, and actually + # operate on a freshly loaded stack so there's no cached attributes. + # Clear the attributes cache here to keep it passing. + s2.attributes.reset_resolved_values() + # Run metadata update to pick up the new value from S2 s1.metadata_update() s2.metadata_update() |