Fix restore with convergence

Handle the restore operation as a normal convergence update instead of a
legacy one.

Change-Id: I6ee46cdf7a8fdf89c58c9812d08af21c97fb0f9e
Related-Bug: #1687006
changes/92/465592/1
Thomas Herve 5 years ago
parent 53aff6561a
commit 42e3d02dbf
  1. 3
      heat/engine/check_resource.py
  2. 11
      heat/engine/service.py
  3. 24
      heat/engine/stack.py
  4. 7
      heat/tests/test_convg_stack.py

@ -77,7 +77,8 @@ class CheckResource(object):
return False
if (not stack.disable_rollback and
stack.action in (stack.CREATE, stack.ADOPT, stack.UPDATE)):
stack.action in (stack.CREATE, stack.ADOPT, stack.UPDATE,
stack.RESTORE)):
self._trigger_rollback(stack)
else:
stack.purge_db()

@ -2113,8 +2113,15 @@ class EngineService(service.ServiceBase):
# FIXME(pas-ha) has to be amended to deny restoring stacks
# that have disallowed for current user
self.thread_group_mgr.start_with_lock(cnxt, stack, self.engine_id,
_stack_restore, stack, snapshot)
if stack.convergence:
new_stack, tmpl = stack.restore_data(snapshot)
stack.thread_group_mgr = self.thread_group_mgr
stack.converge_stack(template=tmpl,
action=stack.RESTORE,
new_stack=new_stack)
else:
self.thread_group_mgr.start_with_lock(
cnxt, stack, self.engine_id, _stack_restore, stack, snapshot)
@context.request_context
def stack_list_snapshots(self, cnxt, stack_identity):

@ -922,7 +922,7 @@ class Stack(collections.Mapping):
if self.convergence and action in (
self.UPDATE, self.DELETE, self.CREATE,
self.ADOPT, self.ROLLBACK):
self.ADOPT, self.ROLLBACK, self.RESTORE):
# if convergence and stack operation is create/update/rollback/
# delete, stack lock is not used, hence persist state
updated = self._persist_state()
@ -940,7 +940,7 @@ class Stack(collections.Mapping):
# or action == UPDATE/DELETE/ROLLBACK. Else, it would
# be done before releasing the stack lock.
if status == self.IN_PROGRESS or action in (
self.UPDATE, self.DELETE, self.ROLLBACK):
self.UPDATE, self.DELETE, self.ROLLBACK, self.RESTORE):
self._persist_state()
def _log_status(self):
@ -1908,14 +1908,7 @@ class Stack(collections.Mapping):
data = snapshot.data['resources'].get(name)
scheduler.TaskRunner(rsrc.delete_snapshot, data)()
@profiler.trace('Stack.restore', hide_args=False)
@reset_state_on_error
def restore(self, snapshot):
"""Restore the given snapshot.
Invokes handle_restore on all resources.
"""
self.updated_time = oslo_timeutils.utcnow()
def restore_data(self, snapshot):
env = environment.Environment(snapshot.data['environment'])
files = snapshot.data['files']
template = tmpl.Template(snapshot.data['template'],
@ -1935,6 +1928,17 @@ class Stack(collections.Mapping):
newstack.parameters.set_stack_id(self.identifier())
return newstack, template
@reset_state_on_error
def restore(self, snapshot):
"""Restore the given snapshot.
Invokes handle_restore on all resources.
"""
self.updated_time = oslo_timeutils.utcnow()
newstack = self.restore_data(snapshot)[0]
updater = scheduler.TaskRunner(self.update_task, newstack,
action=self.RESTORE)
updater()

@ -663,15 +663,16 @@ class TestConvgStackStateSet(common.HeatTestCase):
self.assertIsNone(ret_val)
def test_state_set_stack_restore(self, mock_ps):
mock_ps.return_value = 'updated'
ret_val = self.stack.state_set(
self.stack.RESTORE, self.stack.IN_PROGRESS, 'Restore started')
self.assertTrue(mock_ps.called)
self.assertIsNone(ret_val)
self.assertEqual('updated', ret_val)
mock_ps.reset_mock()
ret_val = self.stack.state_set(
self.stack.RESTORE, self.stack.COMPLETE, 'Restore complete')
self.assertFalse(mock_ps.called)
self.assertIsNone(ret_val)
self.assertTrue(mock_ps.called)
self.assertEqual('updated', ret_val)
class TestConvgStackRollback(common.HeatTestCase):

Loading…
Cancel
Save