Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(814)

Unified Diff: recipe_modules/context/api.py

Issue 2985323002: Add support for LUCI_CONTEXT.
Patch Set: Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: recipe_modules/context/api.py
diff --git a/recipe_modules/context/api.py b/recipe_modules/context/api.py
index 1e53ce149f24043233733c80b301a333bd9d28ab..5a77154d1d015e81b3da90afde112784bc761ea0 100644
--- a/recipe_modules/context/api.py
+++ b/recipe_modules/context/api.py
@@ -28,17 +28,16 @@ with api.context(cwd=api.path['start_dir'].join('subdir')):
```
"""
-
import collections
-import os
-import types
+import copy
from contextlib import contextmanager
-from recipe_engine import recipe_api
from recipe_engine.config_types import Path
from recipe_engine.recipe_api import RecipeApi
+from libs import luci_context as luci_ctx
+
def check_type(name, var, expect):
if not isinstance(var, expect): # pragma: no cover
@@ -55,13 +54,17 @@ class ContextApi(RecipeApi):
self._cwd = [None]
self._env_prefixes = [{}]
self._env = [{}]
+ if self._test_data.enabled:
+ self._luci_context = [self._test_data.get('luci_context', {})]
+ else: # pragma: no cover
+ self._luci_context = [luci_ctx.read_full()]
self._infra_step = [False]
self._name_prefix = ['']
# this could be a number, but it makes the logic easier to use a stack.
self._nest_level = [0]
@contextmanager
- def __call__(self, cwd=None, env_prefixes=None, env=None,
+ def __call__(self, cwd=None, env_prefixes=None, env=None, luci_context=None,
increment_nest_level=None, infra_steps=None, name_prefix=None):
"""Allows adjustment of multiple context values in a single call.
@@ -72,6 +75,7 @@ class ContextApi(RecipeApi):
* env_prefixes (dict) - Environmental variable prefix augmentations. See
below for more info.
* env (dict) - Environmental variable overrides. See below for more info.
+ * luci_context (dict) - LUCI_CONTEXT overrides.
iannucci 2017/08/04 18:55:50 "see below for more info"
* increment_nest_level (True) - increment the nest level by 1 in this
context. Typically you won't directly interact with this, but should
use api.step.nest instead.
@@ -117,6 +121,17 @@ class ContextApi(RecipeApi):
defined in "env", it will be installed as the last path component if it is
not empty.
+ LUCI_CONTEXT overrides:
+
+ This is advanced stuff. LUCI_CONTEXT is used to pass ambient information
+ between layers of LUCI stack. 'luci_context' can be used to replace, add or
+ pop items in the current LUCI_CONTEXT. Unlike 'env', LUCI_CONTEXT contains
+ structured values, so values of 'luci_context' dict can be anything (not
+ only strings), and we are not attempting to merge them in any way, e.g
+ there's no equivalent of %(PATH)s trick.
iannucci 2017/08/04 18:55:50 we're going to delete the %(PATH) trick anyway, so
+
+ See https://github.com/luci/client-py/blob/master/LUCI_CONTEXT.md.
+
**TODO(iannucci): combine nest_level and name_prefix**
Look at the examples in "examples/" for examples of context module usage.
@@ -182,6 +197,20 @@ class ContextApi(RecipeApi):
new[k] = v
_push(self._env, new)
+ if luci_context is not None and len(luci_context) > 0:
+ check_type('luci_context', luci_context, dict)
+ new = dict(self._luci_context[-1])
+ for k, v in luci_context.iteritems():
+ k = str(k)
+ if v is None:
+ new.pop(k, None)
+ elif isinstance(v, dict):
+ new[k] = copy.deepcopy(v)
iannucci 2017/08/04 18:55:51 can we assert that v is serializable to json? Othe
+ else:
+ raise TypeError(
+ 'Bad type for LUCI_CONTEXT[%r]: %s', k, type(v).__name__)
+ _push(self._luci_context, new)
+
try:
yield
finally:
@@ -228,6 +257,20 @@ class ContextApi(RecipeApi):
return dict(self._env_prefixes[-1])
@property
+ def luci_context(self):
+ """Returns a dict with current state of LUCI_CONTEXT.
+
+ This is advanced stuff. LUCI_CONTEXT is used to pass ambient information
+ between layers of LUCI stack. Unlike 'env', it MAY be populated with
+ information about LUCI execution environment when recipe engine starts.
+
+ Do not dump the entirety of LUCI_CONTEXT into logs, it may contain secrets.
iannucci 2017/08/04 18:55:50 s/may contain/contains make them scared :)
+
+ See https://github.com/luci/client-py/blob/master/LUCI_CONTEXT.md.
+ """
+ return dict(self._luci_context[-1])
+
+ @property
def infra_step(self):
"""Returns the current value of the infra_step setting.

Powered by Google App Engine
This is Rietveld 408576698