Use original request context for logging

The various Oslo libraries call oslo_context.context.get_current() to get
the current context for various purposes such as logging. This is a
thread-local variable, so this patch ensures that it is set in the
asynchronous threads that we spawn for various long-running tasks. It also
ensures that we pass overwrite=False when creating new contexts (e.g.
reconstructing a stored context from a stack in the database) so that we
don't overwrite the thread-local variable.

Change-Id: Ic81eda7cb1dddfa72421119a6fe26a093eee3aab
This commit is contained in:
Zane Bitter 2016-05-16 17:38:02 -04:00
parent 2cbcd6f41b
commit e7a3b38c47
7 changed files with 22 additions and 15 deletions

View File

@ -86,7 +86,9 @@ class RequestContext(context.RequestContext):
show_deleted=show_deleted,
request_id=request_id,
user_domain=user_domain_id,
project_domain=project_domain_id)
project_domain=project_domain_id,
roles=roles,
overwrite=overwrite)
self.username = username
self.user_id = user_id
@ -96,7 +98,6 @@ class RequestContext(context.RequestContext):
self.tenant_id = tenant_id
self.auth_token_info = auth_token_info
self.auth_url = auth_url
self.roles = roles or []
self._session = None
self._clients = None
self.trust_id = trust_id

View File

@ -220,8 +220,9 @@ class KeystoneClientV3(object):
raise exception.MissingCredentialError(
required=_("roles %s") % roles)
trust_context = context.RequestContext.from_dict(
self.context.to_dict())
context_data = self.context.to_dict()
context_data['overwrite'] = False
trust_context = context.RequestContext.from_dict(context_data)
trust_context.trust_id = trust.id
trust_context.trustor_user_id = trustor_user_id
return trust_context

View File

@ -118,7 +118,8 @@ class RemoteStack(resource.Resource):
# Build RequestContext from existing one
dict_ctxt = self.context.to_dict()
dict_ctxt.update({'region_name': self._region_name})
dict_ctxt.update({'region_name': self._region_name,
'overwrite': False})
self._local_context = context.RequestContext.from_dict(dict_ctxt)
return self._local_context

View File

@ -19,6 +19,7 @@ import socket
import eventlet
from oslo_config import cfg
from oslo_context import context as oslo_context
from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_serialization import jsonutils
@ -113,9 +114,11 @@ class ThreadGroupManager(object):
}
return trace_info
def _start_with_trace(self, trace, func, *args, **kwargs):
def _start_with_trace(self, cnxt, trace, func, *args, **kwargs):
if trace:
profiler.init(**trace)
if cnxt is not None:
cnxt.update_store()
return func(*args, **kwargs)
def start(self, stack_id, func, *args, **kwargs):
@ -131,7 +134,8 @@ class ThreadGroupManager(object):
except BaseException:
pass
th = self.groups[stack_id].add_thread(self._start_with_trace,
req_cnxt = oslo_context.get_current()
th = self.groups[stack_id].add_thread(self._start_with_trace, req_cnxt,
self._serialize_profile_info(),
func, *args, **kwargs)
th.link(log_exceptions)

View File

@ -281,6 +281,8 @@ class Stack(collections.Mapping):
# We don't store roles in the user_creds table, so disable the
# policy check for admin by setting is_admin=False.
creds['is_admin'] = False
creds['overwrite'] = False
return common_context.RequestContext.from_dict(creds)
else:
msg = _("Attempt to use stored_context with no user_creds")

View File

@ -14,6 +14,8 @@
import eventlet
import mock
from oslo_context import context
from heat.engine import service
from heat.tests import common
@ -61,7 +63,7 @@ class ThreadGroupManagerTest(common.HeatTestCase):
self.assertEqual(self.tg_mock, thm.groups['test'])
self.tg_mock.add_thread.assert_called_with(
thm._start_with_trace, None,
thm._start_with_trace, context.get_current(), None,
self.f, *self.fargs, **self.fkwargs)
self.assertEqual(ret, self.tg_mock.add_thread())

View File

@ -305,13 +305,9 @@ class DummyThreadGroup(object):
def stop_timers(self):
pass
def add_thread(self, callback, *args, **kwargs):
# just to make _start_with_trace() easier to test:
# callback == _start_with_trace
# args[0] == trace_info
# args[1] == actual_callback
callback = args[1]
self.threads.append(callback)
def add_thread(self, callback, cnxt, trace, func, *args, **kwargs):
# callback here is _start_with_trace(); func is the 'real' callback
self.threads.append(func)
return DummyThread()
def stop(self, graceful=False):