Don't use stored context to reset stacks

The resetting of in-progress stacks at startup is done using an admin
context. No user actions (e.g. ReST API calls) are performed, so there is
no need to load the user context that is stored with the stack. (Nor is
the
current context rewritten to the database in the process of resetting the
state.)

Since loading the user context from the DB may result in a call to the
keystone API, eliminating this ensures that stacks can be reset
successfully even if heat-engine starts before keystone is available.

Also there is no need to resolve outputs data while reset stacks, so set
resolve_data=False when load stack.

Change-Id: I9379ef6cc6f1d3bbc2569ff2150795bfaffee430
Closes-Bug: #1570569
This commit is contained in:
huangtianhua 2016-05-24 18:36:46 +08:00
parent 3c181e8d1c
commit 9d239cc80e
4 changed files with 20 additions and 8 deletions

View File

@ -179,7 +179,7 @@ class ThreadGroupManager(object):
"""Callback function that will be passed to GreenThread.link().
Persist the stack state to COMPLETE and FAILED close to
releasing the lock to avoid race condtitions.
releasing the lock to avoid race conditions.
"""
if stack is not None and stack.action not in (
stack.DELETE, stack.ROLLBACK, stack.UPDATE):
@ -2221,7 +2221,9 @@ class EngineService(service.Service):
continue
stk = parser.Stack.load(cnxt, stack=s,
use_stored_context=True)
service_check_defer=True,
resource_validate=False,
resolve_data=False)
LOG.info(_LI('Engine %(engine)s went down when stack '
'%(stack_id)s was in action %(action)s'),
{'engine': engine_id, 'action': stk.action,

View File

@ -459,7 +459,8 @@ class Stack(collections.Mapping):
@classmethod
def load(cls, context, stack_id=None, stack=None, show_deleted=True,
use_stored_context=False, force_reload=False, cache_data=None,
resolve_data=True):
resolve_data=True, service_check_defer=False,
resource_validate=True):
"""Retrieve a Stack from the database."""
if stack is None:
stack = stack_object.Stack.get_by_id(
@ -476,7 +477,9 @@ class Stack(collections.Mapping):
return cls._from_db(context, stack,
use_stored_context=use_stored_context,
cache_data=cache_data, resolve_data=resolve_data)
cache_data=cache_data, resolve_data=resolve_data,
service_check_defer=service_check_defer,
resource_validate=resource_validate)
@classmethod
def load_all(cls, context, limit=None, marker=None, sort_keys=None,
@ -509,7 +512,8 @@ class Stack(collections.Mapping):
@classmethod
def _from_db(cls, context, stack, resolve_data=True,
use_stored_context=False, cache_data=None):
use_stored_context=False, cache_data=None,
service_check_defer=False, resource_validate=True):
template = tmpl.Template.load(
context, stack.raw_template_id, stack.raw_template)
return cls(context, stack.name, template,
@ -531,7 +535,9 @@ class Stack(collections.Mapping):
prev_raw_template_id=stack.prev_raw_template_id,
current_deps=stack.current_deps, cache_data=cache_data,
nested_depth=stack.nested_depth,
deleted_time=stack.deleted_at)
deleted_time=stack.deleted_at,
service_check_defer=service_check_defer,
resource_validate=resource_validate)
def get_kwargs_for_cloning(self, keep_status=False, only_db=False):
"""Get common kwargs for calling Stack() for cloning.

View File

@ -1351,7 +1351,9 @@ class StackServiceTest(common.HeatTestCase):
])
mock_stack_load.assert_called_once_with(self.ctx,
stack=db_stack,
use_stored_context=True)
service_check_defer=True,
resource_validate=False,
resolve_data=False)
self.assertTrue(lock2.release.called)
mock_thread.start_with_acquired_lock.assert_called_once_with(
fake_stack, lock1,

View File

@ -388,7 +388,9 @@ class StackTest(common.HeatTestCase):
prev_raw_template_id=None,
current_deps=None, cache_data=None,
nested_depth=0,
deleted_time=None)
deleted_time=None,
service_check_defer=False,
resource_validate=True)
self.m.ReplayAll()
stack.Stack.load(self.ctx, stack_id=self.stack.id)