@@ -47,7 +47,7 @@ def timeout_handler(signum, frame):
47
47
class ActionModule (ActionBase ):
48
48
''' pauses execution for a length or time, or until input is received '''
49
49
50
- PAUSE_TYPES = ['seconds' , 'minutes' , 'prompt' , '' ]
50
+ PAUSE_TYPES = ['seconds' , 'minutes' , 'prompt' , 'echo' , ' ' ]
51
51
BYPASS_HOST_LOOP = True
52
52
53
53
def run (self , tmp = None , task_vars = None ):
@@ -60,6 +60,8 @@ def run(self, tmp=None, task_vars=None):
60
60
duration_unit = 'minutes'
61
61
prompt = None
62
62
seconds = None
63
+ echo = True
64
+ echo_prompt = ''
63
65
result .update (dict (
64
66
changed = False ,
65
67
rc = 0 ,
@@ -68,14 +70,35 @@ def run(self, tmp=None, task_vars=None):
68
70
start = None ,
69
71
stop = None ,
70
72
delta = None ,
73
+ echo = echo
71
74
))
72
75
73
- # Is 'args' empty, then this is the default prompted pause
74
- if self ._task .args is None or len (self ._task .args .keys ()) == 0 :
75
- prompt = "[%s]\n Press enter to continue:" % self ._task .get_name ().strip ()
76
+ if not set (self ._task .args .keys ()) <= set (self .PAUSE_TYPES ):
77
+ result ['failed' ] = True
78
+ result ['msg' ] = "Invalid argument given. Must be one of: %s" % ", " .join (self .PAUSE_TYPES )
79
+ return result
80
+
81
+ # Should keystrokes be echoed to stdout?
82
+ if 'echo' in self ._task .args :
83
+ echo = self ._task .args ['echo' ]
84
+ if not type (echo ) == bool :
85
+ result ['failed' ] = True
86
+ result ['msg' ] = "'%s' is not a valid setting for 'echo'." % self ._task .args ['echo' ]
87
+ return result
88
+
89
+ # Add a note saying the output is hidden if echo is disabled
90
+ if not echo :
91
+ echo_prompt = ' (output is hidden)'
92
+
93
+ # Is 'prompt' a key in 'args'?
94
+ if 'prompt' in self ._task .args :
95
+ prompt = "[%s]\n %s%s:" % (self ._task .get_name ().strip (), self ._task .args ['prompt' ], echo_prompt )
96
+ else :
97
+ # If no custom prompt is specified, set a default prompt
98
+ prompt = "[%s]\n %s%s:" % (self ._task .get_name ().strip (), 'Press enter to continue' , echo_prompt )
76
99
77
100
# Are 'minutes' or 'seconds' keys that exist in 'args'?
78
- elif 'minutes' in self ._task .args or 'seconds' in self ._task .args :
101
+ if 'minutes' in self ._task .args or 'seconds' in self ._task .args :
79
102
try :
80
103
if 'minutes' in self ._task .args :
81
104
# The time() command operates in seconds so we need to
@@ -90,16 +113,6 @@ def run(self, tmp=None, task_vars=None):
90
113
result ['msg' ] = u"non-integer value given for prompt duration:\n %s" % to_text (e )
91
114
return result
92
115
93
- # Is 'prompt' a key in 'args'?
94
- elif 'prompt' in self ._task .args :
95
- prompt = "[%s]\n %s:" % (self ._task .get_name ().strip (), self ._task .args ['prompt' ])
96
-
97
- else :
98
- # I have no idea what you're trying to do. But it's so wrong.
99
- result ['failed' ] = True
100
- result ['msg' ] = "invalid pause type given. must be one of: %s" % ", " .join (self .PAUSE_TYPES )
101
- return result
102
-
103
116
########################################################################
104
117
# Begin the hard work!
105
118
@@ -113,12 +126,19 @@ def run(self, tmp=None, task_vars=None):
113
126
if seconds is not None :
114
127
if seconds < 1 :
115
128
seconds = 1
129
+
116
130
# setup the alarm handler
117
131
signal .signal (signal .SIGALRM , timeout_handler )
118
132
signal .alarm (seconds )
119
- # show the prompt
120
- display .display ("Pausing for %d seconds" % seconds )
133
+
134
+ # show the timer and control prompts
135
+ display .display ("Pausing for %d seconds%s" % (seconds , echo_prompt ))
121
136
display .display ("(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)\r " ),
137
+
138
+ # show the prompt specified in the task
139
+ if 'prompt' in self ._task .args :
140
+ display .display (prompt )
141
+
122
142
else :
123
143
display .display (prompt )
124
144
@@ -144,25 +164,30 @@ def run(self, tmp=None, task_vars=None):
144
164
# ICANON -> Allows characters to be deleted and hides things like ^M.
145
165
# ICRNL -> Makes the return key work when ICANON is enabled, otherwise
146
166
# you get stuck at the prompt with no way to get out of it.
147
- # ECHO -> Echos input back to stdout
148
- #
149
167
# See man termios for details on these flags
150
168
if not seconds :
151
169
new_settings = termios .tcgetattr (fd )
152
170
new_settings [0 ] = new_settings [0 ] | termios .ICRNL
153
- new_settings [3 ] = new_settings [3 ] | (termios .ICANON | termios .ECHO )
154
- termios .tcsetattr (fd , termios .TCSANOW , new_settings )
171
+ new_settings [3 ] = new_settings [3 ] | termios .ICANON
155
172
termios .tcsetattr (fd , termios .TCSANOW , new_settings )
156
173
174
+ if echo :
175
+ # Enable ECHO since tty.setraw() disables it
176
+ new_settings = termios .tcgetattr (fd )
177
+ new_settings [3 ] = new_settings [3 ] | termios .ECHO
178
+ termios .tcsetattr (fd , termios .TCSANOW , new_settings )
179
+
157
180
# flush the buffer to make sure no previous key presses
158
181
# are read in below
159
182
termios .tcflush (stdin , termios .TCIFLUSH )
160
183
while True :
161
184
try :
162
185
if fd is not None :
163
186
key_pressed = stdin .read (1 )
164
- if key_pressed == b'\x03 ' :
165
- raise KeyboardInterrupt
187
+
188
+ if seconds :
189
+ if key_pressed == b'\x03 ' :
190
+ raise KeyboardInterrupt
166
191
167
192
if not seconds :
168
193
if fd is None or not isatty (fd ):
0 commit comments