mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Port action plugins to global display
This commit is contained in:
parent
186e034515
commit
4c7128da17
4 changed files with 68 additions and 42 deletions
|
@ -43,6 +43,7 @@ except ImportError:
|
||||||
from ansible.utils.display import Display
|
from ansible.utils.display import Display
|
||||||
display = Display()
|
display = Display()
|
||||||
|
|
||||||
|
|
||||||
class ActionBase(with_metaclass(ABCMeta, object)):
|
class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -59,6 +60,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
self._loader = loader
|
self._loader = loader
|
||||||
self._templar = templar
|
self._templar = templar
|
||||||
self._shared_loader_obj = shared_loader_obj
|
self._shared_loader_obj = shared_loader_obj
|
||||||
|
# Backwards compat: self._display isn't really needed, just import the global display and use that.
|
||||||
self._display = display
|
self._display = display
|
||||||
|
|
||||||
self._supports_check_mode = True
|
self._supports_check_mode = True
|
||||||
|
@ -129,8 +131,8 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
if module_path2 is not None:
|
if module_path2 is not None:
|
||||||
raise AnsibleError("The module %s was not found in configured module paths" % (module_name))
|
raise AnsibleError("The module %s was not found in configured module paths" % (module_name))
|
||||||
else:
|
else:
|
||||||
raise AnsibleError("The module %s was not found in configured module paths. " \
|
raise AnsibleError("The module %s was not found in configured module paths. "
|
||||||
"Additionally, core modules are missing. If this is a checkout, " \
|
"Additionally, core modules are missing. If this is a checkout, "
|
||||||
"run 'git submodule update --init --recursive' to correct this problem." % (module_name))
|
"run 'git submodule update --init --recursive' to correct this problem." % (module_name))
|
||||||
|
|
||||||
# insert shared code and arguments into the module
|
# insert shared code and arguments into the module
|
||||||
|
@ -199,9 +201,9 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
tmp_mode = 0o755
|
tmp_mode = 0o755
|
||||||
|
|
||||||
cmd = self._connection._shell.mkdtemp(basefile, use_system_tmp, tmp_mode)
|
cmd = self._connection._shell.mkdtemp(basefile, use_system_tmp, tmp_mode)
|
||||||
self._display.debug("executing _low_level_execute_command to create the tmp path")
|
display.debug("executing _low_level_execute_command to create the tmp path")
|
||||||
result = self._low_level_execute_command(cmd, sudoable=False)
|
result = self._low_level_execute_command(cmd, sudoable=False)
|
||||||
self._display.debug("done with creation of tmp path")
|
display.debug("done with creation of tmp path")
|
||||||
|
|
||||||
# error handling on this seems a little aggressive?
|
# error handling on this seems a little aggressive?
|
||||||
if result['rc'] != 0:
|
if result['rc'] != 0:
|
||||||
|
@ -212,12 +214,16 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
if self._play_context.verbosity > 3:
|
if self._play_context.verbosity > 3:
|
||||||
output = u'SSH encountered an unknown error. The output was:\n%s%s' % (result['stdout'], result['stderr'])
|
output = u'SSH encountered an unknown error. The output was:\n%s%s' % (result['stdout'], result['stderr'])
|
||||||
else:
|
else:
|
||||||
output = u'SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue'
|
output = (u'SSH encountered an unknown error during the connection.'
|
||||||
|
' We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue')
|
||||||
|
|
||||||
elif u'No space left on device' in result['stderr']:
|
elif u'No space left on device' in result['stderr']:
|
||||||
output = result['stderr']
|
output = result['stderr']
|
||||||
else:
|
else:
|
||||||
output = 'Authentication or permission failure. In some cases, you may have been able to authenticate and did not have permissions on the remote directory. Consider changing the remote temp path in ansible.cfg to a path rooted in "/tmp". Failed command was: %s, exited with result %d' % (cmd, result['rc'])
|
output = ('Authentication or permission failure.'
|
||||||
|
' In some cases, you may have been able to authenticate and did not have permissions on the remote directory.'
|
||||||
|
' Consider changing the remote temp path in ansible.cfg to a path rooted in "/tmp".'
|
||||||
|
' Failed command was: %s, exited with result %d' % (cmd, result['rc']))
|
||||||
if 'stdout' in result and result['stdout'] != u'':
|
if 'stdout' in result and result['stdout'] != u'':
|
||||||
output = output + u": %s" % result['stdout']
|
output = output + u": %s" % result['stdout']
|
||||||
raise AnsibleConnectionFailure(output)
|
raise AnsibleConnectionFailure(output)
|
||||||
|
@ -238,9 +244,9 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
cmd = self._connection._shell.remove(tmp_path, recurse=True)
|
cmd = self._connection._shell.remove(tmp_path, recurse=True)
|
||||||
# If we have gotten here we have a working ssh configuration.
|
# If we have gotten here we have a working ssh configuration.
|
||||||
# If ssh breaks we could leave tmp directories out on the remote system.
|
# If ssh breaks we could leave tmp directories out on the remote system.
|
||||||
self._display.debug("calling _low_level_execute_command to remove the tmp path")
|
display.debug("calling _low_level_execute_command to remove the tmp path")
|
||||||
self._low_level_execute_command(cmd, sudoable=False)
|
self._low_level_execute_command(cmd, sudoable=False)
|
||||||
self._display.debug("done removing the tmp path")
|
display.debug("done removing the tmp path")
|
||||||
|
|
||||||
def _transfer_data(self, remote_path, data):
|
def _transfer_data(self, remote_path, data):
|
||||||
'''
|
'''
|
||||||
|
@ -275,9 +281,9 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
cmd = self._connection._shell.chmod(mode, path)
|
cmd = self._connection._shell.chmod(mode, path)
|
||||||
self._display.debug("calling _low_level_execute_command to chmod the remote path")
|
display.debug("calling _low_level_execute_command to chmod the remote path")
|
||||||
res = self._low_level_execute_command(cmd, sudoable=sudoable)
|
res = self._low_level_execute_command(cmd, sudoable=sudoable)
|
||||||
self._display.debug("done with chmod call")
|
display.debug("done with chmod call")
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _remote_checksum(self, path, all_vars):
|
def _remote_checksum(self, path, all_vars):
|
||||||
|
@ -288,9 +294,9 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
python_interp = all_vars.get('ansible_python_interpreter', 'python')
|
python_interp = all_vars.get('ansible_python_interpreter', 'python')
|
||||||
|
|
||||||
cmd = self._connection._shell.checksum(path, python_interp)
|
cmd = self._connection._shell.checksum(path, python_interp)
|
||||||
self._display.debug("calling _low_level_execute_command to get the remote checksum")
|
display.debug("calling _low_level_execute_command to get the remote checksum")
|
||||||
data = self._low_level_execute_command(cmd, sudoable=True)
|
data = self._low_level_execute_command(cmd, sudoable=True)
|
||||||
self._display.debug("done getting the remote checksum")
|
display.debug("done getting the remote checksum")
|
||||||
try:
|
try:
|
||||||
data2 = data['stdout'].strip().splitlines()[-1]
|
data2 = data['stdout'].strip().splitlines()[-1]
|
||||||
if data2 == u'':
|
if data2 == u'':
|
||||||
|
@ -300,7 +306,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
else:
|
else:
|
||||||
return data2.split()[0]
|
return data2.split()[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
self._display.warning(u"Calculating checksum failed unusually, please report this to "
|
display.warning(u"Calculating checksum failed unusually, please report this to "
|
||||||
u"the list so it can be fixed\ncommand: %s\n----\noutput: %s\n----\n" % (to_unicode(cmd), data))
|
u"the list so it can be fixed\ncommand: %s\n----\noutput: %s\n----\n" % (to_unicode(cmd), data))
|
||||||
# this will signal that it changed and allow things to keep going
|
# this will signal that it changed and allow things to keep going
|
||||||
return "INVALIDCHECKSUM"
|
return "INVALIDCHECKSUM"
|
||||||
|
@ -318,9 +324,9 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
expand_path = '~%s' % self._play_context.become_user
|
expand_path = '~%s' % self._play_context.become_user
|
||||||
|
|
||||||
cmd = self._connection._shell.expand_user(expand_path)
|
cmd = self._connection._shell.expand_user(expand_path)
|
||||||
self._display.debug("calling _low_level_execute_command to expand the remote user path")
|
display.debug("calling _low_level_execute_command to expand the remote user path")
|
||||||
data = self._low_level_execute_command(cmd, sudoable=False)
|
data = self._low_level_execute_command(cmd, sudoable=False)
|
||||||
self._display.debug("done expanding the remote user path")
|
display.debug("done expanding the remote user path")
|
||||||
#initial_fragment = utils.last_non_blank_line(data['stdout'])
|
#initial_fragment = utils.last_non_blank_line(data['stdout'])
|
||||||
initial_fragment = data['stdout'].strip().splitlines()[-1]
|
initial_fragment = data['stdout'].strip().splitlines()[-1]
|
||||||
|
|
||||||
|
@ -395,7 +401,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
args_file_path = self._connection._shell.join_path(tmp, 'args')
|
args_file_path = self._connection._shell.join_path(tmp, 'args')
|
||||||
|
|
||||||
if remote_module_path or module_style != 'new':
|
if remote_module_path or module_style != 'new':
|
||||||
self._display.debug("transferring module to remote")
|
display.debug("transferring module to remote")
|
||||||
self._transfer_data(remote_module_path, module_data)
|
self._transfer_data(remote_module_path, module_data)
|
||||||
if module_style == 'old':
|
if module_style == 'old':
|
||||||
# we need to dump the module args to a k=v string in a file on
|
# we need to dump the module args to a k=v string in a file on
|
||||||
|
@ -404,7 +410,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
for k,v in iteritems(module_args):
|
for k,v in iteritems(module_args):
|
||||||
args_data += '%s="%s" ' % (k, pipes.quote(v))
|
args_data += '%s="%s" ' % (k, pipes.quote(v))
|
||||||
self._transfer_data(args_file_path, args_data)
|
self._transfer_data(args_file_path, args_data)
|
||||||
self._display.debug("done transferring module to remote")
|
display.debug("done transferring module to remote")
|
||||||
|
|
||||||
environment_string = self._compute_environment_string()
|
environment_string = self._compute_environment_string()
|
||||||
|
|
||||||
|
@ -436,14 +442,14 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
# specified in the play, not the sudo_user
|
# specified in the play, not the sudo_user
|
||||||
sudoable = False
|
sudoable = False
|
||||||
|
|
||||||
self._display.debug("calling _low_level_execute_command() for command %s" % cmd)
|
display.debug("calling _low_level_execute_command() for command %s" % cmd)
|
||||||
res = self._low_level_execute_command(cmd, sudoable=sudoable, in_data=in_data)
|
res = self._low_level_execute_command(cmd, sudoable=sudoable, in_data=in_data)
|
||||||
self._display.debug("_low_level_execute_command returned ok")
|
display.debug("_low_level_execute_command returned ok")
|
||||||
|
|
||||||
if tmp and "tmp" in tmp and not C.DEFAULT_KEEP_REMOTE_FILES and not persist_files and delete_remote_tmp:
|
if tmp and "tmp" in tmp and not C.DEFAULT_KEEP_REMOTE_FILES and not persist_files and delete_remote_tmp:
|
||||||
if self._play_context.become and self._play_context.become_user != 'root':
|
if self._play_context.become and self._play_context.become_user != 'root':
|
||||||
# not sudoing to root, so maybe can't delete files as that other user
|
# not sudoing to root, so maybe can't delete files as that other user
|
||||||
# have to clean up temp files as original user in a second step
|
# have to clean up temp files as original user in a second step
|
||||||
cmd2 = self._connection._shell.remove(tmp, recurse=True)
|
cmd2 = self._connection._shell.remove(tmp, recurse=True)
|
||||||
self._low_level_execute_command(cmd2, sudoable=False)
|
self._low_level_execute_command(cmd2, sudoable=False)
|
||||||
|
|
||||||
|
@ -464,7 +470,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
if 'stdout' in data and 'stdout_lines' not in data:
|
if 'stdout' in data and 'stdout_lines' not in data:
|
||||||
data['stdout_lines'] = data.get('stdout', u'').splitlines()
|
data['stdout_lines'] = data.get('stdout', u'').splitlines()
|
||||||
|
|
||||||
self._display.debug("done with _execute_module (%s, %s)" % (module_name, module_args))
|
display.debug("done with _execute_module (%s, %s)" % (module_name, module_args))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def _low_level_execute_command(self, cmd, sudoable=True, in_data=None,
|
def _low_level_execute_command(self, cmd, sudoable=True, in_data=None,
|
||||||
|
@ -486,21 +492,21 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
if executable is not None:
|
if executable is not None:
|
||||||
cmd = executable + ' -c ' + cmd
|
cmd = executable + ' -c ' + cmd
|
||||||
|
|
||||||
self._display.debug("in _low_level_execute_command() (%s)" % (cmd,))
|
display.debug("in _low_level_execute_command() (%s)" % (cmd,))
|
||||||
if not cmd:
|
if not cmd:
|
||||||
# this can happen with powershell modules when there is no analog to a Windows command (like chmod)
|
# this can happen with powershell modules when there is no analog to a Windows command (like chmod)
|
||||||
self._display.debug("no command, exiting _low_level_execute_command()")
|
display.debug("no command, exiting _low_level_execute_command()")
|
||||||
return dict(stdout='', stderr='')
|
return dict(stdout='', stderr='')
|
||||||
|
|
||||||
allow_same_user = C.BECOME_ALLOW_SAME_USER
|
allow_same_user = C.BECOME_ALLOW_SAME_USER
|
||||||
same_user = self._play_context.become_user == self._play_context.remote_user
|
same_user = self._play_context.become_user == self._play_context.remote_user
|
||||||
if sudoable and self._play_context.become and (allow_same_user or not same_user):
|
if sudoable and self._play_context.become and (allow_same_user or not same_user):
|
||||||
self._display.debug("using become for this command")
|
display.debug("using become for this command")
|
||||||
cmd = self._play_context.make_become_cmd(cmd, executable=executable)
|
cmd = self._play_context.make_become_cmd(cmd, executable=executable)
|
||||||
|
|
||||||
self._display.debug("executing the command %s through the connection" % cmd)
|
display.debug("executing the command %s through the connection" % cmd)
|
||||||
rc, stdout, stderr = self._connection.exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
rc, stdout, stderr = self._connection.exec_command(cmd, in_data=in_data, sudoable=sudoable)
|
||||||
self._display.debug("command execution done")
|
display.debug("command execution done")
|
||||||
|
|
||||||
# stdout and stderr may be either a file-like or a bytes object.
|
# stdout and stderr may be either a file-like or a bytes object.
|
||||||
# Convert either one to a text type
|
# Convert either one to a text type
|
||||||
|
@ -518,7 +524,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
else:
|
else:
|
||||||
err = stderr
|
err = stderr
|
||||||
|
|
||||||
self._display.debug("done with _low_level_execute_command() (%s)" % (cmd,))
|
display.debug("done with _low_level_execute_command() (%s)" % (cmd,))
|
||||||
if rc is None:
|
if rc is None:
|
||||||
rc = 0
|
rc = 0
|
||||||
|
|
||||||
|
@ -526,9 +532,8 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
|
|
||||||
def _get_first_available_file(self, faf, of=None, searchdir='files'):
|
def _get_first_available_file(self, faf, of=None, searchdir='files'):
|
||||||
|
|
||||||
self._display.deprecated("first_available_file, use with_first_found or lookup('first_found',...) instead")
|
display.deprecated("first_available_file, use with_first_found or lookup('first_found',...) instead")
|
||||||
for fn in faf:
|
for fn in faf:
|
||||||
fn_orig = fn
|
|
||||||
fnt = self._templar.template(fn)
|
fnt = self._templar.template(fn)
|
||||||
if self._task._role is not None:
|
if self._task._role is not None:
|
||||||
lead = self._task._role._role_path
|
lead = self._task._role._role_path
|
||||||
|
@ -551,7 +556,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
def _get_diff_data(self, destination, source, task_vars, source_file=True):
|
def _get_diff_data(self, destination, source, task_vars, source_file=True):
|
||||||
|
|
||||||
diff = {}
|
diff = {}
|
||||||
self._display.debug("Going to peek to see if file has changed permissions")
|
display.debug("Going to peek to see if file has changed permissions")
|
||||||
peek_result = self._execute_module(module_name='file', module_args=dict(path=destination, diff_peek=True), task_vars=task_vars, persist_files=True)
|
peek_result = self._execute_module(module_name='file', module_args=dict(path=destination, diff_peek=True), task_vars=task_vars, persist_files=True)
|
||||||
|
|
||||||
if not('failed' in peek_result and peek_result['failed']) or peek_result.get('rc', 0) == 0:
|
if not('failed' in peek_result and peek_result['failed']) or peek_result.get('rc', 0) == 0:
|
||||||
|
@ -563,7 +568,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
elif peek_result['size'] > C.MAX_FILE_SIZE_FOR_DIFF:
|
elif peek_result['size'] > C.MAX_FILE_SIZE_FOR_DIFF:
|
||||||
diff['dst_larger'] = C.MAX_FILE_SIZE_FOR_DIFF
|
diff['dst_larger'] = C.MAX_FILE_SIZE_FOR_DIFF
|
||||||
else:
|
else:
|
||||||
self._display.debug("Slurping the file %s" % source)
|
display.debug("Slurping the file %s" % source)
|
||||||
dest_result = self._execute_module(module_name='slurp', module_args=dict(path=destination), task_vars=task_vars, persist_files=True)
|
dest_result = self._execute_module(module_name='slurp', module_args=dict(path=destination), task_vars=task_vars, persist_files=True)
|
||||||
if 'content' in dest_result:
|
if 'content' in dest_result:
|
||||||
dest_contents = dest_result['content']
|
dest_contents = dest_result['content']
|
||||||
|
@ -575,7 +580,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
diff['before'] = dest_contents
|
diff['before'] = dest_contents
|
||||||
|
|
||||||
if source_file:
|
if source_file:
|
||||||
self._display.debug("Reading local copy of the file %s" % source)
|
display.debug("Reading local copy of the file %s" % source)
|
||||||
try:
|
try:
|
||||||
src = open(source)
|
src = open(source)
|
||||||
src_contents = src.read(8192)
|
src_contents = src.read(8192)
|
||||||
|
@ -590,7 +595,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
|
||||||
diff['after_header'] = source
|
diff['after_header'] = source
|
||||||
diff['after'] = src_contents
|
diff['after'] = src_contents
|
||||||
else:
|
else:
|
||||||
self._display.debug("source of file passed in")
|
display.debug("source of file passed in")
|
||||||
diff['after_header'] = 'dynamically generated'
|
diff['after_header'] = 'dynamically generated'
|
||||||
diff['after'] = source
|
diff['after'] = source
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,13 @@ from ansible.plugins.action import ActionBase
|
||||||
from ansible.parsing.utils.addresses import parse_address
|
from ansible.parsing.utils.addresses import parse_address
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
|
|
||||||
|
try:
|
||||||
|
from __main__ import display
|
||||||
|
display = display
|
||||||
|
except ImportError:
|
||||||
|
from ansible.utils.display import Display
|
||||||
|
display = Display()
|
||||||
|
|
||||||
|
|
||||||
class ActionModule(ActionBase):
|
class ActionModule(ActionBase):
|
||||||
''' Create inventory hosts and groups in the memory inventory'''
|
''' Create inventory hosts and groups in the memory inventory'''
|
||||||
|
@ -45,7 +52,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
# Parse out any hostname:port patterns
|
# Parse out any hostname:port patterns
|
||||||
new_name = self._task.args.get('name', self._task.args.get('hostname', None))
|
new_name = self._task.args.get('name', self._task.args.get('hostname', None))
|
||||||
self._display.vv("creating host via 'add_host': hostname=%s" % new_name)
|
display.vv("creating host via 'add_host': hostname=%s" % new_name)
|
||||||
|
|
||||||
name, port = parse_address(new_name, allow_ranges=False)
|
name, port = parse_address(new_name, allow_ranges=False)
|
||||||
if not name:
|
if not name:
|
||||||
|
|
|
@ -19,6 +19,13 @@ __metaclass__ = type
|
||||||
|
|
||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
|
|
||||||
|
try:
|
||||||
|
from __main__ import display
|
||||||
|
display = display
|
||||||
|
except ImportError:
|
||||||
|
from ansible.utils.display import Display
|
||||||
|
display = Display()
|
||||||
|
|
||||||
|
|
||||||
class ActionModule(ActionBase):
|
class ActionModule(ActionBase):
|
||||||
|
|
||||||
|
@ -41,7 +48,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
if module == 'auto':
|
if module == 'auto':
|
||||||
facts = self._execute_module(module_name='setup', module_args=dict(filter='ansible_pkg_mgr'), task_vars=task_vars)
|
facts = self._execute_module(module_name='setup', module_args=dict(filter='ansible_pkg_mgr'), task_vars=task_vars)
|
||||||
self._display.debug("Facts %s" % facts)
|
display.debug("Facts %s" % facts)
|
||||||
if 'failed' not in facts:
|
if 'failed' not in facts:
|
||||||
module = getattr(facts['ansible_facts'], 'ansible_pkg_mgr', 'auto')
|
module = getattr(facts['ansible_facts'], 'ansible_pkg_mgr', 'auto')
|
||||||
|
|
||||||
|
@ -57,7 +64,7 @@ class ActionModule(ActionBase):
|
||||||
if 'use' in new_module_args:
|
if 'use' in new_module_args:
|
||||||
del new_module_args['use']
|
del new_module_args['use']
|
||||||
|
|
||||||
self._display.vvvv("Running %s" % module)
|
display.vvvv("Running %s" % module)
|
||||||
result.update(self._execute_module(module_name=module, module_args=new_module_args, task_vars=task_vars))
|
result.update(self._execute_module(module_name=module, module_args=new_module_args, task_vars=task_vars))
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -27,6 +27,13 @@ from os import isatty
|
||||||
from ansible.errors import AnsibleError
|
from ansible.errors import AnsibleError
|
||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
|
|
||||||
|
try:
|
||||||
|
from __main__ import display
|
||||||
|
display = display
|
||||||
|
except ImportError:
|
||||||
|
from ansible.utils.display import Display
|
||||||
|
display = Display()
|
||||||
|
|
||||||
|
|
||||||
class AnsibleTimeoutExceeded(Exception):
|
class AnsibleTimeoutExceeded(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -105,10 +112,10 @@ class ActionModule(ActionBase):
|
||||||
signal.signal(signal.SIGALRM, timeout_handler)
|
signal.signal(signal.SIGALRM, timeout_handler)
|
||||||
signal.alarm(seconds)
|
signal.alarm(seconds)
|
||||||
# show the prompt
|
# show the prompt
|
||||||
self._display.display("Pausing for %d seconds" % seconds)
|
display.display("Pausing for %d seconds" % seconds)
|
||||||
self._display.display("(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)\r"),
|
display.display("(ctrl+C then 'C' = continue early, ctrl+C then 'A' = abort)\r"),
|
||||||
else:
|
else:
|
||||||
self._display.display(prompt)
|
display.display(prompt)
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -129,7 +136,7 @@ class ActionModule(ActionBase):
|
||||||
|
|
||||||
if not seconds:
|
if not seconds:
|
||||||
if not isatty(fd):
|
if not isatty(fd):
|
||||||
self._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 == '\r':
|
||||||
|
@ -140,7 +147,7 @@ class ActionModule(ActionBase):
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
if seconds is not None:
|
if seconds is not None:
|
||||||
signal.alarm(0)
|
signal.alarm(0)
|
||||||
self._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():
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue