|
@@ -51,6 +51,9 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path):
|
|
|
process with the requested log level. Additionally, raise a CalledProcessError if a process
|
|
|
exits with an error (or a warning for exit code 1, if that process matches the Borg local path).
|
|
|
|
|
|
+ If output log level is None, then instead of logging, capture output for each process and return
|
|
|
+ it as a dict from the process to its output.
|
|
|
+
|
|
|
For simplicity, it's assumed that the output buffer for each process is its stdout. But if any
|
|
|
stdouts are given to exclude, then for any matching processes, log from their stderr instead.
|
|
|
|
|
@@ -65,6 +68,7 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path):
|
|
|
if process.stdout or process.stderr
|
|
|
}
|
|
|
output_buffers = list(process_for_output_buffer.keys())
|
|
|
+ captured_outputs = collections.defaultdict(list)
|
|
|
|
|
|
# Log output for each process until they all exit.
|
|
|
while True:
|
|
@@ -99,7 +103,10 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path):
|
|
|
if len(last_lines) > ERROR_OUTPUT_MAX_LINE_COUNT:
|
|
|
last_lines.pop(0)
|
|
|
|
|
|
- logger.log(output_log_level, line)
|
|
|
+ if output_log_level is None:
|
|
|
+ captured_outputs[ready_process].append(line)
|
|
|
+ else:
|
|
|
+ logger.log(output_log_level, line)
|
|
|
|
|
|
still_running = False
|
|
|
|
|
@@ -133,6 +140,11 @@ def log_outputs(processes, exclude_stdouts, output_log_level, borg_local_path):
|
|
|
if not still_running:
|
|
|
break
|
|
|
|
|
|
+ if captured_outputs:
|
|
|
+ return {
|
|
|
+ process: '\n'.join(output_lines) for process, output_lines in captured_outputs.items()
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
def log_command(full_command, input_file, output_file):
|
|
|
'''
|
|
@@ -222,13 +234,14 @@ def execute_command_with_processes(
|
|
|
run as well. This is useful, for instance, for processes that are streaming output to a named
|
|
|
pipe that the given command is consuming from.
|
|
|
|
|
|
- If an open output file object is given, then write stdout to the file and only log stderr (but
|
|
|
- only if an output log level is set). If an open input file object is given, then read stdin from
|
|
|
- the file. If shell is True, execute the command within a shell. If an extra environment dict is
|
|
|
- given, then use it to augment the current environment, and pass the result into the command. If
|
|
|
- a working directory is given, use that as the present working directory when running the
|
|
|
- command. If a Borg local path is given, then for any matching command or process (regardless of
|
|
|
- arguments), treat exit code 1 as a warning instead of an error.
|
|
|
+ If an open output file object is given, then write stdout to the file and only log stderr. But
|
|
|
+ if output log level is None, instead suppress logging and return the captured output for (only)
|
|
|
+ the given command. If an open input file object is given, then read stdin from the file. If
|
|
|
+ shell is True, execute the command within a shell. If an extra environment dict is given, then
|
|
|
+ use it to augment the current environment, and pass the result into the command. If a working
|
|
|
+ directory is given, use that as the present working directory when running the command. If a
|
|
|
+ Borg local path is given, then for any matching command or process (regardless of arguments),
|
|
|
+ treat exit code 1 as a warning instead of an error.
|
|
|
|
|
|
Raise subprocesses.CalledProcessError if an error occurs while running the command or in the
|
|
|
upstream process.
|
|
@@ -259,9 +272,12 @@ def execute_command_with_processes(
|
|
|
process.kill()
|
|
|
raise
|
|
|
|
|
|
- log_outputs(
|
|
|
+ captured_outputs = log_outputs(
|
|
|
tuple(processes) + (command_process,),
|
|
|
(input_file, output_file),
|
|
|
output_log_level,
|
|
|
borg_local_path=borg_local_path,
|
|
|
)
|
|
|
+
|
|
|
+ if output_log_level is None:
|
|
|
+ return captured_outputs.get(command_process)
|