Coverage for lib/ansible/plugins/callback/__init__.py : 40%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com> # # This file is part of Ansible # # Ansible is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ansible is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
except ImportError: from ansible.utils.display import Display global_display = Display()
except ImportError: # using API w/o cli cli = False
''' This is a base ansible callback class that does nothing. New callbacks should use this class as a base and override any callback methods they wish to execute custom actions. '''
self._display = display else:
self._options = cli.options else:
self.set_options(options)
''' helper for callbacks, so they don't all have to include deepcopy '''
self._plugin_options[k] = v
return self._plugin_options[k]
''' This is different than the normal plugin method as callbacks get called early and really don't accept keywords. Also _options was already taken for CLI args and callbacks use _plugin_options instead. '''
# load from config
# or parse specific options for k in direct: if k in self._plugin_options: self.set_option(k, direct[k])
# All result keys stating with _ansible_ are internal, so remove them from the result before we output anything.
# remove invocation unless specifically wanting it del abridged_result['invocation']
# remove diff information from screen output del abridged_result['diff']
# remove exception from screen output del abridged_result['exception']
''' display warnings, if enabled and any exist in the result ''' for warning in res['warnings']: self._display.warning(warning) del res['warnings']
msg = "An exception occurred during task execution. " if self._display.verbosity < 3: # extract just the actual error message from the exception text error = result['exception'].strip().split('\n')[-1] msg += "To see the full traceback, use -vvv. The error was: %s" % error else: msg = "The full traceback is:\n" + result['exception'] del result['exception']
self._display.display(msg, color=C.COLOR_ERROR)
if not isinstance(difflist, list): difflist = [difflist]
ret = [] for diff in difflist: try: with warnings.catch_warnings(): warnings.simplefilter('ignore') if 'dst_binary' in diff: ret.append("diff skipped: destination file appears to be binary\n") if 'src_binary' in diff: ret.append("diff skipped: source file appears to be binary\n") if 'dst_larger' in diff: ret.append("diff skipped: destination file size is greater than %d\n" % diff['dst_larger']) if 'src_larger' in diff: ret.append("diff skipped: source file size is greater than %d\n" % diff['src_larger']) if 'before' in diff and 'after' in diff: # format complex structures into 'files' for x in ['before', 'after']: if isinstance(diff[x], dict): diff[x] = json.dumps(diff[x], sort_keys=True, indent=4, separators=(',', ': ')) + '\n' if 'before_header' in diff: before_header = "before: %s" % diff['before_header'] else: before_header = 'before' if 'after_header' in diff: after_header = "after: %s" % diff['after_header'] else: after_header = 'after' before_lines = to_text(diff['before']).splitlines(True) after_lines = to_text(diff['after']).splitlines(True) if before_lines and not before_lines[-1].endswith('\n'): before_lines[-1] += '\n\\ No newline at end of file\n' if after_lines and not after_lines[-1].endswith('\n'): after_lines[-1] += '\n\\ No newline at end of file\n' differ = difflib.unified_diff(before_lines, after_lines, fromfile=before_header, tofile=after_header, fromfiledate='', tofiledate='', n=C.DIFF_CONTEXT) difflines = list(differ) if len(difflines) >= 3 and sys.version_info[:2] == (2, 6): # difflib in Python 2.6 adds trailing spaces after # filenames in the -- before/++ after headers. difflines[0] = difflines[0].replace(' \n', '\n') difflines[1] = difflines[1].replace(' \n', '\n') # it also treats empty files differently difflines[2] = difflines[2].replace('-1,0', '-0,0').replace('+1,0', '+0,0') has_diff = False for line in difflines: has_diff = True if line.startswith('+'): line = stringc(line, C.COLOR_DIFF_ADD) elif line.startswith('-'): line = stringc(line, C.COLOR_DIFF_REMOVE) elif line.startswith('@@'): line = stringc(line, C.COLOR_DIFF_LINES) ret.append(line) if has_diff: ret.append('\n') if 'prepared' in diff: ret.append(to_text(diff['prepared'])) except UnicodeDecodeError: ret.append(">> the files are different, but the diff library cannot compare unicode strings\n\n") return u''.join(ret)
item = "(censored due to no_log)" item = result.get('_ansible_item_label') else:
# just remove them as now they get handled by individual callbacks
''' removes data from results for display '''
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
pass
# V2 METHODS, by default they call v1 counterparts if possible
host = result._host.get_name() self.runner_on_failed(host, result._result, ignore_errors)
host = result._host.get_name() self.runner_on_ok(host, result._result)
if C.DISPLAY_SKIPPED_HOSTS: host = result._host.get_name() self.runner_on_skipped(host, self._get_item(getattr(result._result, 'results', {})))
host = result._host.get_name() self.runner_on_unreachable(host, result._result)
# FIXME: not called host = result._host.get_name() jid = result._result.get('ansible_job_id') # FIXME, get real clock clock = 0 self.runner_on_async_poll(host, result._result, jid, clock)
# FIXME: not called host = result._host.get_name() jid = result._result.get('ansible_job_id') self.runner_on_async_ok(host, result._result, jid)
# FIXME: not called host = result._host.get_name() jid = result._result.get('ansible_job_id') self.runner_on_async_failed(host, result._result, jid)
self.playbook_on_start()
self.playbook_on_notify(host, handler)
self.playbook_on_no_hosts_matched()
self.playbook_on_no_hosts_remaining()
self.playbook_on_task_start(task.name, is_conditional)
# FIXME: not called pass # no v1 correspondence
pass # no v1 correspondence
self.playbook_on_vars_prompt(varname, private, prompt, encrypt, confirm, salt_size, salt, default)
# FIXME: not called host = result._host.get_name() self.playbook_on_import_for_host(host, imported_file)
# FIXME: not called host = result._host.get_name() self.playbook_on_not_import_for_host(host, missing_file)
self.playbook_on_play_start(play.name)
self.playbook_on_stats(stats)
if 'diff' in result._result: host = result._host.get_name() self.on_file_diff(host, result._result['diff'])
pass # no v1 correspondence
pass
pass
pass
pass |