@ -10,14 +10,15 @@ import time
import json
import json
import subprocess
import subprocess
import sys
import sys
import termios
import traceback
import traceback
from ansible import constants as C
from ansible import constants as C
from ansible . errors import AnsibleError , AnsibleParserError , AnsibleUndefinedVariable , AnsibleConnectionFailure , AnsibleActionFail , AnsibleActionSkip
from ansible . errors import AnsibleError , AnsibleParserError , AnsibleUndefinedVariable , AnsibleConnectionFailure , AnsibleActionFail , AnsibleActionSkip
from ansible . executor . task_result import TaskResult
from ansible . executor . task_result import TaskResult
from ansible . module_utils . six import iteritems , string_types , binary_type
from ansible . module_utils . six import iteritems , string_types , binary_type
from ansible . module_utils . six . moves import cPickle
from ansible . module_utils . _text import to_text , to_native
from ansible . module_utils . _text import to_text , to_native
from ansible . module_utils . connection import write_to_file_descriptor
from ansible . playbook . conditional import Conditional
from ansible . playbook . conditional import Conditional
from ansible . playbook . task import Task
from ansible . playbook . task import Task
from ansible . template import Templar
from ansible . template import Templar
@ -920,28 +921,24 @@ class TaskExecutor:
[ python , find_file_in_path ( ' ansible-connection ' ) , to_text ( os . getppid ( ) ) ] ,
[ python , find_file_in_path ( ' ansible-connection ' ) , to_text ( os . getppid ( ) ) ] ,
stdin = slave , stdout = subprocess . PIPE , stderr = subprocess . PIPE
stdin = slave , stdout = subprocess . PIPE , stderr = subprocess . PIPE
)
)
stdin = os . fdopen ( master , ' wb ' , 0 )
os . close ( slave )
os . close ( slave )
# Need to force a protocol that is compatible with both py2 and py3.
# We need to set the pty into noncanonical mode. This ensures that we
# That would be protocol=2 or less.
# can receive lines longer than 4095 characters (plus newline) without
# Also need to force a protocol that excludes certain control chars as
# truncating.
# stdin in this case is a pty and control chars will cause problems.
old = termios . tcgetattr ( master )
# that means only protocol=0 will work.
new = termios . tcgetattr ( master )
src = cPickle . dumps ( self . _play_context . serialize ( ) , protocol = 0 )
new [ 3 ] = new [ 3 ] & ~ termios . ICANON
stdin . write ( src )
stdin . write ( b ' \n #END_INIT# \n ' )
try :
termios . tcsetattr ( master , termios . TCSANOW , new )
src = cPickle . dumps ( variables , protocol = 0 )
write_to_file_descriptor ( master , variables )
# remaining \r fail to round-trip the socket
write_to_file_descriptor ( master , self . _play_context . serialize ( ) )
src = src . replace ( b ' \r ' , br ' \ r ' )
stdin . write ( src )
( stdout , stderr ) = p . communicate ( )
stdin . write ( b ' \n #END_VARS# \n ' )
finally :
termios . tcsetattr ( master , termios . TCSANOW , old )
stdin . flush ( )
os . close ( master )
( stdout , stderr ) = p . communicate ( )
stdin . close ( )
if p . returncode == 0 :
if p . returncode == 0 :
result = json . loads ( to_text ( stdout , errors = ' surrogate_then_replace ' ) )
result = json . loads ( to_text ( stdout , errors = ' surrogate_then_replace ' ) )