Skip to content

Commit b861850

Browse files
Feat: Add callback plugin print_task (#10087)
* Feat: Add callback plugin print_task Prints task snippet to job output. * Fix for failing tests * Fix some pep8 formatting issues * Updating DOCUMENTATION variable with version_added * Set correct CALLBACK_NAME and fix warning with gather_facts * Fix formatting again * Update plugins/callback/print_task.py Co-authored-by: Felix Fontein <[email protected]> * Update plugins/callback/print_task.py Co-authored-by: Felix Fontein <[email protected]> * Add entry to BOTMETA.yml * Use CSafeLoader and fallback to SafeLoader * Change output function to self._display.display() * Adding tests for community.general.print_task * Adding EXAMPLES * Apply suggestions from code review Co-authored-by: Felix Fontein <[email protected]> --------- Co-authored-by: Felix Fontein <[email protected]>
1 parent 3daa1de commit b861850

File tree

4 files changed

+204
-0
lines changed

4 files changed

+204
-0
lines changed

.github/BOTMETA.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ files:
7777
$callbacks/opentelemetry.py:
7878
keywords: opentelemetry observability
7979
maintainers: v1v
80+
$callbacks/print_task.py:
81+
maintainers: demonpig
8082
$callbacks/say.py:
8183
keywords: brew cask darwin homebrew macosx macports osx
8284
labels: macos say

plugins/callback/print_task.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright (c) 2025, Max Mitschke <[email protected]>
3+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
4+
# SPDX-License-Identifier: GPL-3.0-or-later
5+
6+
from __future__ import (absolute_import, division, print_function)
7+
__metaclass__ = type
8+
9+
DOCUMENTATION = r'''
10+
name: print_task
11+
type: aggregate
12+
short_description: Prints playbook task snippet to job output
13+
description:
14+
- This plugin prints the currently executing playbook task to the job output.
15+
version_added: 10.7.0
16+
requirements:
17+
- enable in configuration
18+
'''
19+
20+
EXAMPLES = r'''
21+
ansible.cfg: >
22+
# Enable plugin
23+
[defaults]
24+
callbacks_enabled=community.general.print_task
25+
'''
26+
27+
from yaml import load, dump
28+
29+
try:
30+
from yaml import CSafeDumper as SafeDumper
31+
from yaml import CSafeLoader as SafeLoader
32+
except ImportError:
33+
from yaml import SafeDumper, SafeLoader
34+
35+
from ansible.plugins.callback import CallbackBase
36+
37+
38+
class CallbackModule(CallbackBase):
39+
"""
40+
This callback module tells you how long your plays ran for.
41+
"""
42+
CALLBACK_VERSION = 2.0
43+
CALLBACK_TYPE = 'aggregate'
44+
CALLBACK_NAME = 'community.general.print_task'
45+
46+
CALLBACK_NEEDS_ENABLED = True
47+
48+
def __init__(self):
49+
super(CallbackModule, self).__init__()
50+
self._printed_message = False
51+
52+
def _print_task(self, task):
53+
if hasattr(task, '_ds'):
54+
task_snippet = load(str([task._ds.copy()]), Loader=SafeLoader)
55+
task_yaml = dump(task_snippet, sort_keys=False, Dumper=SafeDumper)
56+
self._display.display(f"\n{task_yaml}\n")
57+
self._printed_message = True
58+
59+
def v2_playbook_on_task_start(self, task, is_conditional):
60+
self._printed_message = False
61+
62+
def v2_runner_on_start(self, host, task):
63+
if not self._printed_message:
64+
self._print_task(task)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (c) Ansible Project
2+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
3+
# SPDX-License-Identifier: GPL-3.0-or-later
4+
5+
azp/posix/3
6+
needs/target/callback
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
---
2+
####################################################################
3+
# WARNING: These are designed specifically for Ansible tests #
4+
# and should not be used as examples of how to write Ansible roles #
5+
####################################################################
6+
7+
# Copyright (c) Ansible Project
8+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
9+
# SPDX-License-Identifier: GPL-3.0-or-later
10+
11+
- name: Run tests
12+
include_role:
13+
name: callback
14+
vars:
15+
tests:
16+
- name: community.general.print_task is not enabled
17+
environment:
18+
ANSIBLE_NOCOLOR: 'true'
19+
ANSIBLE_FORCE_COLOR: 'false'
20+
playbook: |
21+
- hosts: testhost
22+
gather_facts: false
23+
tasks:
24+
- name: Sample task
25+
debug:
26+
msg: This is a test
27+
expected_output: [
28+
"",
29+
"PLAY [testhost] ****************************************************************",
30+
"",
31+
"TASK [Sample task] *************************************************************",
32+
"ok: [testhost] => {",
33+
" \"msg\": \"This is a test\"",
34+
"}",
35+
"",
36+
"PLAY RECAP *********************************************************************",
37+
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
38+
]
39+
40+
- name: community.general.print_task is enabled
41+
environment:
42+
ANSIBLE_NOCOLOR: 'true'
43+
ANSIBLE_FORCE_COLOR: 'false'
44+
ANSIBLE_CALLBACKS_ENABLED: 'community.general.print_task'
45+
playbook: |
46+
- hosts: testhost
47+
gather_facts: false
48+
tasks:
49+
- name: Sample task
50+
debug:
51+
msg: This is a test
52+
expected_output: [
53+
"",
54+
"PLAY [testhost] ****************************************************************",
55+
"",
56+
"TASK [Sample task] *************************************************************",
57+
"",
58+
"- name: Sample task",
59+
" debug:",
60+
" msg: This is a test",
61+
"",
62+
"ok: [testhost] => {",
63+
" \"msg\": \"This is a test\"",
64+
"}",
65+
"",
66+
"PLAY RECAP *********************************************************************",
67+
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
68+
]
69+
70+
- name: Print with msg parameter on the same line
71+
environment:
72+
ANSIBLE_NOCOLOR: 'true'
73+
ANSIBLE_FORCE_COLOR: 'false'
74+
ANSIBLE_CALLBACKS_ENABLED: 'community.general.print_task'
75+
playbook: |
76+
- hosts: testhost
77+
gather_facts: false
78+
tasks:
79+
- name: Sample task
80+
debug: msg="This is a test"
81+
expected_output: [
82+
"",
83+
"PLAY [testhost] ****************************************************************",
84+
"",
85+
"TASK [Sample task] *************************************************************",
86+
"",
87+
"- name: Sample task",
88+
" debug: msg=\"This is a test\"",
89+
"",
90+
"ok: [testhost] => {",
91+
" \"msg\": \"This is a test\"",
92+
"}",
93+
"",
94+
"PLAY RECAP *********************************************************************",
95+
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
96+
]
97+
98+
- name: Task with additional parameters
99+
environment:
100+
ANSIBLE_NOCOLOR: 'true'
101+
ANSIBLE_FORCE_COLOR: 'false'
102+
ANSIBLE_CALLBACKS_ENABLED: 'community.general.print_task'
103+
playbook: |
104+
- hosts: testhost
105+
gather_facts: false
106+
tasks:
107+
- name: Sample task
108+
when: True
109+
vars:
110+
test_var: "Hello World"
111+
debug:
112+
var: test_var
113+
expected_output: [
114+
"",
115+
"PLAY [testhost] ****************************************************************",
116+
"",
117+
"TASK [Sample task] *************************************************************",
118+
"",
119+
"- name: Sample task",
120+
" when: true",
121+
" vars:",
122+
" test_var: Hello World",
123+
" debug:",
124+
" var: test_var",
125+
"",
126+
"ok: [testhost] => {",
127+
" \"test_var\": \"Hello World\"",
128+
"}",
129+
"",
130+
"PLAY RECAP *********************************************************************",
131+
"testhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 "
132+
]

0 commit comments

Comments
 (0)