@ -25,6 +25,8 @@ import tty
from os import isatty
from os import isatty
from ansible . errors import AnsibleError
from ansible . errors import AnsibleError
from ansible . module_utils . six import PY3
from ansible . module_utils . _text import to_text
from ansible . plugins . action import ActionBase
from ansible . plugins . action import ActionBase
try :
try :
@ -85,7 +87,7 @@ class ActionModule(ActionBase):
except ValueError as e :
except ValueError as e :
result [ ' failed ' ] = True
result [ ' failed ' ] = True
result [ ' msg ' ] = " non-integer value given for prompt duration: \n %s " % str ( e )
result [ ' msg ' ] = u " non-integer value given for prompt duration: \n %s " % to_text ( e )
return result
return result
# Is 'prompt' a key in 'args'?
# Is 'prompt' a key in 'args'?
@ -102,8 +104,8 @@ class ActionModule(ActionBase):
# Begin the hard work!
# Begin the hard work!
start = time . time ( )
start = time . time ( )
result [ ' start ' ] = str ( datetime . datetime . now ( ) )
result [ ' start ' ] = to_text ( datetime . datetime . now ( ) )
result [ ' user_input ' ] = ' '
result [ ' user_input ' ] = b ' '
fd = None
fd = None
old_settings = None
old_settings = None
@ -122,9 +124,13 @@ class ActionModule(ActionBase):
# save the attributes on the existing (duped) stdin so
# save the attributes on the existing (duped) stdin so
# that we can restore them later after we set raw mode
# that we can restore them later after we set raw mode
if PY3 :
stdin = self . _connection . _new_stdin . buffer
else :
stdin = self . _connection . _new_stdin
fd = None
fd = None
try :
try :
fd = self . _connection . _new_stdin . fileno ( )
fd = stdin. fileno ( )
except ( ValueError , AttributeError ) :
except ( ValueError , AttributeError ) :
# ValueError: someone is using a closed file descriptor as stdin
# ValueError: someone is using a closed file descriptor as stdin
# AttributeError: someone is using a null file descriptor as stdin on windoez
# AttributeError: someone is using a null file descriptor as stdin on windoez
@ -136,12 +142,12 @@ class ActionModule(ActionBase):
# flush the buffer to make sure no previous key presses
# flush the buffer to make sure no previous key presses
# are read in below
# are read in below
termios . tcflush ( self . _connection. _new_ stdin, termios . TCIFLUSH )
termios . tcflush ( stdin, termios . TCIFLUSH )
while True :
while True :
try :
try :
if fd is not None :
if fd is not None :
key_pressed = self . _connection. _new_ stdin. read ( 1 )
key_pressed = stdin. read ( 1 )
if key_pressed == ' \x03 ' :
if key_pressed == b ' \x03 ' :
raise KeyboardInterrupt
raise KeyboardInterrupt
if not seconds :
if not seconds :
@ -149,7 +155,7 @@ class ActionModule(ActionBase):
display . warning ( " Not waiting from prompt as stdin is not interactive " )
display . warning ( " Not waiting from prompt as stdin is not interactive " )
break
break
# read key presses and act accordingly
# read key presses and act accordingly
if key_pressed == ' \r ' :
if key_pressed in ( b ' \r ' , b ' \n ' ) :
break
break
else :
else :
result [ ' user_input ' ] + = key_pressed
result [ ' user_input ' ] + = key_pressed
@ -158,7 +164,7 @@ class ActionModule(ActionBase):
if seconds is not None :
if seconds is not None :
signal . alarm ( 0 )
signal . alarm ( 0 )
display . display ( " Press ' C ' to continue the play or ' A ' to abort \r " ) ,
display . display ( " Press ' C ' to continue the play or ' A ' to abort \r " ) ,
if self . _c_or_a ( ) :
if self . _c_or_a ( stdin ) :
break
break
else :
else :
raise AnsibleError ( ' user requested abort! ' )
raise AnsibleError ( ' user requested abort! ' )
@ -174,7 +180,7 @@ class ActionModule(ActionBase):
termios . tcsetattr ( fd , termios . TCSADRAIN , old_settings )
termios . tcsetattr ( fd , termios . TCSADRAIN , old_settings )
duration = time . time ( ) - start
duration = time . time ( ) - start
result [ ' stop ' ] = str ( datetime . datetime . now ( ) )
result [ ' stop ' ] = to_text ( datetime . datetime . now ( ) )
result [ ' delta ' ] = int ( duration )
result [ ' delta ' ] = int ( duration )
if duration_unit == ' minutes ' :
if duration_unit == ' minutes ' :
@ -183,12 +189,13 @@ class ActionModule(ActionBase):
duration = round ( duration , 2 )
duration = round ( duration , 2 )
result [ ' stdout ' ] = " Paused for %s %s " % ( duration , duration_unit )
result [ ' stdout ' ] = " Paused for %s %s " % ( duration , duration_unit )
result [ ' user_input ' ] = to_text ( result [ ' user_input ' ] , errors = ' surrogate_or_strict ' )
return result
return result
def _c_or_a ( self ):
def _c_or_a ( self , stdin ):
while True :
while True :
key_pressed = self . _connection. _new_ stdin. read ( 1 )
key_pressed = stdin. read ( 1 )
if key_pressed . lower ( ) == ' a ' :
if key_pressed . lower ( ) == b ' a ' :
return False
return False
elif key_pressed . lower ( ) == ' c ' :
elif key_pressed . lower ( ) == b ' c ' :
return True
return True