YAML stdout callback plugin doesn't output stdout from command module
SUMMARY
Issue migrated from https://github.com/ansible/ansible/issues/39122
ISSUE TYPE
- Bug Report
(Though maybe this is a feature idea?)
COMPONENT NAME
plugins/callback/yaml.py
ANSIBLE VERSION
ansible 2.5.1
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/Users/jgeerling/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python2.7/site-packages/ansible
executable location = /usr/local/bin/ansible
python version = 2.7.13 (default, Jul 18 2017, 09:17:00) [GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)]
CONFIGURATION
17:27:10 ~/Dropbox/VMs/infrastructure/solr/solr $ ansible-config dump --only-changed
ANSIBLE_NOCOWS(/etc/ansible/ansible.cfg) = True
ANSIBLE_PIPELINING(/etc/ansible/ansible.cfg) = True
ANSIBLE_SSH_CONTROL_PATH(/etc/ansible/ansible.cfg) = /tmp/ansible-ssh-%%h-%%p-%%r
DEFAULT_FORKS(/etc/ansible/ansible.cfg) = 20
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = [u'/etc/ansible/hosts']
DEFAULT_LOAD_CALLBACK_PLUGINS(/etc/ansible/ansible.cfg) = True
DEFAULT_ROLES_PATH(/etc/ansible/ansible.cfg) = [u'/Users/jgeerling/Dropbox/VMs/roles']
DEFAULT_STDOUT_CALLBACK(/etc/ansible/ansible.cfg) = yaml
RETRY_FILES_ENABLED(/etc/ansible/ansible.cfg) = False
OS / ENVIRONMENT
N/A
SUMMARY
When using the Ansible default configuration (default stdout callback plugin), and running command module commands either via playbook or ad-hoc commands, command output directed at stdout is printed to the console on the machine running Ansible, e.g.:
$ ansible myserver -a "echo 'testing'"
myserver | SUCCESS | rc=0 >>
testing
When using the yaml callback plugin, stdout output is not printed to the console on the machine running Ansible, e.g.:
$ ansible myserver -a "echo 'testing'"
PLAY [Ansible Ad-Hoc] **************************************************************************************************
TASK [command] *********************************************************************************************************
changed: [myserver]
PLAY RECAP *************************************************************************************************************
myserver : ok=1 changed=1 unreachable=0 failed=0
STEPS TO REPRODUCE
See summary above.
EXPECTED RESULTS
I expected the yaml callback plugin to behave similar to the default callback plugin, printing stdout from command module commands to the command line while running playbooks or ad-hoc tasks.
ACTUAL RESULTS
stdout from command module commands is eaten up and never displayed on the CLI. Note that the debug module does print msgs and vars to screen.
Files identified in the description:
If these files are inaccurate, please update the component name section of the description or use the !component bot command.
The default callback does not print the command stdout. The output you see in the above ad-hoc command comes from the minimal callback (https://github.com/ansible/ansible/blob/devel/lib/ansible/cli/adhoc.py#L143).
For anyone who's come here from the prior issue, I fixed this by forcing a reinstallation of the collections from galaxy.
ansible-galaxy install --force -r requirements.yml
Perhaps there was some corruption on my local, seeing as this started happening after I installed a new role and I think it caused a redownload of a collection.
This happens everywhere for us including on new installs, so it is not an issue of reinstallation for us.
Well, there's no reason why reinstalling should ever "fix" this, since this isn't a bug and nobody implemented this feature. If someone wants to improve / change this, take a look at @sivel's suggestions here: https://github.com/ansible/ansible/issues/39122#issuecomment-383642487
Also, changing the behavior of the YAML callback is not exactly trivial, since this is a breaking change. Having a detection for ad-hoc mode and a new configuration is probably the best solution. (No idea how to detect ad-hoc mode though...)
Can detect if in adhoc by using the playbook name
def v2_playbook_on_start(self, playbook): playbook_name = os.path.basename(playbook._file_name).split('.yml')[0]
playbook_name will be "__adhoc_playbook__" when adhoc is run.
What changes would be needed to the yaml plugin to change this?
Seems like this doesn't work for any ad-hoc command. I tried with other modules as well like setup and shell all are not providing the output in YAML format
Not sure if this is related or not, but I am experiencing same problem with setup module:
~$ ansible --version
ansible 2.10.6
config file = None
configured module search path = ['~/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = ~/.local/lib/python3.8/site-packages/ansible
executable location = ~/.local/bin/ansible
python version = 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0]
~$ ANSIBLE_LOAD_CALLBACK_PLUGINS=yes ANSIBLE_STDOUT_CALLBACK=community.general.yaml ansible -m setup localhost
[WARNING]: No inventory was parsed, only implicit localhost is available
PLAY [Ansible Ad-Hoc] **************************************************************************************************************************************************
TASK [setup] ***********************************************************************************************************************************************************
ok: [localhost]
PLAY RECAP *************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
~$ ANSIBLE_LOAD_CALLBACK_PLUGINS=yes ANSIBLE_STDOUT_CALLBACK=minimal ansible -m setup localhost
[WARNING]: No inventory was parsed, only implicit localhost is available
localhost | SUCCESS => {
"ansible_facts": {
....
That's pretty much expected, since almost no callback plugin (except minimal) automatically dumps all task results if you don't provide -v. Otherwise the normal playbook output would be severly cluttered :-)
You'll see what I mean if you use the minimal callback for a regular playbook. It will be a lot less "minimal" than most other callbacks.
(...) almost no callback plugin (except minimal) automatically dumps all task results if you don't provide -v.
That's true for a regular playbook, but it's not true in case of ad-hoc tasks. For example default:
$ ANSIBLE_LOAD_CALLBACK_PLUGINS=yes ANSIBLE_STDOUT_CALLBACK=default ansible -m setup localhost | grep -A10 "ansible_date_time"
[WARNING]: No inventory was parsed, only implicit localhost is available
"ansible_date_time": {
"date": "2021-04-15",
"day": "15",
"epoch": "1618484703",
"hour": "12",
"iso8601": "2021-04-15T11:05:03Z",
"iso8601_basic": "20210415T120503978122",
"iso8601_basic_short": "20210415T120503",
"iso8601_micro": "2021-04-15T11:05:03.978122Z",
"minute": "05",
"month": "04",
$ ansible --version | head -n1
ansible 2.10.7
@weakcamel please note that ansible seems to always replace the default plugin by minimal. See https://github.com/ansible/ansible/blob/devel/lib/ansible/cli/adhoc.py#L135-L143 (I'm not sure whether self.callback can actually be something other than None.)