With the deprecation of the --one-line parameter and its associated callback plugin, I’m working on simplifying the use of a suggested workaround. First, a little background.
- Everything “interesting” in Ansible is implemented as a plugin.
- Callback plugins control the presentation of the console output from various Ansible commands, particularly
ansibleandansible-playbook. - The
onelinecallback puts each task’s output for each target host on a single line (so one line per host per task). For some cases, especially ad hoc commands with short task output from many hosts, this can often be much simpler for humans to read. - The
oneline.pycallback plugin is deprecated and will be removed from ansible-core version 2.23, at the same time the-o/--one-lineparameters will be removed from core commands. - The suggestion, for those who find
--one-lineoccasionally useful, is to use a private copy of theoneline.pycallback plugin, with the caveat that you’ll own any maintenance issues going forward.
That’s great, but using a one-off callback requires changing some config, either in ansible.cfg or environment variables. The ideal would be something nearly as simple as adding --one-line to your ad hoc command parameters. That’s possible, but it requires a bit of one-time setup.
First, you’ll need to create a place for your private copy of the oneline.py callback plugin. This should be in your DEFAULT_CALLBACK_PLUGIN_PATH; see ansible-config list to be sure.
$ mkdir -p ~/.ansible/plugins/callback
Next, copy Ansible’s current oneline.py callback plugin to the private plugins/callback directory you just created. Give it a slightly different name — here I’m using “xoneline.py” — to avoid plugin name collisions before the final removal from ansible-core 2.23.
$ cp "$(ansible --version | grep -Po '(?<=ansible python module location = ).*')"/plugins/callback/oneline.py ~/.ansible/plugins/callback/xoneline.py
Then edit ~/.ansible/plugins/callback/xoneline.py to comment out the lines pertaining to the pending deprecation of the oneline plugin. Don’t be shy about editing that file. You own it now. In ansible-core 2.20, that will look something like this:
# self._display.deprecated( # pylint: disable=ansible-deprecated-unnecessary-collection-name
# msg='The xoneline callback plugin is deprecated.',
# version='2.23',
# deprecator=_deprecator.ANSIBLE_CORE_DEPRECATOR, # entire plugin being removed; this improves the messaging
# )
Finally, create an alias that sets a few environment variables as a prefix to your ad hoc ansible commands. You’ll want to update your “dotfiles”, wherever you set your personal shell aliases, to have it defined on subsequent shell sessions.
N.B. - The trailing space on this alias is important!
$ alias xoneline='ANSIBLE_CALLBACKS_ENABLED=xoneline ANSIBLE_LOAD_CALLBACK_PLUGINS=true ANSIBLE_STDOUT_CALLBACK=xoneline '
Notice this alias doesn’t execute any commands. You invoke the alias as a prefix to your ad hoc ansible commands, so that these two ad hoc commands are essentially equivalent (with spaces inserted to facilitate comparison):
$ ansible my_hosts -a 'uname -r' --one-line
$ xoneline ansible my_hosts -a 'uname -r'
Only the latter one (may) work with ansible-core 2.23 and beyond.
The trailing space on that alias causes the word after the alias to also be subject to alias expansion. (See help alias in bash.) This can be useful if you, like me, have other aliases for specific ansible invocations. For example, I have this alias:
alias ansible-md='ansible -i /path/to/myinventory/hosts -u ansible-mydomain --ssh-extra-args="-i=/path/to/id_rsa_ansible_mydomain"'
so that
$ xoneline ansible-md …
expands to a lot more than I want to type. Without the trailing space in the xoneline alias definition, my ansible-md alias would not expand in that command.