Skip to content

Commit 7164477

Browse files
authored
refactor: Add log_std(out|err) bools to repo_utils that execute a subprocess (#2817)
While making a local patch to work around #2640, I found that I had a need for running a subprocess (`gcloud auth print-access-token`) via `repo_utils.execute_checked_stdout`. However, doing so would log that access token when debug logging was enabled via `RULES_PYTHON_REPO_DEBUG=1`. This is a security concern for us, so I hacked in an option to allow a particular `execute_(un)checked(_stdout)` call to disable logging stdout, stderr, or both. I figure this might be useful to others so I thought I'd upstream it. `execute_(un)checked(_stdout)` now support `log_stdout` and `log_stderr` bools that default to `True` (which is the same behavior as before this PR. When the subprocess writes to stdout and `log_stdout = False`, the logged message will show: ``` ===== stdout start ===== <log_stdout = False; skipping> ===== stdout end ===== ``` If the subprocess does not write to stdout, the debug log shows the same as before: ``` <stdout empty> ``` The above also applies for stderr, with text adjusted accordingly.
1 parent bb7b164 commit 7164477

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ END_UNRELEASED_TEMPLATE
7777

7878
{#v0-0-0-added}
7979
### Added
80-
* Nothing added.
80+
* Repo utilities `execute_unchecked`, `execute_checked`, and `execute_checked_stdout` now
81+
support `log_stdout` and `log_stderr` keyword arg booleans. When these are `True`
82+
(the default), the subprocess's stdout/stderr will be logged.
8183

8284
{#v0-0-0-removed}
8385
### Removed

python/private/repo_utils.bzl

+24-7
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ def _execute_internal(
9898
arguments,
9999
environment = {},
100100
logger = None,
101+
log_stdout = True,
102+
log_stderr = True,
101103
**kwargs):
102104
"""Execute a subprocess with debugging instrumentation.
103105
@@ -116,6 +118,10 @@ def _execute_internal(
116118
logger: optional `Logger` to use for logging execution details. Must be
117119
specified when using module_ctx. If not specified, a default will
118120
be created.
121+
log_stdout: If True (the default), write stdout to the logged message. Setting
122+
to False can be useful for large stdout messages or for secrets.
123+
log_stderr: If True (the default), write stderr to the logged message. Setting
124+
to False can be useful for large stderr messages or for secrets.
119125
**kwargs: additional kwargs to pass onto rctx.execute
120126
121127
Returns:
@@ -160,7 +166,7 @@ def _execute_internal(
160166
cwd = _cwd_to_str(mrctx, kwargs),
161167
timeout = _timeout_to_str(kwargs),
162168
env_str = _env_to_str(environment),
163-
output = _outputs_to_str(result),
169+
output = _outputs_to_str(result, log_stdout = log_stdout, log_stderr = log_stderr),
164170
))
165171
elif _is_repo_debug_enabled(mrctx):
166172
logger.debug((
@@ -171,7 +177,7 @@ def _execute_internal(
171177
op = op,
172178
status = "success" if result.return_code == 0 else "failure",
173179
return_code = result.return_code,
174-
output = _outputs_to_str(result),
180+
output = _outputs_to_str(result, log_stdout = log_stdout, log_stderr = log_stderr),
175181
))
176182

177183
result_kwargs = {k: getattr(result, k) for k in dir(result)}
@@ -183,6 +189,8 @@ def _execute_internal(
183189
mrctx = mrctx,
184190
kwargs = kwargs,
185191
environment = environment,
192+
log_stdout = log_stdout,
193+
log_stderr = log_stderr,
186194
),
187195
**result_kwargs
188196
)
@@ -220,7 +228,16 @@ def _execute_checked_stdout(*args, **kwargs):
220228
"""Calls execute_checked, but only returns the stdout value."""
221229
return _execute_checked(*args, **kwargs).stdout
222230

223-
def _execute_describe_failure(*, op, arguments, result, mrctx, kwargs, environment):
231+
def _execute_describe_failure(
232+
*,
233+
op,
234+
arguments,
235+
result,
236+
mrctx,
237+
kwargs,
238+
environment,
239+
log_stdout = True,
240+
log_stderr = True):
224241
return (
225242
"repo.execute: {op}: failure:\n" +
226243
" command: {cmd}\n" +
@@ -236,7 +253,7 @@ def _execute_describe_failure(*, op, arguments, result, mrctx, kwargs, environme
236253
cwd = _cwd_to_str(mrctx, kwargs),
237254
timeout = _timeout_to_str(kwargs),
238255
env_str = _env_to_str(environment),
239-
output = _outputs_to_str(result),
256+
output = _outputs_to_str(result, log_stdout = log_stdout, log_stderr = log_stderr),
240257
)
241258

242259
def _which_checked(mrctx, binary_name):
@@ -331,11 +348,11 @@ def _env_to_str(environment):
331348
def _timeout_to_str(kwargs):
332349
return kwargs.get("timeout", "<default timeout>")
333350

334-
def _outputs_to_str(result):
351+
def _outputs_to_str(result, log_stdout = True, log_stderr = True):
335352
lines = []
336353
items = [
337-
("stdout", result.stdout),
338-
("stderr", result.stderr),
354+
("stdout", result.stdout if log_stdout else "<log_stdout = False; skipping>"),
355+
("stderr", result.stderr if log_stderr else "<log_stderr = False; skipping>"),
339356
]
340357
for name, content in items:
341358
if content:

0 commit comments

Comments
 (0)