Implement async callbacks (#74953)

* add changelog and output from default callback
* add test
* add comments about TE task
This commit is contained in:
David Shrewsbury 2021-06-22 12:19:32 -04:00 committed by GitHub
parent ca6123e0ee
commit 703cb79442
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 4 deletions

View file

@ -0,0 +1,4 @@
minor_changes:
- callback API - implemented ``v2_runner_on_async_ok`` and ``v2_runner_on_async_failed`` callbacks
(https://github.com/ansible/ansible/pull/74953).
- default callback plugin - displays output for ``v2_runner_on_async_ok`` and ``v2_runner_on_async_failed`` callbacks.

View file

@ -617,6 +617,20 @@ class TaskExecutor:
if self._task.async_val > 0:
if self._task.poll > 0 and not result.get('skipped') and not result.get('failed'):
result = self._poll_async_result(result=result, templar=templar, task_vars=vars_copy)
if result.get('failed'):
self._final_q.send_callback(
'v2_runner_on_async_failed',
TaskResult(self._host.name,
self._task, # We send the full task here, because the controller knows nothing about it, the TE created it
result,
task_fields=self._task.dump_attrs()))
else:
self._final_q.send_callback(
'v2_runner_on_async_ok',
TaskResult(self._host.name,
self._task, # We send the full task here, because the controller knows nothing about it, the TE created it
result,
task_fields=self._task.dump_attrs()))
# ensure no log is preserved
result["_ansible_no_log"] = self._play_context.no_log
@ -831,7 +845,7 @@ class TaskExecutor:
if int(async_result.get('finished', 0)) != 1:
if async_result.get('_ansible_parsed'):
return dict(failed=True, msg="async task did not complete within the requested time - %ss" % self._task.async_val)
return dict(failed=True, msg="async task did not complete within the requested time - %ss" % self._task.async_val, async_result=async_result)
else:
return dict(failed=True, msg="async task produced unparseable results", async_result=async_result)
else:

View file

@ -364,7 +364,6 @@ class CallbackBase(AnsiblePlugin):
host = result._host.get_name()
self.runner_on_unreachable(host, result._result)
# FIXME: not called
def v2_runner_on_async_poll(self, result):
host = result._host.get_name()
jid = result._result.get('ansible_job_id')
@ -372,16 +371,18 @@ class CallbackBase(AnsiblePlugin):
clock = 0
self.runner_on_async_poll(host, result._result, jid, clock)
# FIXME: not called
def v2_runner_on_async_ok(self, result):
host = result._host.get_name()
jid = result._result.get('ansible_job_id')
self.runner_on_async_ok(host, result._result, jid)
# FIXME: not called
def v2_runner_on_async_failed(self, result):
host = result._host.get_name()
# Attempt to get the async job ID. If the job does not finish before the
# async timeout value, the ID may be within the unparsed 'async_result' dict.
jid = result._result.get('ansible_job_id')
if not jid and 'async_result' in result._result:
jid = result._result['async_result'].get('ansible_job_id')
self.runner_on_async_failed(host, result._result, jid)
def v2_playbook_on_start(self, playbook):

View file

@ -413,6 +413,21 @@ class CallbackModule(CallbackBase):
color=C.COLOR_DEBUG
)
def v2_runner_on_async_ok(self, result):
host = result._host.get_name()
jid = result._result.get('ansible_job_id')
self._display.display("ASYNC OK on %s: jid=%s" % (host, jid), color=C.COLOR_DEBUG)
def v2_runner_on_async_failed(self, result):
host = result._host.get_name()
# Attempt to get the async job ID. If the job does not finish before the
# async timeout value, the ID may be within the unparsed 'async_result' dict.
jid = result._result.get('ansible_job_id')
if not jid and 'async_result' in result._result:
jid = result._result['async_result'].get('ansible_job_id')
self._display.display("ASYNC FAILED on %s: jid=%s" % (host, jid), color=C.COLOR_DEBUG)
def v2_playbook_on_notify(self, handler, host):
if self._display.verbosity > 1:
self._display.display("NOTIFIED HANDLER %s for %s" % (handler.get_name(), host), color=C.COLOR_VERBOSE, screen_only=True)

View file

@ -125,6 +125,13 @@ export ANSIBLE_CHECK_MODE_MARKERS=0
run_test default
# Check for async output
# NOTE: regex to match 1 or more digits works for both BSD and GNU grep
ansible-playbook -i inventory test_async.yml 2>&1 | tee async_test.out
grep "ASYNC OK .* jid=[0-9]\{1,\}" async_test.out
grep "ASYNC FAILED .* jid=[0-9]\{1,\}" async_test.out
rm -f async_test.out
# Hide skipped
export ANSIBLE_DISPLAY_SKIPPED_HOSTS=0

View file

@ -0,0 +1,14 @@
---
- hosts: testhost
gather_facts: no
tasks:
- name: test success async output
command: sleep 1
async: 10
poll: 1
- name: test failure async output
command: sleep 10
async: 1
poll: 1
ignore_errors: yes