|
|
@ -27,22 +27,6 @@ from ansible.plugins.callback import CallbackBase
|
|
|
|
from ansible.utils.color import colorize, hostcolor
|
|
|
|
from ansible.utils.color import colorize, hostcolor
|
|
|
|
from ansible.utils.fqcn import add_internal_fqcns
|
|
|
|
from ansible.utils.fqcn import add_internal_fqcns
|
|
|
|
|
|
|
|
|
|
|
|
# These values use ansible.constants for historical reasons, mostly to allow
|
|
|
|
|
|
|
|
# unmodified derivative plugins to work. However, newer options added to the
|
|
|
|
|
|
|
|
# plugin are not also added to ansible.constants, so authors of derivative
|
|
|
|
|
|
|
|
# callback plugins will eventually need to add a reference to the common docs
|
|
|
|
|
|
|
|
# fragment for the 'default' callback plugin
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# these are used to provide backwards compat with old plugins that subclass from default
|
|
|
|
|
|
|
|
# but still don't use the new config system and/or fail to document the options
|
|
|
|
|
|
|
|
# TODO: Change the default of check_mode_markers to True in a future release (2.13)
|
|
|
|
|
|
|
|
COMPAT_OPTIONS = (('display_skipped_hosts', C.DISPLAY_SKIPPED_HOSTS),
|
|
|
|
|
|
|
|
('display_ok_hosts', True),
|
|
|
|
|
|
|
|
('show_custom_stats', C.SHOW_CUSTOM_STATS),
|
|
|
|
|
|
|
|
('display_failed_stderr', False),
|
|
|
|
|
|
|
|
('check_mode_markers', False),
|
|
|
|
|
|
|
|
('show_per_host_start', False))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CallbackModule(CallbackBase):
|
|
|
|
class CallbackModule(CallbackBase):
|
|
|
|
|
|
|
|
|
|
|
@ -63,20 +47,6 @@ class CallbackModule(CallbackBase):
|
|
|
|
self._task_type_cache = {}
|
|
|
|
self._task_type_cache = {}
|
|
|
|
super(CallbackModule, self).__init__()
|
|
|
|
super(CallbackModule, self).__init__()
|
|
|
|
|
|
|
|
|
|
|
|
def set_options(self, task_keys=None, var_options=None, direct=None):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# for backwards compat with plugins subclassing default, fallback to constants
|
|
|
|
|
|
|
|
for option, constant in COMPAT_OPTIONS:
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
value = self.get_option(option)
|
|
|
|
|
|
|
|
except (AttributeError, KeyError):
|
|
|
|
|
|
|
|
self._display.deprecated("'%s' is subclassing DefaultCallback without the corresponding doc_fragment." % self._load_name,
|
|
|
|
|
|
|
|
version='2.14', collection_name='ansible.builtin')
|
|
|
|
|
|
|
|
value = constant
|
|
|
|
|
|
|
|
setattr(self, option, value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def v2_runner_on_failed(self, result, ignore_errors=False):
|
|
|
|
def v2_runner_on_failed(self, result, ignore_errors=False):
|
|
|
|
|
|
|
|
|
|
|
|
host_label = self.host_label(result)
|
|
|
|
host_label = self.host_label(result)
|
|
|
@ -85,7 +55,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
if self._last_task_banner != result._task._uuid:
|
|
|
|
if self._last_task_banner != result._task._uuid:
|
|
|
|
self._print_task_banner(result._task)
|
|
|
|
self._print_task_banner(result._task)
|
|
|
|
|
|
|
|
|
|
|
|
self._handle_exception(result._result, use_stderr=self.display_failed_stderr)
|
|
|
|
self._handle_exception(result._result, use_stderr=self.get_option('display_failed_stderr'))
|
|
|
|
self._handle_warnings(result._result)
|
|
|
|
self._handle_warnings(result._result)
|
|
|
|
|
|
|
|
|
|
|
|
if result._task.loop and 'results' in result._result:
|
|
|
|
if result._task.loop and 'results' in result._result:
|
|
|
@ -95,7 +65,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
if self._display.verbosity < 2 and self.get_option('show_task_path_on_failure'):
|
|
|
|
if self._display.verbosity < 2 and self.get_option('show_task_path_on_failure'):
|
|
|
|
self._print_task_path(result._task)
|
|
|
|
self._print_task_path(result._task)
|
|
|
|
msg = "fatal: [%s]: FAILED! => %s" % (host_label, self._dump_results(result._result))
|
|
|
|
msg = "fatal: [%s]: FAILED! => %s" % (host_label, self._dump_results(result._result))
|
|
|
|
self._display.display(msg, color=C.COLOR_ERROR, stderr=self.display_failed_stderr)
|
|
|
|
self._display.display(msg, color=C.COLOR_ERROR, stderr=self.get_option('display_failed_stderr'))
|
|
|
|
|
|
|
|
|
|
|
|
if ignore_errors:
|
|
|
|
if ignore_errors:
|
|
|
|
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
|
|
|
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
|
|
@ -115,7 +85,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
msg = "changed: [%s]" % (host_label,)
|
|
|
|
msg = "changed: [%s]" % (host_label,)
|
|
|
|
color = C.COLOR_CHANGED
|
|
|
|
color = C.COLOR_CHANGED
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
if not self.display_ok_hosts:
|
|
|
|
if not self.get_option('display_ok_hosts'):
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
if self._last_task_banner != result._task._uuid:
|
|
|
|
if self._last_task_banner != result._task._uuid:
|
|
|
@ -137,7 +107,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
|
|
|
|
|
|
|
|
def v2_runner_on_skipped(self, result):
|
|
|
|
def v2_runner_on_skipped(self, result):
|
|
|
|
|
|
|
|
|
|
|
|
if self.display_skipped_hosts:
|
|
|
|
if self.get_option('display_skipped_hosts'):
|
|
|
|
|
|
|
|
|
|
|
|
self._clean_results(result._result, result._task.action)
|
|
|
|
self._clean_results(result._result, result._task.action)
|
|
|
|
|
|
|
|
|
|
|
@ -158,7 +128,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
|
|
|
|
|
|
|
|
host_label = self.host_label(result)
|
|
|
|
host_label = self.host_label(result)
|
|
|
|
msg = "fatal: [%s]: UNREACHABLE! => %s" % (host_label, self._dump_results(result._result))
|
|
|
|
msg = "fatal: [%s]: UNREACHABLE! => %s" % (host_label, self._dump_results(result._result))
|
|
|
|
self._display.display(msg, color=C.COLOR_UNREACHABLE, stderr=self.display_failed_stderr)
|
|
|
|
self._display.display(msg, color=C.COLOR_UNREACHABLE, stderr=self.get_option('display_failed_stderr'))
|
|
|
|
|
|
|
|
|
|
|
|
def v2_playbook_on_no_hosts_matched(self):
|
|
|
|
def v2_playbook_on_no_hosts_matched(self):
|
|
|
|
self._display.display("skipping: no hosts matched", color=C.COLOR_SKIP)
|
|
|
|
self._display.display("skipping: no hosts matched", color=C.COLOR_SKIP)
|
|
|
@ -186,7 +156,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
self._last_task_name = task.get_name().strip()
|
|
|
|
self._last_task_name = task.get_name().strip()
|
|
|
|
|
|
|
|
|
|
|
|
# Display the task banner immediately if we're not doing any filtering based on task result
|
|
|
|
# Display the task banner immediately if we're not doing any filtering based on task result
|
|
|
|
if self.display_skipped_hosts and self.display_ok_hosts:
|
|
|
|
if self.get_option('display_skipped_hosts') and self.get_option('display_ok_hosts'):
|
|
|
|
self._print_task_banner(task)
|
|
|
|
self._print_task_banner(task)
|
|
|
|
|
|
|
|
|
|
|
|
def _print_task_banner(self, task):
|
|
|
|
def _print_task_banner(self, task):
|
|
|
@ -210,7 +180,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
if task_name is None:
|
|
|
|
if task_name is None:
|
|
|
|
task_name = task.get_name().strip()
|
|
|
|
task_name = task.get_name().strip()
|
|
|
|
|
|
|
|
|
|
|
|
if task.check_mode and self.check_mode_markers:
|
|
|
|
if task.check_mode and self.get_option('check_mode_markers'):
|
|
|
|
checkmsg = " [CHECK MODE]"
|
|
|
|
checkmsg = " [CHECK MODE]"
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
checkmsg = ""
|
|
|
|
checkmsg = ""
|
|
|
@ -233,7 +203,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
|
|
|
|
|
|
|
|
def v2_playbook_on_play_start(self, play):
|
|
|
|
def v2_playbook_on_play_start(self, play):
|
|
|
|
name = play.get_name().strip()
|
|
|
|
name = play.get_name().strip()
|
|
|
|
if play.check_mode and self.check_mode_markers:
|
|
|
|
if play.check_mode and self.get_option('check_mode_markers'):
|
|
|
|
checkmsg = " [CHECK MODE]"
|
|
|
|
checkmsg = " [CHECK MODE]"
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
checkmsg = ""
|
|
|
|
checkmsg = ""
|
|
|
@ -274,7 +244,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
msg = 'changed'
|
|
|
|
msg = 'changed'
|
|
|
|
color = C.COLOR_CHANGED
|
|
|
|
color = C.COLOR_CHANGED
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
if not self.display_ok_hosts:
|
|
|
|
if not self.get_option('display_ok_hosts'):
|
|
|
|
return
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
|
if self._last_task_banner != result._task._uuid:
|
|
|
|
if self._last_task_banner != result._task._uuid:
|
|
|
@ -295,18 +265,18 @@ class CallbackModule(CallbackBase):
|
|
|
|
|
|
|
|
|
|
|
|
host_label = self.host_label(result)
|
|
|
|
host_label = self.host_label(result)
|
|
|
|
self._clean_results(result._result, result._task.action)
|
|
|
|
self._clean_results(result._result, result._task.action)
|
|
|
|
self._handle_exception(result._result, use_stderr=self.display_failed_stderr)
|
|
|
|
self._handle_exception(result._result, use_stderr=self.get_option('display_failed_stderr'))
|
|
|
|
|
|
|
|
|
|
|
|
msg = "failed: [%s]" % (host_label,)
|
|
|
|
msg = "failed: [%s]" % (host_label,)
|
|
|
|
self._handle_warnings(result._result)
|
|
|
|
self._handle_warnings(result._result)
|
|
|
|
self._display.display(
|
|
|
|
self._display.display(
|
|
|
|
msg + " (item=%s) => %s" % (self._get_item_label(result._result), self._dump_results(result._result)),
|
|
|
|
msg + " (item=%s) => %s" % (self._get_item_label(result._result), self._dump_results(result._result)),
|
|
|
|
color=C.COLOR_ERROR,
|
|
|
|
color=C.COLOR_ERROR,
|
|
|
|
stderr=self.display_failed_stderr
|
|
|
|
stderr=self.get_option('display_failed_stderr')
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def v2_runner_item_on_skipped(self, result):
|
|
|
|
def v2_runner_item_on_skipped(self, result):
|
|
|
|
if self.display_skipped_hosts:
|
|
|
|
if self.get_option('display_skipped_hosts'):
|
|
|
|
if self._last_task_banner != result._task._uuid:
|
|
|
|
if self._last_task_banner != result._task._uuid:
|
|
|
|
self._print_task_banner(result._task)
|
|
|
|
self._print_task_banner(result._task)
|
|
|
|
|
|
|
|
|
|
|
@ -361,7 +331,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
self._display.display("", screen_only=True)
|
|
|
|
self._display.display("", screen_only=True)
|
|
|
|
|
|
|
|
|
|
|
|
# print custom stats if required
|
|
|
|
# print custom stats if required
|
|
|
|
if stats.custom and self.show_custom_stats:
|
|
|
|
if stats.custom and self.get_option('show_custom_stats'):
|
|
|
|
self._display.banner("CUSTOM STATS: ")
|
|
|
|
self._display.banner("CUSTOM STATS: ")
|
|
|
|
# per host
|
|
|
|
# per host
|
|
|
|
# TODO: come up with 'pretty format'
|
|
|
|
# TODO: come up with 'pretty format'
|
|
|
@ -376,7 +346,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
self._display.display('\tRUN: %s' % self._dump_results(stats.custom['_run'], indent=1).replace('\n', ''))
|
|
|
|
self._display.display('\tRUN: %s' % self._dump_results(stats.custom['_run'], indent=1).replace('\n', ''))
|
|
|
|
self._display.display("", screen_only=True)
|
|
|
|
self._display.display("", screen_only=True)
|
|
|
|
|
|
|
|
|
|
|
|
if context.CLIARGS['check'] and self.check_mode_markers:
|
|
|
|
if context.CLIARGS['check'] and self.get_option('check_mode_markers'):
|
|
|
|
self._display.banner("DRY RUN")
|
|
|
|
self._display.banner("DRY RUN")
|
|
|
|
|
|
|
|
|
|
|
|
def v2_playbook_on_start(self, playbook):
|
|
|
|
def v2_playbook_on_start(self, playbook):
|
|
|
@ -395,7 +365,7 @@ class CallbackModule(CallbackBase):
|
|
|
|
if val:
|
|
|
|
if val:
|
|
|
|
self._display.display('%s: %s' % (argument, val), color=C.COLOR_VERBOSE, screen_only=True)
|
|
|
|
self._display.display('%s: %s' % (argument, val), color=C.COLOR_VERBOSE, screen_only=True)
|
|
|
|
|
|
|
|
|
|
|
|
if context.CLIARGS['check'] and self.check_mode_markers:
|
|
|
|
if context.CLIARGS['check'] and self.get_option('check_mode_markers'):
|
|
|
|
self._display.banner("DRY RUN")
|
|
|
|
self._display.banner("DRY RUN")
|
|
|
|
|
|
|
|
|
|
|
|
def v2_runner_retry(self, result):
|
|
|
|
def v2_runner_retry(self, result):
|
|
|
|