From 4d43d71dcb5d562a710d1ce9d63d333ae6a21b94 Mon Sep 17 00:00:00 2001 From: ksaegusa Date: Thu, 28 Aug 2025 23:12:59 +0900 Subject: [PATCH 1/3] add display_included_hosts option --- changelogs/fragments/display_included_hosts.yml | 2 ++ lib/ansible/plugins/callback/default.py | 11 ++++++----- lib/ansible/plugins/doc_fragments/default_callback.py | 10 ++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/display_included_hosts.yml diff --git a/changelogs/fragments/display_included_hosts.yml b/changelogs/fragments/display_included_hosts.yml new file mode 100644 index 00000000000..145d4399ec9 --- /dev/null +++ b/changelogs/fragments/display_included_hosts.yml @@ -0,0 +1,2 @@ +minor_changes: + - default callback - add `display_included_hosts` option to control the `included:` banner lines for include_tasks/include_role. diff --git a/lib/ansible/plugins/callback/default.py b/lib/ansible/plugins/callback/default.py index 5032d917c42..3da66ea38b9 100644 --- a/lib/ansible/plugins/callback/default.py +++ b/lib/ansible/plugins/callback/default.py @@ -293,11 +293,12 @@ class CallbackModule(CallbackBase): self._display.display(msg, color=C.COLOR_SKIP) def v2_playbook_on_include(self, included_file): - msg = 'included: %s for %s' % (included_file._filename, ", ".join([h.name for h in included_file._hosts])) - label = self._get_item_label(included_file._vars) - if label: - msg += " => (item=%s)" % label - self._display.display(msg, color=C.COLOR_INCLUDED) + if self.get_option("display_included_hosts"): + msg = 'included: %s for %s' % (included_file._filename, ", ".join([h.name for h in included_file._hosts])) + label = self._get_item_label(included_file._vars) + if label: + msg += " => (item=%s)" % label + self._display.display(msg, color=C.COLOR_INCLUDED) def v2_playbook_on_stats(self, stats): self._display.banner("PLAY RECAP") diff --git a/lib/ansible/plugins/doc_fragments/default_callback.py b/lib/ansible/plugins/doc_fragments/default_callback.py index 7c02c290b9f..e858c4e6319 100644 --- a/lib/ansible/plugins/doc_fragments/default_callback.py +++ b/lib/ansible/plugins/doc_fragments/default_callback.py @@ -9,6 +9,16 @@ class ModuleDocFragment(object): DOCUMENTATION = r""" options: + display_included_hosts: + name: Show included hosts + description: "Toggle to control displaying included task/host results in a task." + type: bool + default: yes + env: + - name: ANSIBLE_DISPLAY_INCLUDED_HOSTS + ini: + - key: display_included_hosts + section: defaults display_skipped_hosts: name: Show skipped hosts description: "Toggle to control displaying skipped task/host results in a task." From c8253bdcaf6ccc13bb68847c17a46445b0f1065c Mon Sep 17 00:00:00 2001 From: ksaegusa Date: Thu, 28 Aug 2025 23:43:35 +0900 Subject: [PATCH 2/3] callback/default+docs: early return; convert docs to RST MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Invert check; reduce indentation. Switch docs to RST (``…``, ::). --- changelogs/fragments/display_included_hosts.yml | 2 +- lib/ansible/plugins/callback/default.py | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/changelogs/fragments/display_included_hosts.yml b/changelogs/fragments/display_included_hosts.yml index 145d4399ec9..5d8052b668f 100644 --- a/changelogs/fragments/display_included_hosts.yml +++ b/changelogs/fragments/display_included_hosts.yml @@ -1,2 +1,2 @@ minor_changes: - - default callback - add `display_included_hosts` option to control the `included:` banner lines for include_tasks/include_role. + - default callback - add ``display_included_hosts`` option to control the ``included:`` banner lines for ``include_tasks``/``include_role``. diff --git a/lib/ansible/plugins/callback/default.py b/lib/ansible/plugins/callback/default.py index 3da66ea38b9..71d8b99c488 100644 --- a/lib/ansible/plugins/callback/default.py +++ b/lib/ansible/plugins/callback/default.py @@ -293,12 +293,14 @@ class CallbackModule(CallbackBase): self._display.display(msg, color=C.COLOR_SKIP) def v2_playbook_on_include(self, included_file): - if self.get_option("display_included_hosts"): - msg = 'included: %s for %s' % (included_file._filename, ", ".join([h.name for h in included_file._hosts])) - label = self._get_item_label(included_file._vars) - if label: - msg += " => (item=%s)" % label - self._display.display(msg, color=C.COLOR_INCLUDED) + if not self.get_option("display_included_hosts"): + return + + msg = 'included: %s for %s' % (included_file._filename, ", ".join([h.name for h in included_file._hosts])) + label = self._get_item_label(included_file._vars) + if label: + msg += " => (item=%s)" % label + self._display.display(msg, color=C.COLOR_INCLUDED) def v2_playbook_on_stats(self, stats): self._display.banner("PLAY RECAP") From 6f60c9eed6aee950a11d70cc72bc70f5c1246a78 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 12 Sep 2025 07:40:24 +0900 Subject: [PATCH 3/3] add display_included_hosts test --- .../plugins/doc_fragments/default_callback.py | 21 +-- .../callback_default.out.hide_included.stderr | 2 + .../callback_default.out.hide_included.stdout | 130 ++++++++++++++++++ ...efault.out.hide_skipped_ok_included.stderr | 2 + ...efault.out.hide_skipped_ok_included.stdout | 93 +++++++++++++ .../targets/callback_default/runme.sh | 21 +++ 6 files changed, 259 insertions(+), 10 deletions(-) create mode 100644 test/integration/targets/callback_default/callback_default.out.hide_included.stderr create mode 100644 test/integration/targets/callback_default/callback_default.out.hide_included.stdout create mode 100644 test/integration/targets/callback_default/callback_default.out.hide_skipped_ok_included.stderr create mode 100644 test/integration/targets/callback_default/callback_default.out.hide_skipped_ok_included.stdout diff --git a/lib/ansible/plugins/doc_fragments/default_callback.py b/lib/ansible/plugins/doc_fragments/default_callback.py index e858c4e6319..b8df0f4aa92 100644 --- a/lib/ansible/plugins/doc_fragments/default_callback.py +++ b/lib/ansible/plugins/doc_fragments/default_callback.py @@ -9,16 +9,6 @@ class ModuleDocFragment(object): DOCUMENTATION = r""" options: - display_included_hosts: - name: Show included hosts - description: "Toggle to control displaying included task/host results in a task." - type: bool - default: yes - env: - - name: ANSIBLE_DISPLAY_INCLUDED_HOSTS - ini: - - key: display_included_hosts - section: defaults display_skipped_hosts: name: Show skipped hosts description: "Toggle to control displaying skipped task/host results in a task." @@ -51,6 +41,17 @@ class ModuleDocFragment(object): - key: display_failed_stderr section: defaults version_added: '2.7' + display_included_hosts: + name: Show included hosts + description: "Toggle to control displaying included task/host results in a task." + type: bool + default: yes + env: + - name: ANSIBLE_DISPLAY_INCLUDED_HOSTS + ini: + - key: display_included_hosts + section: defaults + version_added: '2.20' show_custom_stats: name: Show custom stats description: 'This adds the custom stats set via the set_stats plugin to the play recap.' diff --git a/test/integration/targets/callback_default/callback_default.out.hide_included.stderr b/test/integration/targets/callback_default/callback_default.out.hide_included.stderr new file mode 100644 index 00000000000..d3e07d472db --- /dev/null +++ b/test/integration/targets/callback_default/callback_default.out.hide_included.stderr @@ -0,0 +1,2 @@ ++ ansible-playbook -i inventory test.yml +++ set +x diff --git a/test/integration/targets/callback_default/callback_default.out.hide_included.stdout b/test/integration/targets/callback_default/callback_default.out.hide_included.stdout new file mode 100644 index 00000000000..37c5ff39246 --- /dev/null +++ b/test/integration/targets/callback_default/callback_default.out.hide_included.stdout @@ -0,0 +1,130 @@ + +PLAY [testhost] **************************************************************** + +TASK [Changed task] ************************************************************ +changed: [testhost] + +TASK [Ok task] ***************************************************************** +ok: [testhost] + +TASK [Failed task] ************************************************************* +[ERROR]: Task failed: Action failed: no reason +Origin: TEST_PATH/test.yml:16:7 + +14 changed_when: false +15 +16 - name: Failed task + ^ column 7 + +fatal: [testhost]: FAILED! => {"changed": false, "msg": "no reason"} +...ignoring + +TASK [Skipped task] ************************************************************ +skipping: [testhost] + +TASK [Task with var in name (foo bar)] ***************************************** +changed: [testhost] + +TASK [Loop task] *************************************************************** +changed: [testhost] => (item=foo-1) +changed: [testhost] => (item=foo-2) +changed: [testhost] => (item=foo-3) + +TASK [debug loop] ************************************************************** +changed: [testhost] => (item=debug-1) => { + "msg": "debug-1" +} +[ERROR]: Task failed: Action failed: debug-2 +Origin: TEST_PATH/test.yml:38:7 + +36 +37 # detect "changed" debug tasks being hidden with display_ok_tasks=false +38 - name: debug loop + ^ column 7 + +failed: [testhost] (item=debug-2) => { + "msg": "debug-2" +} +ok: [testhost] => (item=debug-3) => { + "msg": "debug-3" +} +skipping: [testhost] => (item=debug-4) +fatal: [testhost]: FAILED! => {"msg": "One or more items failed"} +...ignoring + +TASK [EXPECTED FAILURE Failed task to be rescued] ****************************** +[ERROR]: Task failed: Action failed: Failed as requested from task +Origin: TEST_PATH/test.yml:54:11 + +52 +53 - block: +54 - name: EXPECTED FAILURE Failed task to be rescued + ^ column 11 + +fatal: [testhost]: FAILED! => {"changed": false, "msg": "Failed as requested from task"} + +TASK [Rescue task] ************************************************************* +changed: [testhost] + +TASK [include_tasks] *********************************************************** + +TASK [debug] ******************************************************************* +ok: [testhost] => { + "item": 1 +} + +TASK [copy] ******************************************************************** +changed: [testhost] + +TASK [replace] ***************************************************************** +--- before: .../test_diff.txt ++++ after: .../test_diff.txt +@@ -1 +1 @@ +-foo +\ No newline at end of file ++bar +\ No newline at end of file + +changed: [testhost] + +TASK [replace] ***************************************************************** +ok: [testhost] + +TASK [debug] ******************************************************************* +skipping: [testhost] + +TASK [debug] ******************************************************************* +skipping: [testhost] + +TASK [debug] ******************************************************************* +skipping: [testhost] => (item=1) +skipping: [testhost] => (item=2) +skipping: [testhost] + +RUNNING HANDLER [Test handler 1] *********************************************** +changed: [testhost] + +RUNNING HANDLER [Test handler 2] *********************************************** +ok: [testhost] + +RUNNING HANDLER [Test handler 3] *********************************************** +changed: [testhost] + +PLAY [testhost] **************************************************************** + +TASK [First free task] ********************************************************* +changed: [testhost] + +TASK [Second free task] ******************************************************** +changed: [testhost] + +TASK [Include some tasks] ****************************************************** + +TASK [debug] ******************************************************************* +ok: [testhost] => { + "item": 1 +} + +PLAY RECAP ********************************************************************* +testhost : ok=19 changed=11 unreachable=0 failed=0 skipped=4 rescued=1 ignored=2 + diff --git a/test/integration/targets/callback_default/callback_default.out.hide_skipped_ok_included.stderr b/test/integration/targets/callback_default/callback_default.out.hide_skipped_ok_included.stderr new file mode 100644 index 00000000000..d3e07d472db --- /dev/null +++ b/test/integration/targets/callback_default/callback_default.out.hide_skipped_ok_included.stderr @@ -0,0 +1,2 @@ ++ ansible-playbook -i inventory test.yml +++ set +x diff --git a/test/integration/targets/callback_default/callback_default.out.hide_skipped_ok_included.stdout b/test/integration/targets/callback_default/callback_default.out.hide_skipped_ok_included.stdout new file mode 100644 index 00000000000..c87e0b9dbb2 --- /dev/null +++ b/test/integration/targets/callback_default/callback_default.out.hide_skipped_ok_included.stdout @@ -0,0 +1,93 @@ + +PLAY [testhost] **************************************************************** + +TASK [Changed task] ************************************************************ +changed: [testhost] + +TASK [Failed task] ************************************************************* +[ERROR]: Task failed: Action failed: no reason +Origin: TEST_PATH/test.yml:16:7 + +14 changed_when: false +15 +16 - name: Failed task + ^ column 7 + +fatal: [testhost]: FAILED! => {"changed": false, "msg": "no reason"} +...ignoring + +TASK [Task with var in name (foo bar)] ***************************************** +changed: [testhost] + +TASK [Loop task] *************************************************************** +changed: [testhost] => (item=foo-1) +changed: [testhost] => (item=foo-2) +changed: [testhost] => (item=foo-3) + +TASK [debug loop] ************************************************************** +changed: [testhost] => (item=debug-1) => { + "msg": "debug-1" +} +[ERROR]: Task failed: Action failed: debug-2 +Origin: TEST_PATH/test.yml:38:7 + +36 +37 # detect "changed" debug tasks being hidden with display_ok_tasks=false +38 - name: debug loop + ^ column 7 + +failed: [testhost] (item=debug-2) => { + "msg": "debug-2" +} +fatal: [testhost]: FAILED! => {"msg": "One or more items failed"} +...ignoring + +TASK [EXPECTED FAILURE Failed task to be rescued] ****************************** +[ERROR]: Task failed: Action failed: Failed as requested from task +Origin: TEST_PATH/test.yml:54:11 + +52 +53 - block: +54 - name: EXPECTED FAILURE Failed task to be rescued + ^ column 11 + +fatal: [testhost]: FAILED! => {"changed": false, "msg": "Failed as requested from task"} + +TASK [Rescue task] ************************************************************* +changed: [testhost] + +TASK [include_tasks] *********************************************************** + +TASK [copy] ******************************************************************** +changed: [testhost] + +TASK [replace] ***************************************************************** +--- before: .../test_diff.txt ++++ after: .../test_diff.txt +@@ -1 +1 @@ +-foo +\ No newline at end of file ++bar +\ No newline at end of file + +changed: [testhost] + +RUNNING HANDLER [Test handler 1] *********************************************** +changed: [testhost] + +RUNNING HANDLER [Test handler 3] *********************************************** +changed: [testhost] + +PLAY [testhost] **************************************************************** + +TASK [First free task] ********************************************************* +changed: [testhost] + +TASK [Second free task] ******************************************************** +changed: [testhost] + +TASK [Include some tasks] ****************************************************** + +PLAY RECAP ********************************************************************* +testhost : ok=19 changed=11 unreachable=0 failed=0 skipped=4 rescued=1 ignored=2 + diff --git a/test/integration/targets/callback_default/runme.sh b/test/integration/targets/callback_default/runme.sh index 473518b4af9..df281090971 100755 --- a/test/integration/targets/callback_default/runme.sh +++ b/test/integration/targets/callback_default/runme.sh @@ -170,6 +170,27 @@ export ANSIBLE_DISPLAY_OK_HOSTS=0 run_test hide_ok test.yml +# Hide include +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=1 +export ANSIBLE_DISPLAY_OK_HOSTS=1 +export ANSIBLE_DISPLAY_INCLUDED_HOSTS=0 + +run_test hide_included test.yml + +# Hide skipped/ok/included +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=0 +export ANSIBLE_DISPLAY_OK_HOSTS=0 +export ANSIBLE_DISPLAY_INCLUDED_HOSTS=0 + +run_test hide_skipped_ok_included test.yml + +# Hide ok +export ANSIBLE_DISPLAY_SKIPPED_HOSTS=1 +export ANSIBLE_DISPLAY_OK_HOSTS=0 +export ANSIBLE_DISPLAY_INCLUDED_HOSTS=1 + +run_test hide_ok test.yml + # Failed to stderr export ANSIBLE_DISPLAY_SKIPPED_HOSTS=1 export ANSIBLE_DISPLAY_OK_HOSTS=1