How to specify a callback when calling ansible via its API?
I have a callback plugin database_write.py
for ansible 2.0.0.2 that logs into a database when this is run:
ansible-playbook -i inventory.txt playbook.yml # callback is fired ok
This works ok because in my $PWD i have ansible.cfg
with this line:
callback_plugins = ./src/callback
Now I'm trying to make ansible to execute my playbook and my callback using the python API. I've basically copied what the ansible-playbook cli tool does
# based on https://github.com/ansible/ansible/blob/v2.0.0.2-1/lib/ansible/cli/playbook.py
pbex = PlaybookExecutor(playbooks=['../playbook.yml'],
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=passwords)
results = pbex.run()
This executes the playbook fine, but the callback is not triggered.
I guess when using the python API, my ansible.cfg
file is not being taken into account?
how do I specify my callback plugin to the PlaybookExecutor?
(most of the documentation I've found works for ansible versions < 2.0)
thank you in advance!
2.0 API is very raw and generally not suited for end-user. It's likely to be changed in the future also. See this discussion on mailing list where I posted similar question and proposed my own answer that apparently was correct: you can assign your callbacks to TaskQueueManager instance of the executor (PlaybookExecutor._tqm._stdout_callback).
pbex = PlaybookExecutor(playbooks=playbooks, inventory=inventory,
variable_manager=variable_manager,
loader=loader, options=options,
passwords=passwords)
cb = ResultAccumulator()
pbex._tqm._stdout_callback = cb
results = pbex.run()
(ResultAccumulator is callback plugin class from here. It should be derived from ansible.plugins.callback.CallbackBase.
Ansible API docs are scarce. PlaybookExecutor does not accept any callback arguments.
However, you can create a custom callback from CallbackBase.
Here's an example which returns a list of all the TaskResults:
class SampleCallback(CallbackBase):
"""Sample callback"""
def __init__(self):
super(SampleCallback, self).__init__()
# store all results
self.results = []
def v2_runner_on_ok(self, result, **kwargs):
"""Save result instead of printing it"""
self.results.append(result)
pbe = PlaybookExecutor(
playbooks=playbooks,
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=passwords
)
callback = SampleCallback()
pbe._tqm._stdout_callback = callback
return_code = pbe.run()
results = callback.results
With my setup (ansible 2.0.0.2 RHEL6 python 2.6.6) I needed to have it set in /etc/ansible/ansible.cfg
and did it thusly:
callback_plugins = /usr/lib/python2.6/site-packages/ansible/plugins/callback
bin_ansible_callbacks = True
callback_whitelist = profile_tasks