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
This commit is contained in:
Zane Bitter 2017-02-17 13:33:06 -05:00
parent b5359cedf1
commit 666930d195
4 changed files with 33 additions and 2 deletions

View File

@ -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()

View File

@ -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.

View File

@ -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)

View File

@ -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()