mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-06-14 03:55:37 +00:00
[PR #12067/f677c2ab backport][stable-13] counter_enabled callback: display output for looped tasks (#12241)
counter_enabled callback: display output for looped tasks (#12067)
* fix(counter_enabled): display output for looped tasks with delegate_to
Implement v2_runner_item_on_ok, v2_runner_item_on_failed, and
v2_runner_item_on_skipped so that looped tasks (including those
using delegate_to: localhost) produce visible output.
Also extract _host_label, _display_result_ok, _display_result_failed,
and _display_result_skipped helpers to eliminate repeated delegation
and message-building logic across the callback methods.
Fixes #8187
* changelog(counter_enabled): add fragment for PR #12067
* test(counter_enabled): add integration tests, adjust _host_label
* test(counter_enabled): migrate integration tests to callback test framework
* test(counter_enabled): fix integration tests to use set_fact instead of debug
---------
(cherry picked from commit f677c2ab7d)
Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
c14620fcf6
commit
5bb9c6c805
4 changed files with 165 additions and 56 deletions
|
|
@ -140,69 +140,83 @@ class CallbackModule(CallbackBase):
|
|||
self._host_counter = self._previous_batch_total
|
||||
self._task_counter += 1
|
||||
|
||||
def v2_runner_on_ok(self, result):
|
||||
self._host_counter += 1
|
||||
|
||||
delegated_vars = result._result.get("_ansible_delegated_vars", None)
|
||||
|
||||
if self._play.strategy == "free" and self._last_task_banner != result._task._uuid:
|
||||
self._print_task_banner(result._task)
|
||||
def _host_label(self, result):
|
||||
host_name = result._host.get_name()
|
||||
delegate_to = result._task.delegate_to
|
||||
if delegate_to and delegate_to != host_name:
|
||||
delegated_vars = result._result.get("_ansible_delegated_vars", {})
|
||||
ahost = delegated_vars.get("ansible_host", delegate_to)
|
||||
label = f"{host_name} -> {delegate_to}"
|
||||
if ahost != delegate_to:
|
||||
label += f"({ahost})"
|
||||
return f"[{label}]"
|
||||
return f"[{host_name}]"
|
||||
|
||||
def _display_result_ok(self, result, counter_str="", item_suffix=""):
|
||||
if isinstance(result._task, TaskInclude):
|
||||
return
|
||||
elif result._result.get("changed", False):
|
||||
if delegated_vars:
|
||||
msg = f"changed: {self._host_counter}/{self._host_total} [{result._host.get_name()} -> {delegated_vars['ansible_host']}]"
|
||||
else:
|
||||
msg = f"changed: {self._host_counter}/{self._host_total} [{result._host.get_name()}]"
|
||||
msg = f"changed: {counter_str}{self._host_label(result)}{item_suffix}"
|
||||
color = C.COLOR_CHANGED
|
||||
else:
|
||||
if not self._plugin_options.get("display_ok_hosts", True):
|
||||
return
|
||||
if delegated_vars:
|
||||
msg = f"ok: {self._host_counter}/{self._host_total} [{result._host.get_name()} -> {delegated_vars['ansible_host']}]"
|
||||
else:
|
||||
msg = f"ok: {self._host_counter}/{self._host_total} [{result._host.get_name()}]"
|
||||
msg = f"ok: {counter_str}{self._host_label(result)}{item_suffix}"
|
||||
color = C.COLOR_OK
|
||||
|
||||
self._handle_warnings(result._result)
|
||||
self._clean_results(result._result, result._task.action)
|
||||
if self._run_is_verbose(result):
|
||||
msg += f" => {self._dump_results(result._result)}"
|
||||
self._display.display(msg, color=color)
|
||||
|
||||
def v2_runner_on_ok(self, result):
|
||||
self._host_counter += 1
|
||||
|
||||
if self._play.strategy == "free" and self._last_task_banner != result._task._uuid:
|
||||
self._print_task_banner(result._task)
|
||||
|
||||
if result._task.loop and "results" in result._result:
|
||||
self._process_items(result)
|
||||
else:
|
||||
self._clean_results(result._result, result._task.action)
|
||||
self._display_result_ok(result, f"{self._host_counter}/{self._host_total} ")
|
||||
|
||||
if self._run_is_verbose(result):
|
||||
msg += f" => {self._dump_results(result._result)}"
|
||||
self._display.display(msg, color=color)
|
||||
def v2_runner_item_on_ok(self, result):
|
||||
self._display_result_ok(result, item_suffix=f" => (item={self._get_item_label(result._result)})")
|
||||
|
||||
def _display_result_failed(self, result, counter_str="", item_suffix=""):
|
||||
self._clean_results(result._result, result._task.action)
|
||||
self._handle_warnings(result._result)
|
||||
prefix = "failed" if item_suffix else "fatal"
|
||||
msg = f"{prefix}: {counter_str}{self._host_label(result)}{item_suffix}"
|
||||
self._display.display(f"{msg} => {self._dump_results(result._result)}", color=C.COLOR_ERROR)
|
||||
|
||||
def v2_runner_item_on_failed(self, result):
|
||||
self._display_result_failed(result, item_suffix=f" (item={self._get_item_label(result._result)})")
|
||||
|
||||
def _display_result_skipped(self, result, counter_str="", item_suffix=""):
|
||||
self._clean_results(result._result, result._task.action)
|
||||
msg = f"skipping: {counter_str}[{result._host.get_name()}]{item_suffix}"
|
||||
if self._run_is_verbose(result):
|
||||
msg += f" => {self._dump_results(result._result)}"
|
||||
self._display.display(msg, color=C.COLOR_SKIP)
|
||||
|
||||
def v2_runner_item_on_skipped(self, result):
|
||||
if self._plugin_options.get("show_skipped_hosts", C.DISPLAY_SKIPPED_HOSTS):
|
||||
self._display_result_skipped(result, item_suffix=f" => (item={self._get_item_label(result._result)})")
|
||||
|
||||
def v2_runner_on_failed(self, result, ignore_errors=False):
|
||||
self._host_counter += 1
|
||||
|
||||
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)
|
||||
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(
|
||||
f"fatal: {self._host_counter}/{self._host_total} [{result._host.get_name()} -> "
|
||||
f"{delegated_vars['ansible_host']}]: FAILED! => {self._dump_results(result._result)}",
|
||||
color=C.COLOR_ERROR,
|
||||
)
|
||||
else:
|
||||
self._display.display(
|
||||
f"fatal: {self._host_counter}/{self._host_total} [{result._host.get_name()}]: FAILED! => {self._dump_results(result._result)}",
|
||||
color=C.COLOR_ERROR,
|
||||
)
|
||||
self._display_result_failed(result, f"{self._host_counter}/{self._host_total} ", ": FAILED!")
|
||||
|
||||
if ignore_errors:
|
||||
self._display.display("...ignoring", color=C.COLOR_SKIP)
|
||||
|
|
@ -210,21 +224,14 @@ class CallbackModule(CallbackBase):
|
|||
def v2_runner_on_skipped(self, result):
|
||||
self._host_counter += 1
|
||||
|
||||
if self._plugin_options.get(
|
||||
"show_skipped_hosts", C.DISPLAY_SKIPPED_HOSTS
|
||||
): # fallback on constants for inherited plugins missing docs
|
||||
self._clean_results(result._result, result._task.action)
|
||||
|
||||
if self._plugin_options.get("show_skipped_hosts", C.DISPLAY_SKIPPED_HOSTS):
|
||||
if self._play.strategy == "free" and self._last_task_banner != result._task._uuid:
|
||||
self._print_task_banner(result._task)
|
||||
|
||||
if result._task.loop and "results" in result._result:
|
||||
self._process_items(result)
|
||||
else:
|
||||
msg = f"skipping: {self._host_counter}/{self._host_total} [{result._host.get_name()}]"
|
||||
if self._run_is_verbose(result):
|
||||
msg += f" => {self._dump_results(result._result)}"
|
||||
self._display.display(msg, color=C.COLOR_SKIP)
|
||||
self._display_result_skipped(result, f"{self._host_counter}/{self._host_total} ")
|
||||
|
||||
def v2_runner_on_unreachable(self, result):
|
||||
self._host_counter += 1
|
||||
|
|
@ -232,15 +239,7 @@ class CallbackModule(CallbackBase):
|
|||
if self._play.strategy == "free" and self._last_task_banner != result._task._uuid:
|
||||
self._print_task_banner(result._task)
|
||||
|
||||
delegated_vars = result._result.get("_ansible_delegated_vars", None)
|
||||
if delegated_vars:
|
||||
self._display.display(
|
||||
f"fatal: {self._host_counter}/{self._host_total} [{result._host.get_name()} -> "
|
||||
f"{delegated_vars['ansible_host']}]: UNREACHABLE! => {self._dump_results(result._result)}",
|
||||
color=C.COLOR_UNREACHABLE,
|
||||
)
|
||||
else:
|
||||
self._display.display(
|
||||
f"fatal: {self._host_counter}/{self._host_total} [{result._host.get_name()}]: UNREACHABLE! => {self._dump_results(result._result)}",
|
||||
color=C.COLOR_UNREACHABLE,
|
||||
)
|
||||
self._display.display(
|
||||
f"fatal: {self._host_counter}/{self._host_total} {self._host_label(result)}: UNREACHABLE! => {self._dump_results(result._result)}",
|
||||
color=C.COLOR_UNREACHABLE,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue