From fde206499d1a310480e35b570a02a47354af8bf5 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Tue, 26 Mar 2024 17:06:29 -0400 Subject: [PATCH] async support check mode (#82901) Allow async tasks to run in check mode Add check_mode support to async_status Add tests, also for 'hidden' async mode in gather_facts/parallel --- .../fragments/async_status_check_mode.yml | 3 +++ lib/ansible/modules/async_status.py | 18 ++++++++----- lib/ansible/plugins/action/__init__.py | 2 -- test/integration/targets/async/tasks/main.yml | 27 +++++++++++++++++++ 4 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 changelogs/fragments/async_status_check_mode.yml diff --git a/changelogs/fragments/async_status_check_mode.yml b/changelogs/fragments/async_status_check_mode.yml new file mode 100644 index 00000000000..4802cb8fb8a --- /dev/null +++ b/changelogs/fragments/async_status_check_mode.yml @@ -0,0 +1,3 @@ +minor_changes: + - async tasks can now also support check mode at the same time. + - async_status now supports check mode. diff --git a/lib/ansible/modules/async_status.py b/lib/ansible/modules/async_status.py index 9bcc3ef1255..e07143adb55 100644 --- a/lib/ansible/modules/async_status.py +++ b/lib/ansible/modules/async_status.py @@ -36,7 +36,8 @@ attributes: async: support: none check_mode: - support: none + support: full + version_added: '2.17' diff_mode: support: none bypass_host_loop: @@ -116,12 +117,15 @@ from ansible.module_utils.common.text.converters import to_native def main(): - module = AnsibleModule(argument_spec=dict( - jid=dict(type='str', required=True), - mode=dict(type='str', default='status', choices=['cleanup', 'status']), - # passed in from the async_status action plugin - _async_dir=dict(type='path', required=True), - )) + module = AnsibleModule( + argument_spec=dict( + jid=dict(type="str", required=True), + mode=dict(type="str", default="status", choices=["cleanup", "status"]), + # passed in from the async_status action plugin + _async_dir=dict(type="path", required=True), + ), + supports_check_mode=True, + ) mode = module.params['mode'] jid = module.params['jid'] diff --git a/lib/ansible/plugins/action/__init__.py b/lib/ansible/plugins/action/__init__.py index 5517d10a638..7ebfd13e4c7 100644 --- a/lib/ansible/plugins/action/__init__.py +++ b/lib/ansible/plugins/action/__init__.py @@ -118,8 +118,6 @@ class ActionBase(ABC): raise AnsibleActionFail('This action (%s) does not support async.' % self._task.action) elif self._task.check_mode and not self._supports_check_mode: raise AnsibleActionSkip('This action (%s) does not support check mode.' % self._task.action) - elif self._task.async_val and self._task.check_mode: - raise AnsibleActionFail('"check mode" and "async" cannot be used on same task.') # Error if invalid argument is passed if self._VALID_ARGS: diff --git a/test/integration/targets/async/tasks/main.yml b/test/integration/targets/async/tasks/main.yml index 491be966a04..65182070553 100644 --- a/test/integration/targets/async/tasks/main.yml +++ b/test/integration/targets/async/tasks/main.yml @@ -310,3 +310,30 @@ - assert: that: - '"ASYNC OK on localhost" in check_task_disabled_output.stdout' + +- name: test 'hidden' async, gather_facts does internal on parallel true. Ensure it won't freeze in check_mode due to async_status not supporting it. + gather_facts: + parallel: true + timeout: 60 + check_mode: true + when: "ansible_facts['os_family'] != 'Darwin'" + vars: + ansible_facts_modules: + - setup + - package_facts + - service_facts + +- name: test async in check mode + check_mode: true + block: + - setup: + async: 60 + poll: 0 + register: gf_async + - async_status: + jid: "{{ gf_async['ansible_job_id'] }}" + register: gf_done + until: gf_done is finished + retries: 100 + delay: 10 + timeout: 30