Merge pull request #1795 from dagwieers/raw-enhanced
Add return code and error output to raw module
This commit is contained in:
commit
3d3deb9797
8 changed files with 34 additions and 24 deletions
|
@ -226,7 +226,7 @@ class Runner(object):
|
|||
if tmp.find("tmp") != -1 and C.DEFAULT_KEEP_REMOTE_FILES != '1':
|
||||
cmd = cmd + "; rm -rf %s >/dev/null 2>&1" % tmp
|
||||
res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
|
||||
return ReturnData(conn=conn, result=res)
|
||||
return ReturnData(conn=conn, result=res['stdout'])
|
||||
|
||||
# *****************************************************
|
||||
|
||||
|
@ -442,19 +442,22 @@ class Runner(object):
|
|||
''' execute a command string over SSH, return the output '''
|
||||
|
||||
sudo_user = self.sudo_user
|
||||
stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, sudoable=sudoable)
|
||||
rc, stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, sudoable=sudoable)
|
||||
|
||||
if type(stdout) not in [ str, unicode ]:
|
||||
out = "\n".join(stdout.readlines())
|
||||
out = ''.join(stdout.readlines())
|
||||
else:
|
||||
out = stdout
|
||||
|
||||
if type(stderr) not in [ str, unicode ]:
|
||||
err = "\n".join(stderr.readlines())
|
||||
err = ''.join(stderr.readlines())
|
||||
else:
|
||||
err = stderr
|
||||
|
||||
return out + err
|
||||
if rc != None:
|
||||
return dict(rc=rc, stdout=out, stderr=err )
|
||||
else:
|
||||
return dict(stdout=out, stderr=err )
|
||||
|
||||
# *****************************************************
|
||||
|
||||
|
@ -474,7 +477,7 @@ class Runner(object):
|
|||
cmd = " || ".join(md5s)
|
||||
cmd = "%s; %s || (echo \"${rc} %s\")" % (test, cmd, path)
|
||||
data = self._low_level_exec_command(conn, cmd, tmp, sudoable=False)
|
||||
data2 = utils.last_non_blank_line(data)
|
||||
data2 = utils.last_non_blank_line(data['stdout'])
|
||||
try:
|
||||
return data2.split()[0]
|
||||
except IndexError:
|
||||
|
@ -502,7 +505,7 @@ class Runner(object):
|
|||
cmd += ' && echo %s' % basetmp
|
||||
|
||||
result = self._low_level_exec_command(conn, cmd, None, sudoable=False)
|
||||
rc = utils.last_non_blank_line(result).strip() + '/'
|
||||
rc = utils.last_non_blank_line(result['stdout']).strip() + '/'
|
||||
return rc
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class ActionModule(object):
|
|||
self.runner = runner
|
||||
|
||||
def run(self, conn, tmp, module_name, module_args, inject):
|
||||
return ReturnData(conn=conn, result=dict(
|
||||
stdout=self.runner._low_level_exec_command(conn, module_args.encode('utf-8'), tmp, sudoable=True)
|
||||
))
|
||||
return ReturnData(conn=conn,
|
||||
result=self.runner._low_level_exec_command(conn, module_args.encode('utf-8'), tmp, sudoable=True)
|
||||
)
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ class Connection(object):
|
|||
response = utils.decrypt(self.key, response)
|
||||
response = utils.parse_json(response)
|
||||
|
||||
return ('', response.get('stdout',''), response.get('stderr',''))
|
||||
return (response.get('rc',None), '', response.get('stdout',''), response.get('stderr',''))
|
||||
|
||||
def put_file(self, in_path, out_path):
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class Connection(object):
|
|||
p = subprocess.Popen(cmd, cwd=basedir, shell=True, stdin=None,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdout, stderr = p.communicate()
|
||||
return ("", stdout, stderr)
|
||||
return (p.returncode, '', stdout, stderr)
|
||||
|
||||
def put_file(self, in_path, out_path):
|
||||
''' transfer a file from local to local '''
|
||||
|
|
|
@ -145,7 +145,7 @@ class Connection(object):
|
|||
except socket.timeout:
|
||||
raise errors.AnsibleError('ssh timed out waiting for sudo.\n' + sudo_output)
|
||||
|
||||
return (chan.makefile('wb', bufsize), chan.makefile('rb', bufsize), '')
|
||||
return (chan.recv_exit_status(), chan.makefile('wb', bufsize), chan.makefile('rb', bufsize), chan.makefile_stderr('rb', bufsize))
|
||||
|
||||
def put_file(self, in_path, out_path):
|
||||
''' transfer a file from local to remote '''
|
||||
|
|
|
@ -108,11 +108,11 @@ class Connection(object):
|
|||
import pty
|
||||
master, slave = pty.openpty()
|
||||
p = subprocess.Popen(ssh_cmd, stdin=slave,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdin = os.fdopen(master, 'w', 0)
|
||||
except:
|
||||
p = subprocess.Popen(ssh_cmd, stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
stdin = p.stdin
|
||||
|
||||
self._send_password()
|
||||
|
@ -137,22 +137,29 @@ class Connection(object):
|
|||
|
||||
# We can't use p.communicate here because the ControlMaster may have stdout open as well
|
||||
stdout = ''
|
||||
stderr = ''
|
||||
while True:
|
||||
rfd, wfd, efd = select.select([p.stdout], [], [p.stdout], 1)
|
||||
rfd, wfd, efd = select.select([p.stdout, p.stderr], [], [p.stdout, p.stderr], 1)
|
||||
if p.stdout in rfd:
|
||||
dat = os.read(p.stdout.fileno(), 9000)
|
||||
stdout += dat
|
||||
if dat == '':
|
||||
p.wait()
|
||||
break
|
||||
elif p.stderr in rfd:
|
||||
dat = os.read(p.stderr.fileno(), 9000)
|
||||
stderr += dat
|
||||
if dat == '':
|
||||
p.wait()
|
||||
break
|
||||
elif p.poll() is not None:
|
||||
break
|
||||
stdin.close() # close stdin after we read from stdout (see also issue #848)
|
||||
|
||||
if p.returncode != 0 and stdout.find('Bad configuration option: ControlPersist') != -1:
|
||||
if p.returncode != 0 and stderr.find('Bad configuration option: ControlPersist') != -1:
|
||||
raise errors.AnsibleError('using -c ssh on certain older ssh versions may not support ControlPersist, set ANSIBLE_SSH_ARGS="" (or ansible_ssh_args in the config file) before running again')
|
||||
|
||||
return ('', stdout, '')
|
||||
return (p.returncode, '', stdout, stderr)
|
||||
|
||||
def put_file(self, in_path, out_path):
|
||||
''' transfer a file from local to remote '''
|
||||
|
|
|
@ -159,7 +159,7 @@ def command(data):
|
|||
stderr = ''
|
||||
log("got stdout: %s" % stdout)
|
||||
|
||||
return dict(stdout=stdout, stderr=stderr)
|
||||
return dict(rc=p.returncode, stdout=stdout, stderr=stderr)
|
||||
|
||||
def fetch(data):
|
||||
if 'in_path' not in data:
|
||||
|
|
10
library/raw
10
library/raw
|
@ -13,11 +13,11 @@ description:
|
|||
all core modules require it. Another is speaking to any devices such as
|
||||
routers that do not have any Python installed. In any other case, using
|
||||
the M(shell) or M(command) module is much more appropriate. Arguments
|
||||
given to M(raw) are run directly through the configured remote shell and
|
||||
only output is returned. There is no error detection or change handler
|
||||
support for this module
|
||||
given to M(raw) are run directly through the configured remote shell.
|
||||
Standard output, error output and return code are returned when
|
||||
available. There is no change handler support for this module.
|
||||
examples:
|
||||
- code: ansible newhost.example.com -m raw -a "yum -y install python-simplejson"
|
||||
description: Example from C(/usr/bin/ansible) to bootstrap a legacy python 2.4 host
|
||||
- description: Example from C(/usr/bin/ansible) to bootstrap a legacy python 2.4 host
|
||||
code: ansible newhost.example.com -m raw -a "yum -y install python-simplejson"
|
||||
author: Michael DeHaan
|
||||
'''
|
||||
|
|
Loading…
Reference in a new issue