mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-26 20:31:27 -07:00
* Using docstrings conflicts with the standard use of docstrings * PYTHON_OPTIMIZE=2 will omit docstrings. Using docstrings makes future changes to the plugin and module code subject to the requirement that we ensure it won't be run with optimization.
79 lines
3.1 KiB
Python
79 lines
3.1 KiB
Python
# (c) 2017, Frederic Van Espen <github@freh.be>
|
|
# (c) 2017 Ansible Project
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
# Make coding more python3-ish
|
|
from __future__ import (absolute_import, division, print_function)
|
|
__metaclass__ = type
|
|
|
|
DOCUMENTATION = '''
|
|
callback: stderr
|
|
callback_type: stdout
|
|
requirements:
|
|
- set as main display callback
|
|
short_description: Splits output, sending failed tasks to stderr
|
|
version_added: "2.4"
|
|
description:
|
|
- This is the stderr callback plugin, it behaves like the default callback plugin but sends error output to stderr.
|
|
- Also it does not output skipped host/task/item status
|
|
'''
|
|
|
|
from ansible import constants as C
|
|
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
|
|
|
|
|
|
class CallbackModule(CallbackModule_default):
|
|
|
|
'''
|
|
This is the stderr callback plugin, which reuses the default
|
|
callback plugin but sends error output to stderr.
|
|
'''
|
|
|
|
CALLBACK_VERSION = 2.0
|
|
CALLBACK_TYPE = 'stdout'
|
|
CALLBACK_NAME = 'stderr'
|
|
|
|
def __init__(self):
|
|
|
|
self.super_ref = super(CallbackModule, self)
|
|
self.super_ref.__init__()
|
|
|
|
def v2_runner_on_failed(self, result, ignore_errors=False):
|
|
|
|
delegated_vars = result._result.get('_ansible_delegated_vars', None)
|
|
self._clean_results(result._result, result._task.action)
|
|
|
|
if self._play.strategy == 'free' and self._last_task_banner != result._task._uuid:
|
|
self._print_task_banner(result._task)
|
|
|
|
self._handle_exception(result._result, errors_to_stderr=True)
|
|
self._handle_warnings(result._result)
|
|
|
|
if result._task.loop and 'results' in result._result:
|
|
self._process_items(result)
|
|
|
|
else:
|
|
if delegated_vars:
|
|
self._display.display("fatal: [%s -> %s]: FAILED! => %s" % (result._host.get_name(), delegated_vars['ansible_host'],
|
|
self._dump_results(result._result)), color=C.COLOR_ERROR,
|
|
stderr=True)
|
|
else:
|
|
self._display.display("fatal: [%s]: FAILED! => %s" % (result._host.get_name(), self._dump_results(result._result)),
|
|
color=C.COLOR_ERROR, stderr=True)
|
|
|
|
if ignore_errors:
|
|
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
|
|
|
def _handle_exception(self, result, errors_to_stderr=False):
|
|
|
|
if 'exception' in result:
|
|
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, stderr=errors_to_stderr)
|