-
Notifications
You must be signed in to change notification settings - Fork 346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Respect user-specified stdout callback #387
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,3 +18,5 @@ | |
.coverage | ||
*,cover | ||
.venv | ||
|
||
__pycache__/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,18 +21,42 @@ | |
import collections | ||
import contextlib | ||
import sys | ||
import os | ||
import importlib | ||
import uuid | ||
from copy import copy | ||
|
||
# Ansible | ||
from ansible import constants as C | ||
from ansible.plugins.callback import CallbackBase | ||
from ansible.plugins.callback.default import CallbackModule as DefaultCallbackModule | ||
|
||
# AWX Display Callback | ||
from .events import event_context | ||
from .minimal import CallbackModule as MinimalCallbackModule | ||
|
||
|
||
BASE_DOCUMENTATION = ''' | ||
callback: %s | ||
short_description: Playbook event dispatcher for ansible-runner | ||
version_added: "2.0" | ||
description: | ||
- This callback is necessary for ansible-runner to work | ||
type: stdout | ||
extends_documentation_fragment: | ||
- default_callback | ||
requirements: | ||
- Set as stdout in config | ||
''' | ||
|
||
|
||
if 'RUNNER_STDOUT_CALLBACK_PROXY' in os.environ: | ||
from ansible.plugins.loader import callback_loader | ||
DefaultCallbackModule = callback_loader.get(os.environ['RUNNER_STDOUT_CALLBACK_PROXY']).__class__ | ||
DefaultCallbackModule.PROXY_DOCUMENTATION = importlib.import_module(DefaultCallbackModule.__module__).DOCUMENTATION | ||
else: | ||
from ansible.plugins.callback.default import CallbackModule as DefaultCallbackModule | ||
|
||
|
||
CENSORED = "the output has been hidden due to the fact that 'no_log: true' was specified for this result" # noqa | ||
|
||
|
||
|
@@ -60,6 +84,12 @@ class BaseCallbackModule(CallbackBase): | |
'playbook_on_no_hosts_remaining', | ||
] | ||
|
||
@classmethod | ||
def get_documentation(cls): | ||
if hasattr(cls, 'PROXY_DOCUMENTATION'): | ||
return cls.PROXY_DOCUMENTATION | ||
return BASE_DOCUMENTATION % cls.CALLBACK_NAME | ||
|
||
def __init__(self): | ||
super(BaseCallbackModule, self).__init__() | ||
self.task_uuids = set() | ||
|
@@ -271,7 +301,7 @@ def v2_playbook_on_task_start(self, task, is_conditional): | |
uuid=task_uuid, | ||
) | ||
with self.capture_event_data('playbook_on_task_start', **event_data): | ||
super(BaseCallbackModule, self).v2_playbook_on_task_start(task, is_conditional) | ||
super(BaseCallbackModule, self).v2_playbook_on_task_start(task, is_conditional=is_conditional) | ||
|
||
def v2_playbook_on_cleanup_task_start(self, task): | ||
# NOTE: Not used by Ansible 2.x. | ||
|
@@ -374,7 +404,7 @@ def v2_runner_on_failed(self, result, ignore_errors=False): | |
event_loop=self._get_event_loop(result._task), | ||
) | ||
with self.capture_event_data('runner_on_failed', **event_data): | ||
super(BaseCallbackModule, self).v2_runner_on_failed(result, ignore_errors) | ||
super(BaseCallbackModule, self).v2_runner_on_failed(result, ignore_errors=ignore_errors) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in Ansible core, these are kwargs, not args. Thus the change. |
||
|
||
def v2_runner_on_skipped(self, result): | ||
event_data = dict( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -195,6 +195,9 @@ def prepare(self): | |
if python_path and not python_path.endswith(':'): | ||
python_path += ':' | ||
self.env['ANSIBLE_CALLBACK_PLUGINS'] = ':'.join(filter(None,(self.env.get('ANSIBLE_CALLBACK_PLUGINS'), callback_dir))) | ||
# If stdout callback specified, pass info for this stdout callback plugin to subclass it | ||
if 'ANSIBLE_STDOUT_CALLBACK' in self.env and self.env['ANSIBLE_STDOUT_CALLBACK'] not in ('awx_display', 'minimal'): | ||
self.env['RUNNER_STDOUT_CALLBACK_PROXY'] = self.env['ANSIBLE_STDOUT_CALLBACK'] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Needed this name |
||
if 'AD_HOC_COMMAND_ID' in self.env: | ||
self.env['ANSIBLE_STDOUT_CALLBACK'] = 'minimal' | ||
else: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
### Ansible Runner Test Data Directories | ||
|
||
Subfolders in this directory should contain test cases in the form of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
runner input directories. | ||
|
||
If running from the top level of the ansible-runner directory, several | ||
of these cases should be something which can be manually tested by the CLI | ||
invocation. | ||
|
||
``` | ||
ansible-runner run test/data/misc/ -p use_role.yml | ||
``` | ||
|
||
The `misc` case is intended to hold playbooks and roles that do not require | ||
any environment changes that would interfere with other playbooks. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
- hosts: all | ||
gather_facts: false | ||
connection: local | ||
tasks: | ||
- debug: msg="hello" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
--- | ||
ANSIBLE_DISPLAY_SKIPPED_HOSTS: false |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
6_rescued | ||
7_unreachable | ||
|
||
[consolidated] | ||
1_ok | ||
2_skipped | ||
3_changed | ||
4_failed | ||
5_ignored |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
- hosts: consolidated | ||
gather_facts: false | ||
connection: local | ||
name: Use debug task to produce different status for several hosts | ||
tasks: | ||
- name: This task gives ok/changed/skipped/failed/ignored depending on host | ||
debug: | ||
msg: "Playing {{ ansible_host }}" | ||
when: "'_skipped' not in ansible_host" | ||
changed_when: "'_changed' in ansible_host" | ||
failed_when: "('_failed' in ansible_host) or ('_ignored' in ansible_host)" | ||
ignore_errors: "{{'_ignored' in ansible_host}}" | ||
|
||
- hosts: 6_rescued | ||
gather_facts: false | ||
connection: local | ||
name: Target the rescue host in separate play in order to fail and rescue | ||
tasks: | ||
|
||
- name: Fail so that rescue task will be activated | ||
block: | ||
- fail: | ||
msg: "HALP!!!" | ||
rescue: | ||
- name: This is the rescue task | ||
debug: msg="ε-(´・`) フ" | ||
|
||
- hosts: 7_unreachable | ||
gather_facts: false | ||
name: Target unreachable hosts in order to get unreachable status | ||
tasks: | ||
|
||
- name: Reach out to the unreachable host | ||
ping: | ||
vars: | ||
ansible_host: 'invalid.invalid' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Somewhere else I'm going with this - I want to test @wenottingham's #405 with it, because I'm worried about our ability (my ability) to correctly identify all task-ending callback types. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
--- | ||
ANSIBLE_STDOUT_CALLBACK: selective |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
6_rescued | ||
7_unreachable | ||
|
||
[consolidated] | ||
1_ok | ||
2_skipped | ||
3_changed | ||
4_failed | ||
5_ignored |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
- hosts: consolidated | ||
gather_facts: false | ||
connection: local | ||
name: Use debug task to produce different status for several hosts | ||
tasks: | ||
- name: This task gives ok/changed/skipped/failed/ignored depending on host | ||
debug: | ||
msg: "Playing {{ ansible_host }}" | ||
when: "'_skipped' not in ansible_host" | ||
changed_when: "'_changed' in ansible_host" | ||
failed_when: "('_failed' in ansible_host) or ('_ignored' in ansible_host)" | ||
ignore_errors: "{{'_ignored' in ansible_host}}" | ||
|
||
- hosts: 6_rescued | ||
gather_facts: false | ||
connection: local | ||
name: Target the rescue host in separate play in order to fail and rescue | ||
tasks: | ||
|
||
- name: Fail so that rescue task will be activated | ||
block: | ||
- fail: | ||
msg: "HALP!!!" | ||
rescue: | ||
- name: This is the rescue task | ||
debug: msg="ε-(´・`) フ" | ||
|
||
- hosts: 7_unreachable | ||
gather_facts: false | ||
name: Target unreachable hosts in order to get unreachable status | ||
tasks: | ||
|
||
- name: Reach out to the unreachable host | ||
ping: | ||
vars: | ||
ansible_host: 'invalid.invalid' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I don't like the duplication either, but runner right now does not like to combine programatic and file inputs, so that's why it ended up like this. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
ANSIBLE_STDOUT_CALLBACK: selective | ||
# Setting the nocolor option should control whether the output is colorized | ||
ANSIBLE_NOCOLOR: true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
6_rescued | ||
7_unreachable | ||
|
||
[consolidated] | ||
1_ok | ||
2_skipped | ||
3_changed | ||
4_failed | ||
5_ignored |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
- hosts: consolidated | ||
gather_facts: false | ||
connection: local | ||
name: Use debug task to produce different status for several hosts | ||
tasks: | ||
- name: This task gives ok/changed/skipped/failed/ignored depending on host | ||
debug: | ||
msg: "Playing {{ ansible_host }}" | ||
when: "'_skipped' not in ansible_host" | ||
changed_when: "'_changed' in ansible_host" | ||
failed_when: "('_failed' in ansible_host) or ('_ignored' in ansible_host)" | ||
ignore_errors: "{{'_ignored' in ansible_host}}" | ||
|
||
- hosts: 6_rescued | ||
gather_facts: false | ||
connection: local | ||
name: Target the rescue host in separate play in order to fail and rescue | ||
tasks: | ||
|
||
- name: Fail so that rescue task will be activated | ||
block: | ||
- fail: | ||
msg: "HALP!!!" | ||
rescue: | ||
- name: This is the rescue task | ||
debug: msg="ε-(´・`) フ" | ||
|
||
- hosts: 7_unreachable | ||
gather_facts: false | ||
name: Target unreachable hosts in order to get unreachable status | ||
tasks: | ||
|
||
- name: Reach out to the unreachable host | ||
ping: | ||
vars: | ||
ansible_host: 'invalid.invalid' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[all] | ||
localhost ansible_connection=local |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My ears are open if someone wants to suggest a more beautiful way of creating the DOCUMENTATION string in this specific logic.
The "perfect" solution would be for awx_display and minimal to both extend from the same doc_fragment (which would still need to be overwritten by the user callback, if present). But that won't be available until we are fully in the world of collections. So to me, the general thing being doing here seems fully justifiable.