summaryrefslogtreecommitdiff
path: root/heat
diff options
context:
space:
mode:
Diffstat (limited to 'heat')
-rw-r--r--heat/engine/resource.py74
-rw-r--r--heat/tests/test_resource.py4
2 files changed, 37 insertions, 41 deletions
diff --git a/heat/engine/resource.py b/heat/engine/resource.py
index 4275887a5..436fd3d61 100644
--- a/heat/engine/resource.py
+++ b/heat/engine/resource.py
@@ -1436,18 +1436,9 @@ class Resource(status.ResourceStatus):
resource_data and existing resource's requires, then updates the
resource by invoking the scheduler TaskRunner.
"""
- def update_templ_id_and_requires(persist=True):
- self.current_template_id = template_id
- self.requires = list(
- set(data.primary_key for data in resource_data.values()
- if data is not None)
- )
- if not persist:
- return
-
- self.store(lock=self.LOCK_RESPECT)
-
self._calling_engine_id = engine_id
+ new_requires = set(data.primary_key for data in resource_data.values()
+ if data is not None)
# Check that the resource type matches. If the type has changed by a
# legitimate substitution, the load()ed resource will already be of
@@ -1472,18 +1463,10 @@ class Resource(status.ResourceStatus):
raise failure
self.replaced_by = None
- runner = scheduler.TaskRunner(
- self.update, new_res_def,
- update_templ_func=update_templ_id_and_requires)
- try:
- runner(timeout=timeout, progress_callback=progress_callback)
- except UpdateReplace:
- raise
- except exception.UpdateInProgress:
- raise
- except BaseException:
- with excutils.save_and_reraise_exception():
- update_templ_id_and_requires(persist=True)
+ runner = scheduler.TaskRunner(self.update, new_res_def,
+ new_template_id=template_id,
+ new_requires=new_requires)
+ runner(timeout=timeout, progress_callback=progress_callback)
def preview_update(self, after, before, after_props, before_props,
prev_resource, check_init_complete=False):
@@ -1600,9 +1583,24 @@ class Resource(status.ResourceStatus):
return is_substituted
return False
+ def _persist_update_no_change(self, new_template_id):
+ """Persist an update where the resource is unchanged."""
+ if new_template_id is not None:
+ self.current_template_id = new_template_id
+ lock = (self.LOCK_RESPECT if self.stack.convergence
+ else self.LOCK_NONE)
+ if self.status == self.FAILED:
+ status_reason = _('Update status to COMPLETE for '
+ 'FAILED resource neither update '
+ 'nor replace.')
+ self.state_set(self.action, self.COMPLETE,
+ status_reason, lock=lock)
+ elif new_template_id is not None:
+ self.store(lock=lock)
+
@scheduler.wrappertask
def update(self, after, before=None, prev_resource=None,
- update_templ_func=None):
+ new_template_id=None, new_requires=None):
"""Return a task to update the resource.
Subclasses should provide a handle_update() method to customise update,
@@ -1623,8 +1621,7 @@ class Resource(status.ResourceStatus):
raise exception.ResourceFailure(exc, self, action)
elif after_external_id is not None:
LOG.debug("Skip update on external resource.")
- if update_templ_func is not None:
- update_templ_func(persist=True)
+ self._persist_update_no_change(new_template_id)
return
after_props, before_props = self._prepare_update_props(after, before)
@@ -1656,16 +1653,7 @@ class Resource(status.ResourceStatus):
raise failure
if not needs_update:
- if update_templ_func is not None:
- update_templ_func(persist=True)
- if self.status == self.FAILED:
- status_reason = _('Update status to COMPLETE for '
- 'FAILED resource neither update '
- 'nor replace.')
- lock = (self.LOCK_RESPECT if self.stack.convergence
- else self.LOCK_NONE)
- self.state_set(self.action, self.COMPLETE,
- status_reason, lock=lock)
+ self._persist_update_no_change(new_template_id)
return
if not self.stack.convergence:
@@ -1680,10 +1668,14 @@ class Resource(status.ResourceStatus):
self.updated_time = datetime.utcnow()
+ if new_requires is not None:
+ self.requires = list(set(self.requires) | new_requires)
+
with self._action_recorder(action, UpdateReplace):
after_props.validate()
self.properties = before_props
tmpl_diff = self.update_template_diff(after.freeze(), before)
+ old_template_id = self.current_template_id
try:
if tmpl_diff and self.needs_replace_with_tmpl_diff(tmpl_diff):
@@ -1691,19 +1683,23 @@ class Resource(status.ResourceStatus):
prop_diff = self.update_template_diff_properties(after_props,
before_props)
+
+ if new_template_id is not None:
+ self.current_template_id = new_template_id
+
yield self.action_handler_task(action,
args=[after, tmpl_diff,
prop_diff])
except UpdateReplace:
with excutils.save_and_reraise_exception():
+ self.current_template_id = old_template_id
self._prepare_update_replace(action)
self.t = after
self.reparse()
self._update_stored_properties()
- if update_templ_func is not None:
- # template/requires will be persisted by _action_recorder()
- update_templ_func(persist=False)
+ if new_requires is not None:
+ self.requires = list(new_requires)
yield self._break_if_required(
self.UPDATE, environment.HOOK_POST_UPDATE)
diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py
index a02bfb9e5..621aadd66 100644
--- a/heat/tests/test_resource.py
+++ b/heat/tests/test_resource.py
@@ -2366,10 +2366,10 @@ class ResourceTest(common.HeatTestCase):
self.assertEqual(new_temp.id, res.current_template_id)
# check if requires was updated
- self.assertItemsEqual([3, 4], res.requires)
+ self.assertItemsEqual([2, 3, 4], res.requires)
self.assertEqual(res.action, resource.Resource.UPDATE)
self.assertEqual(res.status, resource.Resource.FAILED)
- self._assert_resource_lock(res.id, None, 3)
+ self._assert_resource_lock(res.id, None, 2)
def test_update_resource_convergence_update_replace(self):
tmpl = template.Template({