@ -39,6 +39,7 @@ DOCUMENTATION = """
"""
import distutils . spawn
import fcntl
import os
import os . path
import subprocess
@ -47,6 +48,7 @@ import re
from distutils . version import LooseVersion
import ansible . constants as C
from ansible . compat import selectors
from ansible . errors import AnsibleError , AnsibleFileNotFound
from ansible . module_utils . six . moves import shlex_quote
from ansible . module_utils . _text import to_bytes , to_native , to_text
@ -205,10 +207,55 @@ class Connection(ConnectionBase):
display . vvv ( " EXEC %s " % ( local_cmd , ) , host = self . _play_context . remote_addr )
local_cmd = [ to_bytes ( i , errors = ' surrogate_or_strict ' ) for i in local_cmd ]
p = subprocess . Popen ( local_cmd , shell = False , stdin = subprocess . PIPE ,
stdout = subprocess . PIPE , stderr = subprocess . PIPE )
p = subprocess . Popen (
local_cmd ,
stdin = subprocess . PIPE ,
stdout = subprocess . PIPE ,
stderr = subprocess . PIPE ,
)
if self . become and self . become . expect_prompt ( ) and sudoable :
display . debug ( " handling privilege escalation " )
fcntl . fcntl ( p . stdout , fcntl . F_SETFL , fcntl . fcntl ( p . stdout , fcntl . F_GETFL ) | os . O_NONBLOCK )
fcntl . fcntl ( p . stderr , fcntl . F_SETFL , fcntl . fcntl ( p . stderr , fcntl . F_GETFL ) | os . O_NONBLOCK )
selector = selectors . DefaultSelector ( )
selector . register ( p . stdout , selectors . EVENT_READ )
selector . register ( p . stderr , selectors . EVENT_READ )
become_output = b ' '
try :
while not self . become . check_success ( become_output ) and not self . become . check_password_prompt ( become_output ) :
events = selector . select ( self . _play_context . timeout )
if not events :
stdout , stderr = p . communicate ( )
raise AnsibleError ( ' timeout waiting for privilege escalation password prompt: \n ' + to_native ( become_output ) )
for key , event in events :
if key . fileobj == p . stdout :
chunk = p . stdout . read ( )
break
elif key . fileobj == p . stderr :
chunk = p . stderr . read ( )
if not chunk :
stdout , stderr = p . communicate ( )
raise AnsibleError ( ' privilege output closed while waiting for password prompt: \n ' + to_native ( become_output ) )
become_output + = chunk
finally :
selector . close ( )
if not self . become . check_success ( become_output ) :
p . stdin . write ( to_bytes ( self . _play_context . become_pass , errors = ' surrogate_or_strict ' ) + b ' \n ' )
fcntl . fcntl ( p . stdout , fcntl . F_SETFL , fcntl . fcntl ( p . stdout , fcntl . F_GETFL ) & ~ os . O_NONBLOCK )
fcntl . fcntl ( p . stderr , fcntl . F_SETFL , fcntl . fcntl ( p . stderr , fcntl . F_GETFL ) & ~ os . O_NONBLOCK )
display . debug ( " getting output with communicate() " )
stdout , stderr = p . communicate ( in_data )
display . debug ( " done communicating " )
display . debug ( " done with docker.exec_command() " )
return ( p . returncode , stdout , stderr )
def _prefix_login_path ( self , remote_path ) :