Merge "convergence: add adopt support"
This commit is contained in:
commit
41e5d679cf
|
@ -259,6 +259,7 @@ class Resource(object):
|
|||
db_res = resource_objects.Resource.get_obj(context, resource_id)
|
||||
# TODO(sirushtim): Load stack from cache
|
||||
stack = stack_mod.Stack.load(context, db_res.stack_id)
|
||||
stack.adopt_stack_data = data.get('adopt_stack_data')
|
||||
# NOTE(sirushtim): Because on delete/cleanup operations, we simply
|
||||
# update with another template, the stack object won't have the
|
||||
# template of the previous stack-run.
|
||||
|
@ -676,7 +677,11 @@ class Resource(object):
|
|||
set(data[u'id'] for data in resource_data.values()
|
||||
if data is not None)
|
||||
)
|
||||
runner = scheduler.TaskRunner(self.create)
|
||||
adopt_data = self.stack._adopt_kwargs(self)
|
||||
if adopt_data['resource_data'] is None:
|
||||
runner = scheduler.TaskRunner(self.create)
|
||||
else:
|
||||
runner = scheduler.TaskRunner(self.adopt, **adopt_data)
|
||||
runner()
|
||||
|
||||
@scheduler.wrappertask
|
||||
|
|
|
@ -688,7 +688,6 @@ class EngineService(service.Service):
|
|||
six.text_type(ex))
|
||||
|
||||
def _stack_create(stack):
|
||||
_create_stack_user(stack)
|
||||
# Create/Adopt a stack, and create the periodic task if successful
|
||||
if stack.adopt_stack_data:
|
||||
stack.adopt()
|
||||
|
@ -710,14 +709,15 @@ class EngineService(service.Service):
|
|||
nested_depth, user_creds_id, stack_user_project_id, convergence,
|
||||
parent_resource_name)
|
||||
|
||||
# once validations are done
|
||||
# if convergence is enabled, take convergence path
|
||||
stack.store()
|
||||
_create_stack_user(stack)
|
||||
if convergence:
|
||||
# TODO(later): call _create_stack_user(stack)
|
||||
# call stack.converge_stack(template=stack.t, action=stack.CREATE)
|
||||
raise exception.NotSupported(feature=_('Convergence engine'))
|
||||
action = stack.CREATE
|
||||
if stack.adopt_stack_data:
|
||||
action = stack.ADOPT
|
||||
stack.converge_stack(template=stack.t, action=action)
|
||||
else:
|
||||
stack.store()
|
||||
self.thread_group_mgr.start_with_lock(cnxt, stack, self.engine_id,
|
||||
_stack_create, stack)
|
||||
|
||||
|
@ -782,8 +782,6 @@ class EngineService(service.Service):
|
|||
self._validate_deferred_auth_context(cnxt, updated_stack)
|
||||
updated_stack.validate()
|
||||
|
||||
# Once all the validations are done
|
||||
# if convergence is enabled, take the convergence path
|
||||
if current_kwargs['convergence']:
|
||||
current_stack.converge_stack(template=tmpl,
|
||||
new_stack=updated_stack)
|
||||
|
|
|
@ -939,7 +939,7 @@ class Stack(collections.Mapping):
|
|||
"""
|
||||
Updates the stack and triggers convergence for resources
|
||||
"""
|
||||
if action is not self.CREATE:
|
||||
if action not in [self.CREATE, self.ADOPT]:
|
||||
# no back-up template for create action
|
||||
self.prev_raw_template_id = getattr(self.t, 'id', None)
|
||||
|
||||
|
@ -995,9 +995,11 @@ class Stack(collections.Mapping):
|
|||
LOG.info(_LI("Triggering resource %(rsrc_id)s "
|
||||
"for %(is_update)s update"),
|
||||
{'rsrc_id': rsrc_id, 'is_update': is_update})
|
||||
input_data = {'input_data': {},
|
||||
'adopt_stack_data': self.adopt_stack_data}
|
||||
self.worker_client.check_resource(self.context, rsrc_id,
|
||||
self.current_traversal,
|
||||
{}, is_update)
|
||||
input_data, is_update)
|
||||
|
||||
def _get_best_existing_rsrc_db(self, rsrc_name):
|
||||
candidate = None
|
||||
|
|
|
@ -123,7 +123,7 @@ class WorkerService(service.Service):
|
|||
stack.state_set(stack.action, stack.FAILED, failure_reason)
|
||||
|
||||
if (not stack.disable_rollback and
|
||||
stack.action in (stack.CREATE, stack.UPDATE)):
|
||||
stack.action in (stack.CREATE, stack.ADOPT, stack.UPDATE)):
|
||||
self._trigger_rollback(cnxt, stack)
|
||||
else:
|
||||
stack.purge_db()
|
||||
|
@ -137,11 +137,13 @@ class WorkerService(service.Service):
|
|||
The node may be associated with either an update or a cleanup of its
|
||||
associated resource.
|
||||
'''
|
||||
adopt_data = data.get('adopt_stack_data')
|
||||
data = dict(sync_point.deserialize_input_data(data))
|
||||
try:
|
||||
cache_data = {in_data.get(
|
||||
'name'): in_data for in_data in data.values()
|
||||
if in_data is not None}
|
||||
cache_data['adopt_stack_data'] = adopt_data
|
||||
rsrc, stack = resource.Resource.load(cnxt, resource_id, cache_data)
|
||||
except (exception.ResourceNotFound, exception.NotFound):
|
||||
return
|
||||
|
|
|
@ -212,7 +212,8 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
|
|||
for rsrc_id, is_update in leaves:
|
||||
expected_calls.append(
|
||||
mock.call.worker_client.WorkerClient.check_resource(
|
||||
stack.context, rsrc_id, stack.current_traversal, {},
|
||||
stack.context, rsrc_id, stack.current_traversal,
|
||||
{'input_data': {}, 'adopt_stack_data': None},
|
||||
is_update))
|
||||
self.assertEqual(expected_calls, mock_cr.mock_calls)
|
||||
|
||||
|
@ -268,7 +269,8 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
|
|||
for rsrc_id, is_update in leaves:
|
||||
expected_calls.append(
|
||||
mock.call.worker_client.WorkerClient.check_resource(
|
||||
stack.context, rsrc_id, stack.current_traversal, {},
|
||||
stack.context, rsrc_id, stack.current_traversal,
|
||||
{'input_data': {}, 'adopt_stack_data': None},
|
||||
is_update))
|
||||
self.assertEqual(expected_calls, mock_cr.mock_calls)
|
||||
|
||||
|
@ -403,7 +405,8 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
|
|||
for rsrc_id, is_update in leaves:
|
||||
expected_calls.append(
|
||||
mock.call.worker_client.WorkerClient.check_resource(
|
||||
stack.context, rsrc_id, stack.current_traversal, {},
|
||||
stack.context, rsrc_id, stack.current_traversal,
|
||||
{'input_data': {}, 'adopt_stack_data': None},
|
||||
is_update))
|
||||
|
||||
leaves = curr_stack.convergence_dependencies.leaves()
|
||||
|
@ -411,7 +414,8 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
|
|||
expected_calls.append(
|
||||
mock.call.worker_client.WorkerClient.check_resource(
|
||||
curr_stack.context, rsrc_id, curr_stack.current_traversal,
|
||||
{}, is_update))
|
||||
{'input_data': {}, 'adopt_stack_data': None},
|
||||
is_update))
|
||||
self.assertEqual(expected_calls, mock_cr.mock_calls)
|
||||
|
||||
def test_conv_empty_template_stack_update_delete(self, mock_cr):
|
||||
|
@ -482,7 +486,8 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
|
|||
for rsrc_id, is_update in leaves:
|
||||
expected_calls.append(
|
||||
mock.call.worker_client.WorkerClient.check_resource(
|
||||
stack.context, rsrc_id, stack.current_traversal, {},
|
||||
stack.context, rsrc_id, stack.current_traversal,
|
||||
{'input_data': {}, 'adopt_stack_data': None},
|
||||
is_update))
|
||||
|
||||
leaves = curr_stack.convergence_dependencies.leaves()
|
||||
|
@ -490,7 +495,8 @@ class StackConvergenceCreateUpdateDeleteTest(common.HeatTestCase):
|
|||
expected_calls.append(
|
||||
mock.call.worker_client.WorkerClient.check_resource(
|
||||
curr_stack.context, rsrc_id, curr_stack.current_traversal,
|
||||
{}, is_update))
|
||||
{'input_data': {}, 'adopt_stack_data': None},
|
||||
is_update))
|
||||
self.assertEqual(expected_calls, mock_cr.mock_calls)
|
||||
|
||||
def test_mark_complete_purges_db(self, mock_cr):
|
||||
|
|
|
@ -1430,6 +1430,7 @@ class ResourceTest(common.HeatTestCase):
|
|||
def test_create_convergence(self, mock_create):
|
||||
tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo')
|
||||
res = generic_rsrc.GenericResource('test_res', tmpl, self.stack)
|
||||
res.action = res.CREATE
|
||||
res._store()
|
||||
self._assert_resource_lock(res.id, None, None)
|
||||
res_data = {(1, True): {u'id': 1, u'name': 'A', 'attrs': {}},
|
||||
|
@ -1459,6 +1460,24 @@ class ResourceTest(common.HeatTestCase):
|
|||
self.assertItemsEqual([5, 3], res.requires)
|
||||
self._assert_resource_lock(res.id, None, 2)
|
||||
|
||||
@mock.patch.object(resource.Resource, 'adopt')
|
||||
def test_adopt_convergence(self, mock_adopt):
|
||||
tmpl = rsrc_defn.ResourceDefinition('test_res', 'Foo')
|
||||
res = generic_rsrc.GenericResource('test_res', tmpl, self.stack)
|
||||
res.action = res.ADOPT
|
||||
res._store()
|
||||
self.stack.adopt_stack_data = {'resources': {'test_res': {
|
||||
'resource_id': 'fluffy'}}}
|
||||
self._assert_resource_lock(res.id, None, None)
|
||||
res_data = {(1, True): {u'id': 5, u'name': 'A', 'attrs': {}},
|
||||
(2, True): {u'id': 3, u'name': 'B', 'attrs': {}}}
|
||||
res.create_convergence(res_data, 'engine-007')
|
||||
|
||||
mock_adopt.assert_called_once_with(
|
||||
resource_data={'resource_id': 'fluffy'})
|
||||
self.assertItemsEqual([5, 3], res.requires)
|
||||
self._assert_resource_lock(res.id, None, 2)
|
||||
|
||||
@mock.patch.object(resource.Resource, 'update')
|
||||
def test_update_convergence(self, mock_update):
|
||||
tmpl = rsrc_defn.ResourceDefinition('test_res',
|
||||
|
|
Loading…
Reference in New Issue