From 6c91c48305a00f5777076f9868f36d35bf1e8639 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Tue, 20 Feb 2024 05:35:05 +1000 Subject: [PATCH] Fix up gather_facts parallel=true in check mode Fixed code to run parallel=true when in check mode rather than perpetually looping. --- changelogs/fragments/gather_facts_async.yml | 2 + lib/ansible/plugins/action/gather_facts.py | 48 +++++++++++++------ .../gathering_facts/test_gathering_facts.yml | 13 +++++ 3 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 changelogs/fragments/gather_facts_async.yml diff --git a/changelogs/fragments/gather_facts_async.yml b/changelogs/fragments/gather_facts_async.yml new file mode 100644 index 00000000000..63b58a932f0 --- /dev/null +++ b/changelogs/fragments/gather_facts_async.yml @@ -0,0 +1,2 @@ +bugfixes: +- gather_facts - Fix up check mode support when ``parallel=true`` - https://github.com/ansible/ansible/issues/82685 diff --git a/lib/ansible/plugins/action/gather_facts.py b/lib/ansible/plugins/action/gather_facts.py index 31210ec724d..9bf6296d4e7 100644 --- a/lib/ansible/plugins/action/gather_facts.py +++ b/lib/ansible/plugins/action/gather_facts.py @@ -133,23 +133,41 @@ class ActionModule(ActionBase): self._display.vvvv("Running %s" % fact_module) jobs[fact_module] = (self._execute_module(module_name=fact_module, module_args=mod_args, task_vars=task_vars, wrap_async=True)) - while jobs: - for module in jobs: - poll_args = {'jid': jobs[module]['ansible_job_id'], '_async_dir': os.path.dirname(jobs[module]['results_file'])} - res = self._execute_module(module_name='ansible.legacy.async_status', module_args=poll_args, task_vars=task_vars, wrap_async=False) - if res.get('finished', 0) == 1: - if res.get('failed', False): - failed[module] = res - elif res.get('skipped', False): - skipped[module] = res + check_mode = self._task.check_mode + try: + # async_status does not support check mode, this avoids + # that problem for this specific step. + self._task.check_mode = False + + while jobs: + for module in jobs: + poll_args = { + 'jid': jobs[module]['ansible_job_id'], '_async_dir': + os.path.dirname(jobs[module]['results_file']), + } + res = self._execute_module( + module_name='ansible.legacy.async_status', + module_args=poll_args, + task_vars=task_vars, + wrap_async=False, + ) + if res.get('finished', 0) == 1: + if res.get('failed', False): + failed[module] = res + elif res.get('skipped', False): + skipped[module] = res + else: + result = self._combine_task_result(result, res) + del jobs[module] + break else: - result = self._combine_task_result(result, res) - del jobs[module] - break + time.sleep(0.1) else: - time.sleep(0.1) - else: - time.sleep(0.5) + time.sleep(0.5) + + finally: + self._task.check_mode = check_mode + # restore value for post processing if self._task.async_val != async_val: diff --git a/test/integration/targets/gathering_facts/test_gathering_facts.yml b/test/integration/targets/gathering_facts/test_gathering_facts.yml index 47027e87175..377d27a4fc8 100644 --- a/test/integration/targets/gathering_facts/test_gathering_facts.yml +++ b/test/integration/targets/gathering_facts/test_gathering_facts.yml @@ -534,3 +534,16 @@ - "{{ output_dir }}/empty_file" - "{{ output_dir }}/1charsep" - "{{ output_dir }}/2charsep" + +- hosts: facthost1 + gather_facts: no + tasks: + - name: check parallel works in check mode + gather_facts: + parallel: true + check_mode: true + + - name: assert result of check parallel works in check mode + assert: + that: + - 'ansible_user_id|default("UNDEF_MIN") != "UNDEF_MIN"'