Store resources convergence-style in stack check/suspend/resume

If there are resources in a template that don't exist in the database at
the time of a stack check (or suspend or resume) operation, running the
stack check will cause them to be stored in the database. Since these
operations have not been converted to convergence (story 1727142), they do
not set the current_template_id as a convergence update would. If this
occurs then the stack will be unrecoverable.

To avoid this, when convergence is enabled store any missing resources in
the same manner that a convergence update would, prior to running the stack
check/suspend/resume.

Just in case, make sure the stack doesn't get stuck if we do end up in the
wrong state, by not trying to load a template with None as an ID.

Change-Id: Iedba67c5de39dc2d58938da5505dda5dd147c130
Story: #2003062
Task: 23101
This commit is contained in:
Zane Bitter 2018-07-20 17:30:57 -04:00
parent 99cbff3803
commit 8ca06cfeaf
2 changed files with 12 additions and 2 deletions

View File

@ -339,13 +339,14 @@ class Resource(status.ResourceStatus):
initial_stk_defn = latest_stk_defn = curr_stack.defn
using_new_template = db_res.current_template_id != curr_stack.t.id
current_template_id = db_res.current_template_id
using_new_template = (current_template_id != curr_stack.t.id and
current_template_id is not None)
will_create = (db_res.action == cls.INIT and
is_update and
current_traversal == curr_stack.current_traversal)
if using_new_template and not will_create:
# load the definition associated with the resource's template
current_template_id = db_res.current_template_id
current_template = template.Template.load(context,
current_template_id)
initial_stk_defn = curr_stack.defn.clone_with_new_template(

View File

@ -1214,6 +1214,9 @@ class Stack(collections.Mapping):
@profiler.trace('Stack.check', hide_args=False)
@reset_state_on_error
def check(self, notify=None):
if self.convergence:
self._update_or_store_resources()
self.updated_time = oslo_timeutils.utcnow()
checker = scheduler.TaskRunner(
self.stack_task, self.CHECK,
@ -1967,6 +1970,9 @@ class Stack(collections.Mapping):
LOG.info('%s is already suspended', self)
return
if self.convergence:
self._update_or_store_resources()
self.updated_time = oslo_timeutils.utcnow()
sus_task = scheduler.TaskRunner(
self.stack_task,
@ -1994,6 +2000,9 @@ class Stack(collections.Mapping):
LOG.info('%s is already resumed', self)
return
if self.convergence:
self._update_or_store_resources()
self.updated_time = oslo_timeutils.utcnow()
sus_task = scheduler.TaskRunner(
self.stack_task,