Merge "Save previous template on non convergence updates"
This commit is contained in:
commit
fbb09a416a
@ -892,6 +892,7 @@ class Stack(collections.Mapping):
|
||||
elif create_if_missing:
|
||||
kwargs = self.get_kwargs_for_cloning()
|
||||
kwargs['owner_id'] = self.id
|
||||
del(kwargs['prev_raw_template_id'])
|
||||
prev = type(self)(self.context, self.name, copy.deepcopy(self.t),
|
||||
**kwargs)
|
||||
prev.store(backup=True)
|
||||
@ -1125,8 +1126,19 @@ class Stack(collections.Mapping):
|
||||
'State invalid for %s' % action)
|
||||
return
|
||||
|
||||
self.state_set(action, self.IN_PROGRESS,
|
||||
'Stack %s started' % action)
|
||||
# Save a copy of the new template. To avoid two DB writes
|
||||
# we store the ID at the same time as the action/status
|
||||
prev_tmpl_id = self.prev_raw_template_id
|
||||
bu_tmpl = copy.deepcopy(newstack.t)
|
||||
self.prev_raw_template_id = bu_tmpl.store()
|
||||
self.action = action
|
||||
self.status = self.IN_PROGRESS
|
||||
self.status_reason = 'Stack %s started' % action
|
||||
notification.send(self)
|
||||
self._add_event(self.action, self.status, self.status_reason)
|
||||
self.store()
|
||||
if prev_tmpl_id is not None:
|
||||
raw_template_object.RawTemplate.delete(self.context, prev_tmpl_id)
|
||||
|
||||
if action == self.UPDATE:
|
||||
# Oldstack is useless when the action is not UPDATE , so we don't
|
||||
|
@ -114,6 +114,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||
self.assertEqual({'KeyName': 'test'}, stk.t.env.params)
|
||||
|
||||
with mock.patch('heat.engine.stack.Stack') as mock_stack:
|
||||
stk.update = mock.Mock()
|
||||
mock_stack.load.return_value = stk
|
||||
mock_stack.validate.return_value = None
|
||||
result = self.man.update_stack(self.ctx, stk.identifier(),
|
||||
@ -148,6 +149,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||
stk.t.env.params)
|
||||
|
||||
with mock.patch('heat.engine.stack.Stack') as mock_stack:
|
||||
stk.update = mock.Mock()
|
||||
mock_stack.load.return_value = stk
|
||||
mock_stack.validate.return_value = None
|
||||
result = self.man.update_stack(self.ctx, stk.identifier(),
|
||||
@ -209,6 +211,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||
'newfoo2.yaml': 'newfoo',
|
||||
'myother.yaml': 'myother'}
|
||||
with mock.patch('heat.engine.stack.Stack') as mock_stack:
|
||||
stk.update = mock.Mock()
|
||||
mock_stack.load.return_value = stk
|
||||
mock_stack.validate.return_value = None
|
||||
result = self.man.update_stack(self.ctx, stk.identifier(),
|
||||
@ -250,6 +253,7 @@ class ServiceStackUpdateTest(common.HeatTestCase):
|
||||
'parameters': {},
|
||||
'resource_registry': {'resources': {}}}
|
||||
with mock.patch('heat.engine.stack.Stack') as mock_stack:
|
||||
stk.update = mock.Mock()
|
||||
mock_stack.load.return_value = stk
|
||||
mock_stack.validate.return_value = None
|
||||
result = self.man.update_stack(self.ctx, stk.identifier(),
|
||||
|
@ -527,6 +527,39 @@ class StackTest(common.HeatTestCase):
|
||||
self.stack.update(newstack)
|
||||
self.assertIsNotNone(self.stack.updated_time)
|
||||
|
||||
def test_update_prev_raw_template(self):
|
||||
self.stack = stack.Stack(self.ctx, 'updated_time_test',
|
||||
self.tmpl)
|
||||
self.assertIsNone(self.stack.updated_time)
|
||||
self.stack.store()
|
||||
self.stack.create()
|
||||
|
||||
self.assertIsNone(self.stack.prev_raw_template_id)
|
||||
|
||||
tmpl = {'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Resources': {'R1': {'Type': 'GenericResourceType'}}}
|
||||
newstack = stack.Stack(self.ctx, 'updated_time_test',
|
||||
template.Template(tmpl))
|
||||
self.stack.update(newstack)
|
||||
self.assertIsNotNone(self.stack.prev_raw_template_id)
|
||||
prev_t = template.Template.load(self.ctx,
|
||||
self.stack.prev_raw_template_id)
|
||||
self.assertEqual(tmpl, prev_t.t)
|
||||
prev_id = self.stack.prev_raw_template_id
|
||||
|
||||
tmpl2 = {'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Resources': {'R2': {'Type': 'GenericResourceType'}}}
|
||||
newstack2 = stack.Stack(self.ctx, 'updated_time_test',
|
||||
template.Template(tmpl2))
|
||||
self.stack.update(newstack2)
|
||||
self.assertIsNotNone(self.stack.prev_raw_template_id)
|
||||
self.assertNotEqual(prev_id, self.stack.prev_raw_template_id)
|
||||
prev_t2 = template.Template.load(self.ctx,
|
||||
self.stack.prev_raw_template_id)
|
||||
self.assertEqual(tmpl2, prev_t2.t)
|
||||
self.assertRaises(exception.NotFound,
|
||||
template.Template.load, self.ctx, prev_id)
|
||||
|
||||
def test_access_policy_update(self):
|
||||
tmpl = {'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Resources': {
|
||||
|
@ -23,11 +23,13 @@ from heat.engine import scheduler
|
||||
from heat.engine import service
|
||||
from heat.engine import stack
|
||||
from heat.engine import template
|
||||
from heat.objects import stack as stack_object
|
||||
from heat.rpc import api as rpc_api
|
||||
from heat.tests import common
|
||||
from heat.tests import generic_resource as generic_rsrc
|
||||
from heat.tests import utils
|
||||
|
||||
|
||||
empty_template = template_format.parse('''{
|
||||
"HeatTemplateFormatVersion" : "2012-12-12",
|
||||
}''')
|
||||
@ -854,17 +856,21 @@ class StackUpdateTest(common.HeatTestCase):
|
||||
mock_create = self.patchobject(generic_rsrc.ResourceWithProps,
|
||||
'handle_create', side_effect=Exception)
|
||||
|
||||
with mock.patch.object(self.stack, 'state_set',
|
||||
side_effect=self.stack.state_set) as mock_state:
|
||||
with mock.patch.object(stack_object.Stack,
|
||||
'update_by_id') as mock_db_update:
|
||||
self.stack.update(updated_stack)
|
||||
self.assertEqual((stack.Stack.ROLLBACK, stack.Stack.COMPLETE),
|
||||
self.stack.state)
|
||||
self.assertEqual('abc', self.stack['AResource'].properties['Foo'])
|
||||
self.assertEqual(2, mock_state.call_count)
|
||||
self.assertEqual(('UPDATE', 'IN_PROGRESS'),
|
||||
mock_state.call_args_list[0][0][:2])
|
||||
self.assertEqual(('ROLLBACK', 'IN_PROGRESS'),
|
||||
mock_state.call_args_list[1][0][:2])
|
||||
self.assertEqual(5, mock_db_update.call_count)
|
||||
self.assertEqual('UPDATE',
|
||||
mock_db_update.call_args_list[0][0][2]['action'])
|
||||
self.assertEqual('IN_PROGRESS',
|
||||
mock_db_update.call_args_list[0][0][2]['status'])
|
||||
self.assertEqual('ROLLBACK',
|
||||
mock_db_update.call_args_list[1][0][2]['action'])
|
||||
self.assertEqual('IN_PROGRESS',
|
||||
mock_db_update.call_args_list[1][0][2]['status'])
|
||||
|
||||
mock_create.assert_called_once_with()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user