Move rollback logic to stack class
Currently stack rollback logic is in the worker class which makes stack rollback code to be duplicated to other places like the simulater tests. Change-Id: I2c907ca1c76b39addc22a5d8c36fb50c47af4785
This commit is contained in:
parent
bd7895c555
commit
90e2a26539
|
@ -1005,6 +1005,18 @@ class Stack(collections.Mapping):
|
|||
self.current_traversal,
|
||||
input_data, is_update)
|
||||
|
||||
def rollback(self):
|
||||
old_tmpl_id = self.prev_raw_template_id
|
||||
if old_tmpl_id is None:
|
||||
rollback_tmpl = tmpl.Template.create_empty_template(
|
||||
version=self.t.version)
|
||||
else:
|
||||
rollback_tmpl = tmpl.Template.load(self.context, old_tmpl_id)
|
||||
self.prev_raw_template_id = None
|
||||
self.store()
|
||||
|
||||
self.converge_stack(rollback_tmpl, action=self.ROLLBACK)
|
||||
|
||||
def _get_best_existing_rsrc_db(self, rsrc_name):
|
||||
candidate = None
|
||||
if self.ext_rsrcs_db:
|
||||
|
|
|
@ -28,7 +28,6 @@ from heat.engine import dependencies
|
|||
from heat.engine import resource
|
||||
from heat.engine import stack as parser
|
||||
from heat.engine import sync_point
|
||||
from heat.engine import template as templatem
|
||||
from heat.objects import resource as resource_objects
|
||||
from heat.rpc import listener_client
|
||||
from heat.rpc import worker_client as rpc_client
|
||||
|
@ -99,19 +98,10 @@ class WorkerService(service.Service):
|
|||
return True
|
||||
return False
|
||||
|
||||
def _trigger_rollback(self, cnxt, stack):
|
||||
def _trigger_rollback(self, stack):
|
||||
LOG.info(_LI("Triggering rollback of %(stack_name)s %(action)s "),
|
||||
{'action': stack.action, 'stack_name': stack.name})
|
||||
old_tmpl_id = stack.prev_raw_template_id
|
||||
if old_tmpl_id is None:
|
||||
rollback_tmpl = templatem.Template.create_empty_template(
|
||||
version=stack.t.version)
|
||||
else:
|
||||
rollback_tmpl = templatem.Template.load(cnxt, old_tmpl_id)
|
||||
stack.prev_raw_template_id = None
|
||||
stack.store()
|
||||
|
||||
stack.converge_stack(rollback_tmpl, action=stack.ROLLBACK)
|
||||
stack.rollback()
|
||||
|
||||
def _handle_resource_failure(self, cnxt, stack_id, traversal_id,
|
||||
failure_reason):
|
||||
|
@ -124,7 +114,7 @@ class WorkerService(service.Service):
|
|||
|
||||
if (not stack.disable_rollback and
|
||||
stack.action in (stack.CREATE, stack.ADOPT, stack.UPDATE)):
|
||||
self._trigger_rollback(cnxt, stack)
|
||||
self._trigger_rollback(stack)
|
||||
else:
|
||||
stack.purge_db()
|
||||
|
||||
|
|
|
@ -16,11 +16,9 @@
|
|||
import mock
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
from heat.engine import resource
|
||||
from heat.engine import stack
|
||||
from heat.engine import sync_point
|
||||
from heat.engine import template as templatem
|
||||
from heat.engine import worker
|
||||
from heat.rpc import worker_client
|
||||
from heat.tests import common
|
||||
|
@ -273,7 +271,7 @@ class CheckWorkflowUpdateTest(common.HeatTestCase):
|
|||
self.assertTrue(self.worker._trigger_rollback.called)
|
||||
# make sure the rollback is called on given stack
|
||||
call_args, call_kwargs = self.worker._trigger_rollback.call_args
|
||||
called_stack = call_args[1]
|
||||
called_stack = call_args[0]
|
||||
self.assertEqual(self.stack.id, called_stack.id)
|
||||
|
||||
def test_resource_cleanup_failure_triggers_rollback_if_enabled(
|
||||
|
@ -292,7 +290,7 @@ class CheckWorkflowUpdateTest(common.HeatTestCase):
|
|||
self.assertTrue(self.worker._trigger_rollback.called)
|
||||
# make sure the rollback is called on given stack
|
||||
call_args, call_kwargs = self.worker._trigger_rollback.call_args
|
||||
called_stack = call_args[1]
|
||||
called_stack = call_args[0]
|
||||
self.assertEqual(self.stack.id, called_stack.id)
|
||||
|
||||
def test_rollback_is_not_triggered_on_rollback_disabled_stack(
|
||||
|
@ -325,47 +323,6 @@ class CheckWorkflowUpdateTest(common.HeatTestCase):
|
|||
self.is_update)
|
||||
self.assertFalse(self.worker._trigger_rollback.called)
|
||||
|
||||
def test_trigger_rollback_uses_old_template_if_available(
|
||||
self, mock_cru, mock_crc, mock_pcr, mock_csc, mock_cid):
|
||||
# create a template and assign to stack as previous template
|
||||
t = template_format.parse(tools.wp_template)
|
||||
prev_tmpl = templatem.Template(t)
|
||||
prev_tmpl.store(context=self.ctx)
|
||||
self.stack.prev_raw_template_id = prev_tmpl.id
|
||||
# mock failure
|
||||
self.stack.action = self.stack.UPDATE
|
||||
self.stack.status = self.stack.FAILED
|
||||
self.stack.store()
|
||||
# mock converge_stack()
|
||||
self.stack.converge_stack = mock.Mock()
|
||||
# call trigger_rollbac
|
||||
self.worker._trigger_rollback(self.ctx, self.stack)
|
||||
|
||||
# Make sure stack converge is called with previous template
|
||||
self.assertTrue(self.stack.converge_stack.called)
|
||||
self.assertIsNone(self.stack.prev_raw_template_id)
|
||||
call_args, call_kwargs = self.stack.converge_stack.call_args
|
||||
template_used_for_rollback = call_args[0]
|
||||
self.assertEqual(prev_tmpl.id, template_used_for_rollback.id)
|
||||
|
||||
def test_trigger_rollback_uses_empty_template_if_prev_tmpl_not_available(
|
||||
self, mock_cru, mock_crc, mock_pcr, mock_csc, mock_cid):
|
||||
# mock create failure with no previous template
|
||||
self.stack.prev_raw_template_id = None
|
||||
self.stack.action = self.stack.CREATE
|
||||
self.stack.status = self.stack.FAILED
|
||||
self.stack.store()
|
||||
# mock converge_stack()
|
||||
self.stack.converge_stack = mock.Mock()
|
||||
# call trigger_rollback
|
||||
self.worker._trigger_rollback(self.ctx, self.stack)
|
||||
|
||||
# Make sure stack converge is called with empty template
|
||||
self.assertTrue(self.stack.converge_stack.called)
|
||||
call_args, call_kwargs = self.stack.converge_stack.call_args
|
||||
template_used_for_rollback = call_args[0]
|
||||
self.assertEqual({}, template_used_for_rollback['resources'])
|
||||
|
||||
def test_resource_update_failure_purges_db_for_stack_failure(
|
||||
self, mock_cru, mock_crc, mock_pcr, mock_csc, mock_cid):
|
||||
self.stack.disable_rollback = True
|
||||
|
|
|
@ -37,6 +37,7 @@ from heat.objects import stack as stack_object
|
|||
from heat.objects import stack_tag as stack_tag_object
|
||||
from heat.objects import user_creds as ucreds_object
|
||||
from heat.tests import common
|
||||
from heat.tests.engine import tools
|
||||
from heat.tests import fakes
|
||||
from heat.tests import generic_resource as generic_rsrc
|
||||
from heat.tests import utils
|
||||
|
@ -2208,3 +2209,53 @@ class StackKwargsForCloningTest(common.HeatTestCase):
|
|||
# just make sure that the kwargs are valid
|
||||
# (no exception should be raised)
|
||||
stack.Stack(ctx, utils.random_name(), tmpl, **res)
|
||||
|
||||
|
||||
class TestStackRollback(common.HeatTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestStackRollback, self).setUp()
|
||||
self.ctx = utils.dummy_context()
|
||||
self.stack = tools.get_stack('test_stack_rollback', self.ctx,
|
||||
template=tools.string_template_five,
|
||||
convergence=True)
|
||||
|
||||
def test_trigger_rollback_uses_old_template_if_available(self):
|
||||
# create a template and assign to stack as previous template
|
||||
t = template_format.parse(tools.wp_template)
|
||||
prev_tmpl = template.Template(t)
|
||||
prev_tmpl.store(context=self.ctx)
|
||||
self.stack.prev_raw_template_id = prev_tmpl.id
|
||||
# mock failure
|
||||
self.stack.action = self.stack.UPDATE
|
||||
self.stack.status = self.stack.FAILED
|
||||
self.stack.store()
|
||||
# mock converge_stack()
|
||||
self.stack.converge_stack = mock.Mock()
|
||||
# call trigger_rollbac
|
||||
self.stack.rollback()
|
||||
|
||||
# Make sure stack converge is called with previous template
|
||||
self.assertTrue(self.stack.converge_stack.called)
|
||||
self.assertIsNone(self.stack.prev_raw_template_id)
|
||||
call_args, call_kwargs = self.stack.converge_stack.call_args
|
||||
template_used_for_rollback = call_args[0]
|
||||
self.assertEqual(prev_tmpl.id, template_used_for_rollback.id)
|
||||
|
||||
def test_trigger_rollback_uses_empty_template_if_prev_tmpl_not_available(
|
||||
self):
|
||||
# mock create failure with no previous template
|
||||
self.stack.prev_raw_template_id = None
|
||||
self.stack.action = self.stack.CREATE
|
||||
self.stack.status = self.stack.FAILED
|
||||
self.stack.store()
|
||||
# mock converge_stack()
|
||||
self.stack.converge_stack = mock.Mock()
|
||||
# call trigger_rollback
|
||||
self.stack.rollback()
|
||||
|
||||
# Make sure stack converge is called with empty template
|
||||
self.assertTrue(self.stack.converge_stack.called)
|
||||
call_args, call_kwargs = self.stack.converge_stack.call_args
|
||||
template_used_for_rollback = call_args[0]
|
||||
self.assertEqual({}, template_used_for_rollback['resources'])
|
||||
|
|
Loading…
Reference in New Issue