Backup new resource as soon as possible
The root cause came discussion in https://review.openstack.org/#/c/175868/. It is better to copy a new resources that appears during stack-update to backup stack as soon as possible because it reduces time when backup stack is not synchronized with the existing stack. Change-Id: If104037225905dc9c504972864270d6e68e08d73
This commit is contained in:
parent
bc4255fe07
commit
3786262aed
@ -119,6 +119,19 @@ class StackUpdate(object):
|
||||
existing_res.state_set(existing_res.UPDATE, existing_res.COMPLETE)
|
||||
|
||||
self.existing_stack.add_resource(new_res)
|
||||
|
||||
# Save new resource definition to backup stack if it is not
|
||||
# present in backup stack template already
|
||||
# it allows to resolve all dependencies that existing resource
|
||||
# can have if it was copied to backup stack
|
||||
if (res_name not in
|
||||
self.previous_stack.t[self.previous_stack.t.RESOURCES]):
|
||||
LOG.debug("Backing up new Resource %s" % res_name)
|
||||
definition = new_res.t.reparse(self.previous_stack,
|
||||
new_res.stack.t)
|
||||
self.previous_stack.t.add_resource(definition)
|
||||
self.previous_stack.t.store(self.previous_stack.context)
|
||||
|
||||
yield new_res.create()
|
||||
|
||||
@scheduler.wrappertask
|
||||
@ -135,14 +148,13 @@ class StackUpdate(object):
|
||||
except resource.UpdateReplace:
|
||||
pass
|
||||
else:
|
||||
# Save resource definition to backup stack if it is not
|
||||
# present in backup stack template already
|
||||
if res_name not in self.previous_stack.t[
|
||||
self.previous_stack.t.RESOURCES]:
|
||||
definition = existing_res.t.reparse(self.previous_stack,
|
||||
existing_res.stack.t)
|
||||
self.previous_stack.t.add_resource(definition)
|
||||
self.previous_stack.t.store(self.previous_stack.context)
|
||||
# Save updated resource definition to backup stack
|
||||
# cause it allows the backup stack resources to be synchronized
|
||||
LOG.debug("Backing up updated Resource %s" % res_name)
|
||||
definition = existing_res.t.reparse(self.previous_stack,
|
||||
existing_res.stack.t)
|
||||
self.previous_stack.t.add_resource(definition)
|
||||
self.previous_stack.t.store(self.previous_stack.context)
|
||||
|
||||
LOG.info(_LI("Resource %(res_name)s for stack %(stack_name)s "
|
||||
"updated"),
|
||||
|
@ -1603,3 +1603,73 @@ class StackUpdateTest(common.HeatTestCase):
|
||||
self.stack.delete()
|
||||
self.assertEqual((stack.Stack.DELETE, stack.Stack.COMPLETE),
|
||||
self.stack.state)
|
||||
|
||||
def test_backup_stack_synchronized_after_update(self):
|
||||
"""Test when backup stack updated correctly during stack update.
|
||||
|
||||
Test checks the following scenario:
|
||||
1. Create stack
|
||||
2. Update stack (failed - so the backup should not be deleted)
|
||||
3. Update stack (failed - so the backup from step 2 should be updated)
|
||||
The test checks that backup stack is synchronized with the main stack.
|
||||
"""
|
||||
# create a stack
|
||||
tmpl_create = {
|
||||
'heat_template_version': '2013-05-23',
|
||||
'resources': {
|
||||
'Ares': {'type': 'GenericResourceType'}
|
||||
}
|
||||
}
|
||||
self.stack = stack.Stack(self.ctx, 'test_update_stack_backup',
|
||||
template.Template(tmpl_create),
|
||||
disable_rollback=True)
|
||||
self.stack.store()
|
||||
self.stack.create()
|
||||
self.assertEqual((stack.Stack.CREATE, stack.Stack.COMPLETE),
|
||||
self.stack.state)
|
||||
|
||||
# try to update a stack with a new resource that should be backed up
|
||||
tmpl_update = {
|
||||
'heat_template_version': '2013-05-23',
|
||||
'resources': {
|
||||
'Ares': {'type': 'GenericResourceType'},
|
||||
'Bres': {
|
||||
'type': 'ResWithComplexPropsAndAttrs',
|
||||
'properties': {
|
||||
'an_int': 0,
|
||||
}
|
||||
},
|
||||
'Cres': {
|
||||
'type': 'ResourceWithPropsType',
|
||||
'properties': {
|
||||
'Foo': {'get_resource': 'Bres'},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.patchobject(generic_rsrc.ResourceWithProps,
|
||||
'handle_create',
|
||||
side_effect=[Exception, Exception])
|
||||
|
||||
stack_with_new_resource = stack.Stack(
|
||||
self.ctx,
|
||||
'test_update_stack_backup',
|
||||
template.Template(tmpl_update))
|
||||
self.stack.update(stack_with_new_resource)
|
||||
self.assertEqual((stack.Stack.UPDATE, stack.Stack.FAILED),
|
||||
self.stack.state)
|
||||
# assert that backup stack has been updated correctly
|
||||
self.assertIn('Bres', self.stack._backup_stack())
|
||||
|
||||
# update the stack with resource that updated in-place
|
||||
tmpl_update['resources']['Bres']['properties']['an_int'] = 1
|
||||
updated_stack_second = stack.Stack(self.ctx,
|
||||
'test_update_stack_backup',
|
||||
template.Template(tmpl_update))
|
||||
self.stack.update(updated_stack_second)
|
||||
self.assertEqual((stack.Stack.UPDATE, stack.Stack.FAILED),
|
||||
self.stack.state)
|
||||
# assert that resource in backup stack also has been updated
|
||||
backup = self.stack._backup_stack()
|
||||
self.assertEqual(1, backup['Bres'].properties['an_int'])
|
||||
|
Loading…
Reference in New Issue
Block a user