1
0
Fork 0
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:
Toshio Kuratomi 2015-11-11 08:29:37 -08:00
parent 186e034515
commit 4c7128da17
4 changed files with 68 additions and 42 deletions

View file

@ -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

View file

@ -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:

View file

@ -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:

View file

@ -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: