diff --git a/lib/ansible/executor/play_iterator.py b/lib/ansible/executor/play_iterator.py index faa5425462..aaaa59697b 100644 --- a/lib/ansible/executor/play_iterator.py +++ b/lib/ansible/executor/play_iterator.py @@ -169,6 +169,9 @@ class PlayIterator: fact_path = self._play.fact_path setup_block = Block(play=self._play) + # Gathering facts with run_once would copy the facts from one host to + # the others. + setup_block.run_once = False setup_task = Task(block=setup_block) setup_task.action = 'setup' setup_task.name = 'Gathering Facts' diff --git a/test/integration/targets/gathering_facts/runme.sh b/test/integration/targets/gathering_facts/runme.sh index e4c7b3844a..4baf8379e3 100755 --- a/test/integration/targets/gathering_facts/runme.sh +++ b/test/integration/targets/gathering_facts/runme.sh @@ -5,3 +5,5 @@ set -eux # ANSIBLE_CACHE_PLUGINS=cache_plugins/ ANSIBLE_CACHE_PLUGIN=none ansible-playbook test_gathering_facts.yml -i ../../inventory -v "$@" ansible-playbook test_gathering_facts.yml -i ../../inventory -v "$@" #ANSIBLE_CACHE_PLUGIN=base ansible-playbook test_gathering_facts.yml -i ../../inventory -v "$@" + +ANSIBLE_GATHERING=smart ansible-playbook test_run_once.yml -i ../../inventory -v "$@" diff --git a/test/integration/targets/gathering_facts/test_run_once.yml b/test/integration/targets/gathering_facts/test_run_once.yml new file mode 100644 index 0000000000..88ea155ddd --- /dev/null +++ b/test/integration/targets/gathering_facts/test_run_once.yml @@ -0,0 +1,28 @@ +--- +- hosts: facthost1 + gather_facts: no + tasks: + - name: install test local facts + copy: + src: uuid.fact + dest: /etc/ansible/facts.d/ + mode: 0755 + +- hosts: facthost1,facthost2 + gather_facts: yes + run_once: yes + tasks: + - block: + - name: 'Check the same host is used' + assert: + that: 'hostvars.facthost1.ansible_fqdn == hostvars.facthost2.ansible_fqdn' + msg: 'This test requires 2 inventory hosts referring to the same host.' + - name: "Check that run_once doesn't prevent fact gathering (#39453)" + assert: + that: 'hostvars.facthost1.ansible_local.uuid != hostvars.facthost2.ansible_local.uuid' + msg: "{{ 'Same value for ansible_local.uuid on both hosts: ' ~ hostvars.facthost1.ansible_local.uuid }}" + always: + - name: remove test local facts + file: + path: /etc/ansible/facts.d/uuid.fact + state: absent diff --git a/test/integration/targets/gathering_facts/uuid.fact b/test/integration/targets/gathering_facts/uuid.fact new file mode 100644 index 0000000000..79e3f62677 --- /dev/null +++ b/test/integration/targets/gathering_facts/uuid.fact @@ -0,0 +1,10 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +import json +import uuid + + +# return a random string +print(json.dumps(str(uuid.uuid4())))