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':
|
if tmp.find("tmp") != -1 and C.DEFAULT_KEEP_REMOTE_FILES != '1':
|
||||||
cmd = cmd + "; rm -rf %s >/dev/null 2>&1" % tmp
|
cmd = cmd + "; rm -rf %s >/dev/null 2>&1" % tmp
|
||||||
res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
|
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 '''
|
''' execute a command string over SSH, return the output '''
|
||||||
|
|
||||||
sudo_user = self.sudo_user
|
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 ]:
|
if type(stdout) not in [ str, unicode ]:
|
||||||
out = "\n".join(stdout.readlines())
|
out = ''.join(stdout.readlines())
|
||||||
else:
|
else:
|
||||||
out = stdout
|
out = stdout
|
||||||
|
|
||||||
if type(stderr) not in [ str, unicode ]:
|
if type(stderr) not in [ str, unicode ]:
|
||||||
err = "\n".join(stderr.readlines())
|
err = ''.join(stderr.readlines())
|
||||||
else:
|
else:
|
||||||
err = stderr
|
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 = " || ".join(md5s)
|
||||||
cmd = "%s; %s || (echo \"${rc} %s\")" % (test, cmd, path)
|
cmd = "%s; %s || (echo \"${rc} %s\")" % (test, cmd, path)
|
||||||
data = self._low_level_exec_command(conn, cmd, tmp, sudoable=False)
|
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:
|
try:
|
||||||
return data2.split()[0]
|
return data2.split()[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@ -502,7 +505,7 @@ class Runner(object):
|
||||||
cmd += ' && echo %s' % basetmp
|
cmd += ' && echo %s' % basetmp
|
||||||
|
|
||||||
result = self._low_level_exec_command(conn, cmd, None, sudoable=False)
|
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
|
return rc
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ class ActionModule(object):
|
||||||
self.runner = runner
|
self.runner = runner
|
||||||
|
|
||||||
def run(self, conn, tmp, module_name, module_args, inject):
|
def run(self, conn, tmp, module_name, module_args, inject):
|
||||||
return ReturnData(conn=conn, result=dict(
|
return ReturnData(conn=conn,
|
||||||
stdout=self.runner._low_level_exec_command(conn, module_args.encode('utf-8'), tmp, sudoable=True)
|
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.decrypt(self.key, response)
|
||||||
response = utils.parse_json(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):
|
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,
|
p = subprocess.Popen(cmd, cwd=basedir, shell=True, stdin=None,
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
return ("", stdout, stderr)
|
return (p.returncode, '', stdout, stderr)
|
||||||
|
|
||||||
def put_file(self, in_path, out_path):
|
def put_file(self, in_path, out_path):
|
||||||
''' transfer a file from local to local '''
|
''' transfer a file from local to local '''
|
||||||
|
|
|
@ -145,7 +145,7 @@ class Connection(object):
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
raise errors.AnsibleError('ssh timed out waiting for sudo.\n' + sudo_output)
|
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):
|
def put_file(self, in_path, out_path):
|
||||||
''' transfer a file from local to remote '''
|
''' transfer a file from local to remote '''
|
||||||
|
|
|
@ -108,11 +108,11 @@ class Connection(object):
|
||||||
import pty
|
import pty
|
||||||
master, slave = pty.openpty()
|
master, slave = pty.openpty()
|
||||||
p = subprocess.Popen(ssh_cmd, stdin=slave,
|
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)
|
stdin = os.fdopen(master, 'w', 0)
|
||||||
except:
|
except:
|
||||||
p = subprocess.Popen(ssh_cmd, stdin=subprocess.PIPE,
|
p = subprocess.Popen(ssh_cmd, stdin=subprocess.PIPE,
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
stdin = p.stdin
|
stdin = p.stdin
|
||||||
|
|
||||||
self._send_password()
|
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
|
# We can't use p.communicate here because the ControlMaster may have stdout open as well
|
||||||
stdout = ''
|
stdout = ''
|
||||||
|
stderr = ''
|
||||||
while True:
|
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:
|
if p.stdout in rfd:
|
||||||
dat = os.read(p.stdout.fileno(), 9000)
|
dat = os.read(p.stdout.fileno(), 9000)
|
||||||
stdout += dat
|
stdout += dat
|
||||||
if dat == '':
|
if dat == '':
|
||||||
p.wait()
|
p.wait()
|
||||||
break
|
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:
|
elif p.poll() is not None:
|
||||||
break
|
break
|
||||||
stdin.close() # close stdin after we read from stdout (see also issue #848)
|
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')
|
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):
|
def put_file(self, in_path, out_path):
|
||||||
''' transfer a file from local to remote '''
|
''' transfer a file from local to remote '''
|
||||||
|
|
|
@ -159,7 +159,7 @@ def command(data):
|
||||||
stderr = ''
|
stderr = ''
|
||||||
log("got stdout: %s" % stdout)
|
log("got stdout: %s" % stdout)
|
||||||
|
|
||||||
return dict(stdout=stdout, stderr=stderr)
|
return dict(rc=p.returncode, stdout=stdout, stderr=stderr)
|
||||||
|
|
||||||
def fetch(data):
|
def fetch(data):
|
||||||
if 'in_path' not in 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
|
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
|
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
|
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
|
given to M(raw) are run directly through the configured remote shell.
|
||||||
only output is returned. There is no error detection or change handler
|
Standard output, error output and return code are returned when
|
||||||
support for this module
|
available. There is no change handler support for this module.
|
||||||
examples:
|
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
|
author: Michael DeHaan
|
||||||
'''
|
'''
|
||||||
|
|
Loading…
Reference in a new issue