summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2016-03-21 21:25:15 +0000
committerGerrit Code Review <review@openstack.org>2016-03-21 21:25:15 +0000
commit649e45eaef6699e31f713a2c9001ffbe06e604d2 (patch)
treeb8559c45fb3ca7c878d6d0c21a2f60bf10a5405c
parenta0b640343c54071dfeea68282cf844affdade2d0 (diff)
parentadd1884959bf5fc630584ceaa23a4293b6bd7da5 (diff)
downloadironic-649e45eaef6699e31f713a2c9001ffbe06e604d2.tar.gz
Merge "Add ensure_thread_contain_context() to task_manager"
-rw-r--r--ironic/conductor/task_manager.py20
-rw-r--r--ironic/tests/unit/conductor/test_task_manager.py20
2 files changed, 40 insertions, 0 deletions
diff --git a/ironic/conductor/task_manager.py b/ironic/conductor/task_manager.py
index a136c27e3..3aed594ae 100644
--- a/ironic/conductor/task_manager.py
+++ b/ironic/conductor/task_manager.py
@@ -96,6 +96,7 @@ raised in the background thread.):
import futurist
from oslo_config import cfg
+from oslo_context import context as oslo_context
from oslo_log import log as logging
from oslo_utils import excutils
from oslo_utils import timeutils
@@ -134,6 +135,9 @@ def require_exclusive_lock(f):
task = args[0]
if task.shared:
raise exception.ExclusiveLockRequired()
+ # NOTE(lintan): This is a workaround to set the context of async tasks,
+ # which should contain an exclusive lock.
+ ensure_thread_contain_context(task.context)
return f(*args, **kwargs)
return wrapper
@@ -151,10 +155,26 @@ def acquire(context, node_id, shared=False, driver_name=None,
:returns: An instance of :class:`TaskManager`.
"""
+ # NOTE(lintan): This is a workaround to set the context of periodic tasks.
+ ensure_thread_contain_context(context)
return TaskManager(context, node_id, shared=shared,
driver_name=driver_name, purpose=purpose)
+def ensure_thread_contain_context(context):
+ """Ensure threading contains context
+
+ For async/periodic tasks, the context of local thread is missing.
+ Set it with request context and this is useful to log the request_id
+ in log messages.
+
+ :param context: Request context
+ """
+ if oslo_context.get_current():
+ return
+ context.update_store()
+
+
class TaskManager(object):
"""Context manager for tasks.
diff --git a/ironic/tests/unit/conductor/test_task_manager.py b/ironic/tests/unit/conductor/test_task_manager.py
index 6c6bac1d4..3f42e4f8d 100644
--- a/ironic/tests/unit/conductor/test_task_manager.py
+++ b/ironic/tests/unit/conductor/test_task_manager.py
@@ -19,8 +19,10 @@
import futurist
import mock
+from oslo_context import context as oslo_context
from oslo_utils import uuidutils
+from ironic.common import context
from ironic.common import driver_factory
from ironic.common import exception
from ironic.common import fsm
@@ -657,6 +659,7 @@ class ExclusiveLockDecoratorTestCase(tests_base.TestCase):
def setUp(self):
super(ExclusiveLockDecoratorTestCase, self).setUp()
self.task = mock.Mock(spec=task_manager.TaskManager)
+ self.task.context = self.context
self.args_task_first = (self.task, 1, 2)
self.args_task_second = (1, self.task, 2)
self.kwargs = dict(cat='meow', dog='wuff')
@@ -736,3 +739,20 @@ class ThreadExceptionTestCase(tests_base.TestCase):
self.future_mock.exception.assert_called_once_with()
self.assertIsNone(self.node.last_error)
self.assertTrue(log_mock.called)
+
+
+@mock.patch.object(oslo_context, 'get_current')
+class TaskManagerContextTestCase(tests_base.TestCase):
+ def setUp(self):
+ super(TaskManagerContextTestCase, self).setUp()
+ self.context = mock.Mock(spec=context.RequestContext)
+
+ def test_thread_without_context(self, context_get_mock):
+ context_get_mock.return_value = False
+ task_manager.ensure_thread_contain_context(self.context)
+ self.assertTrue(self.context.update_store.called)
+
+ def test_thread_with_context(self, context_get_mock):
+ context_get_mock.return_value = True
+ task_manager.ensure_thread_contain_context(self.context)
+ self.assertFalse(self.context.update_store.called)