summaryrefslogtreecommitdiffstats
path: root/openstack/common/processutils.py
diff options
context:
space:
mode:
authorMichael Still <mikal@stillhq.com>2013-05-06 16:45:09 +1000
committerMichael Still <mikal@stillhq.com>2013-05-07 08:36:33 +1000
commit3893ef8c807457e54ecaf02c001f4b31a5a58b14 (patch)
tree6ea0b322750ea7d65fc7fcc04af36a4405385e5a /openstack/common/processutils.py
parentf9d502228752bcb909e58cafacd1cd948d9a8206 (diff)
downloadoslo-3893ef8c807457e54ecaf02c001f4b31a5a58b14.tar.gz
oslo-3893ef8c807457e54ecaf02c001f4b31a5a58b14.tar.xz
oslo-3893ef8c807457e54ecaf02c001f4b31a5a58b14.zip
Import trycmd and ssh_execute from nova.
This change required adding basic unit tests as well as these were both untested in nova. Change-Id: If6843e57810198aab3c61f9eb3c3a6f42f710f7c
Diffstat (limited to 'openstack/common/processutils.py')
-rw-r--r--openstack/common/processutils.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/openstack/common/processutils.py b/openstack/common/processutils.py
index 560055e..09baea3 100644
--- a/openstack/common/processutils.py
+++ b/openstack/common/processutils.py
@@ -34,6 +34,11 @@ from openstack.common import log as logging
LOG = logging.getLogger(__name__)
+class InvalidArgumentError(Exception):
+ def __init__(self, message=None):
+ super(InvalidArgumentError, self).__init__(message)
+
+
class UnknownArgumentError(Exception):
def __init__(self, message=None):
super(UnknownArgumentError, self).__init__(message)
@@ -179,3 +184,64 @@ def execute(*cmd, **kwargs):
# call clean something up in between calls, without
# it two execute calls in a row hangs the second one
greenthread.sleep(0)
+
+
+def trycmd(*args, **kwargs):
+ """
+ A wrapper around execute() to more easily handle warnings and errors.
+
+ Returns an (out, err) tuple of strings containing the output of
+ the command's stdout and stderr. If 'err' is not empty then the
+ command can be considered to have failed.
+
+ :discard_warnings True | False. Defaults to False. If set to True,
+ then for succeeding commands, stderr is cleared
+
+ """
+ discard_warnings = kwargs.pop('discard_warnings', False)
+
+ try:
+ out, err = execute(*args, **kwargs)
+ failed = False
+ except ProcessExecutionError, exn:
+ out, err = '', str(exn)
+ failed = True
+
+ if not failed and discard_warnings and err:
+ # Handle commands that output to stderr but otherwise succeed
+ err = ''
+
+ return out, err
+
+
+def ssh_execute(ssh, cmd, process_input=None,
+ addl_env=None, check_exit_code=True):
+ LOG.debug(_('Running cmd (SSH): %s'), cmd)
+ if addl_env:
+ raise InvalidArgumentError(_('Environment not supported over SSH'))
+
+ if process_input:
+ # This is (probably) fixable if we need it...
+ raise InvalidArgumentError(_('process_input not supported over SSH'))
+
+ stdin_stream, stdout_stream, stderr_stream = ssh.exec_command(cmd)
+ channel = stdout_stream.channel
+
+ # NOTE(justinsb): This seems suspicious...
+ # ...other SSH clients have buffering issues with this approach
+ stdout = stdout_stream.read()
+ stderr = stderr_stream.read()
+ stdin_stream.close()
+
+ exit_status = channel.recv_exit_status()
+
+ # exit_status == -1 if no exit code was returned
+ if exit_status != -1:
+ LOG.debug(_('Result was %s') % exit_status)
+ if check_exit_code and exit_status != 0:
+ raise ProcessExecutionError(exit_code=exit_status,
+ stdout=stdout,
+ stderr=stderr,
+ cmd=cmd)
+
+ return (stdout, stderr)