@ -53,6 +53,7 @@ import sys
import syslog
import types
import time
import select
import shutil
import stat
import tempfile
@ -1163,7 +1164,7 @@ class AnsibleModule(object):
# rename might not preserve context
self . set_context_if_different ( dest , context , False )
def run_command ( self , args , check_rc = False , close_fds = Fals e, executable = None , data = None , binary_data = False , path_prefix = None , cwd = None , use_unsafe_shell = False ) :
def run_command ( self , args , check_rc = False , close_fds = Tru e, executable = None , data = None , binary_data = False , path_prefix = None , cwd = None , use_unsafe_shell = False ) :
'''
Execute a command , returns rc , stdout , and stderr .
args is the command to run
@ -1237,7 +1238,7 @@ class AnsibleModule(object):
executable = executable ,
shell = shell ,
close_fds = close_fds ,
stdin = st_in ,
stdin = st_in ,
stdout = subprocess . PIPE ,
stderr = subprocess . PIPE
)
@ -1260,10 +1261,48 @@ class AnsibleModule(object):
try :
cmd = subprocess . Popen ( args , * * kwargs )
# the communication logic here is essentially taken from that
# of the _communicate() function in ssh.py
stdout = ' '
stderr = ' '
rpipes = [ cmd . stdout , cmd . stderr ]
if data :
if not binary_data :
data + = ' \n '
out , err = cmd . communicate ( input = data )
cmd . stdin . write ( data )
cmd . stdin . close ( )
while True :
rfd , wfd , efd = select . select ( rpipes , [ ] , rpipes , 1 )
if cmd . stdout in rfd :
dat = os . read ( cmd . stdout . fileno ( ) , 9000 )
stdout + = dat
if dat == ' ' :
rpipes . remove ( cmd . stdout )
if cmd . stderr in rfd :
dat = os . read ( cmd . stderr . fileno ( ) , 9000 )
stderr + = dat
if dat == ' ' :
rpipes . remove ( cmd . stderr )
# only break out if no pipes are left to read or
# the pipes are completely read and
# the process is terminated
if ( not rpipes or not rfd ) and cmd . poll ( ) is not None :
break
# No pipes are left to read but process is not yet terminated
# Only then it is safe to wait for the process to be finished
# NOTE: Actually cmd.poll() is always None here if rpipes is empty
elif not rpipes and cmd . poll ( ) == None :
cmd . wait ( )
# The process is terminated. Since no pipes to read from are
# left, there is no need to call select() again.
break
cmd . stdout . close ( )
cmd . stderr . close ( )
rc = cmd . returncode
except ( OSError , IOError ) , e :
self . fail_json ( rc = e . errno , msg = str ( e ) , cmd = clean_args )
@ -1271,13 +1310,13 @@ class AnsibleModule(object):
self . fail_json ( rc = 257 , msg = traceback . format_exc ( ) , cmd = clean_args )
if rc != 0 and check_rc :
msg = err. rstrip ( )
self . fail_json ( cmd = clean_args , rc = rc , stdout = out, stderr = err, msg = msg )
msg = std err. rstrip ( )
self . fail_json ( cmd = clean_args , rc = rc , stdout = std out, stderr = std err, msg = msg )
# reset the pwd
os . chdir ( prev_dir )
return ( rc , out, err)
return ( rc , std out, std err)
def append_to_file ( self , filename , str ) :
filename = os . path . expandvars ( os . path . expanduser ( filename ) )