From d48b65ed53cd0e376198f443b6ea8913324876d6 Mon Sep 17 00:00:00 2001 From: Darko Poljak Date: Thu, 23 Jun 2016 10:56:37 +0200 Subject: [PATCH] Fix process error handling in local. --- cdist/exec/local.py | 9 ++++----- cdist/exec/util.py | 49 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/cdist/exec/local.py b/cdist/exec/local.py index e02a33aa..5a0a8644 100644 --- a/cdist/exec/local.py +++ b/cdist/exec/local.py @@ -207,14 +207,13 @@ class Local(object): env.update(message.env) try: - output = exec_util.call_get_output(command, env=env) - self.log.debug("Local output: {}".format(output)) + output, errout = exec_util.call_get_output(command, env=env) + self.log.debug("Local stdout: {}".format(output)) + self.log.debug("Local stderr: {}".format(errout)) if return_output: return output.decode() except subprocess.CalledProcessError as e: - raise cdist.Error("Command failed: " + " ".join(command) - + " with returncode: {} and output: {}".format( - e.returncode, e.output)) + exec_util.handle_called_process_error(e, command) except OSError as error: raise cdist.Error(" ".join(command) + ": " + error.args[1]) finally: diff --git a/cdist/exec/util.py b/cdist/exec/util.py index 983f455c..15430f13 100644 --- a/cdist/exec/util.py +++ b/cdist/exec/util.py @@ -20,20 +20,61 @@ # import subprocess +import sys from tempfile import TemporaryFile import cdist +STDERR_UNSUPPORTED = 'Not supported in this python version' + def call_get_output(command, env=None): """Run the given command with the given environment. - Return the stdout and stderr output as a byte string. + Return the tuple of stdout and stderr output as a byte strings. """ - assert isinstance(command, (list, tuple)), "list or tuple argument expected, got: {}".format(command) + + assert isinstance(command, (list, tuple)), ( + "list or tuple argument expected, got: {}".format(command)) + + if sys.version_info >= (3, 5): + return call_get_out_err(command, env) + else: + return (call_get_stdout(command, env), STDERR_UNSUPPORTED) + +def handle_called_process_error(err, command): + if sys.version_info >= (3, 5): + errout = err.stderr + else: + errout = STDERR_UNSUPPORTED + raise cdist.Error("Command failed: " + " ".join(command) + + " with returncode: {} and stdout: {}, stderr: {}".format( + err.returncode, err.output, errout)) + +def call_get_stdout(command, env=None): + """Run the given command with the given environment. + Return the stdout output as a byte string, stderr is ignored. + """ + assert isinstance(command, (list, tuple)), ( + "list or tuple argument expected, got: {}".format(command)) with TemporaryFile() as fout: - subprocess.check_call(command, env=env, - stdout=fout, stderr=subprocess.STDOUT) + subprocess.check_call(command, env=env, stdout=fout) fout.seek(0) output = fout.read() return output + +def call_get_out_err(command, env=None): + """Run the given command with the given environment. + Return the tuple of stdout and stderr output as a byte strings. + """ + assert isinstance(command, (list, tuple)), ( + "list or tuple argument expected, got: {}".format(command)) + + with TemporaryFile() as fout, TemporaryFile() as ferr: + subprocess.check_call(command, env=env, + stdout=fout, stderr=ferr) + fout.seek(0) + ferr.seek(0) + output = (fout.read(), ferr.read()) + + return output