diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index 4f861e50eec..ebf20cb7d32 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -1227,10 +1227,28 @@ class Runner(object): def _remote_checksum(self, conn, tmp, path, inject): ''' takes a remote checksum and returns 1 if no file ''' - if 'delegate_to' in inject and inject['delegate_to'] and inject['delegate_to'] in inject['hostvars']: - python_interp = inject['hostvars'][inject['delegate_to']].get('ansible_python_interpreter', 'python') + + # Lookup the python interp from the host or delegate + + # host == inven_host when there is no delegate + host = inject['inventory_hostname'] + if 'delegate_to' in inject: + delegate = inject['delegate_to'] + if delegate: + # host == None when the delegate is not in inventory + host = None + # delegate set, check whether the delegate has inventory vars + delegate = template.template(self.basedir, delegate, inject) + if delegate in inject['hostvars']: + # host == delegate if we need to lookup the + # python_interpreter from the delegate's inventory vars + host = delegate + + if host: + python_interp = inject['hostvars'][host].get('ansible_python_interpreter', 'python') else: - python_interp = inject['hostvars'][inject['inventory_hostname']].get('ansible_python_interpreter', 'python') + python_interp = 'python' + cmd = conn.shell.checksum(path, python_interp) data = self._low_level_exec_command(conn, cmd, tmp, sudoable=True) data2 = utils.last_non_blank_line(data['stdout']) diff --git a/test/integration/Makefile b/test/integration/Makefile index 77c81a76b91..fc973e368f4 100644 --- a/test/integration/Makefile +++ b/test/integration/Makefile @@ -19,7 +19,7 @@ TMPDIR = $(shell mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir') VAULT_PASSWORD_FILE = vault-password -all: parsing test_var_precedence unicode non_destructive destructive includes check_mode test_hash test_handlers test_group_by test_vault +all: parsing test_var_precedence unicode non_destructive destructive includes check_mode test_hash test_handlers test_group_by test_vault test_delegate_to parsing: ansible-playbook bad_parsing.yml -i $(INVENTORY) -e @$(VARS_FILE) $(CREDENTIALS_ARG) -vvv $(TEST_FLAGS) --tags prepare,common,scenario1; [ $$? -eq 3 ] @@ -65,6 +65,9 @@ test_vault: ansible-playbook test_vault.yml -i $(INVENTORY) $(CREDENTIALS_ARG) -v $(TEST_FLAGS) --vault-password-file $(VAULT_PASSWORD_FILE) --syntax-check ansible-playbook test_vault.yml -i $(INVENTORY) $(CREDENTIALS_ARG) -v $(TEST_FLAGS) --vault-password-file $(VAULT_PASSWORD_FILE) +test_delegate_to: + ansible-playbook test_delegate_to.yml -i $(INVENTORY) -e @$(VARS_FILE) $(CREDENTIALS_ARG) -v $(TEST_FLAGS) + test_winrm: ansible-playbook test_winrm.yml -i inventory.winrm -e @$(VARS_FILE) $(CREDENTIALS_ARG) -v $(TEST_FLAGS) diff --git a/test/integration/inventory b/test/integration/inventory index a9f160c9895..72d80aabebd 100644 --- a/test/integration/inventory +++ b/test/integration/inventory @@ -1,6 +1,9 @@ [local] testhost ansible_ssh_host=127.0.0.1 ansible_connection=local testhost2 ansible_ssh_host=127.0.0.1 ansible_connection=local +# For testing delegate_to +testhost3 ansible_ssh_host=127.0.0.3 +testhost4 ansible_ssh_host=127.0.0.4 # the following inline declarations are accompanied # by (preferred) group_vars/ and host_vars/ variables diff --git a/test/integration/test_delegate_to.yml b/test/integration/test_delegate_to.yml new file mode 100644 index 00000000000..4ffac5568f0 --- /dev/null +++ b/test/integration/test_delegate_to.yml @@ -0,0 +1,50 @@ +- hosts: testhost3 + roles: + - { role: prepare_tests } + vars: + - template_role: ./roles/test_template + - templated_var: foo + tasks: + - name: Test no delegate_to + setup: + register: setup_results + + - assert: + that: + - '"127.0.0.3" in setup_results.ansible_facts.ansible_env["SSH_CONNECTION"]' + + - name: Test delegate_to with host in inventory + setup: + register: setup_results + delegate_to: testhost4 + + - assert: + that: + - '"127.0.0.4" in setup_results.ansible_facts.ansible_env["SSH_CONNECTION"]' + + - name: Test delegate_to with host not in inventory + setup: + register: setup_results + delegate_to: 127.0.0.254 + + - assert: + that: + - '"127.0.0.254" in setup_results.ansible_facts.ansible_env["SSH_CONNECTION"]' +# +# Smoketest some other modules do not error as a canary +# + - name: Test file works with delegate_to and a host in inventory + file: path={{ output_dir }}/foo.txt mode=0644 state=touch + delegate_to: testhost4 + + - name: Test file works with delegate_to and a host not in inventory + file: path={{ output_dir }}/test_follow_link mode=0644 state=touch + delegate_to: 127.0.0.254 + + - name: Test template works with delegate_to and a host in inventory + template: src={{ template_role }}/templates/foo.j2 dest={{ output_dir }}/foo.txt + delegate_to: testhost4 + + - name: Test template works with delegate_to and a host not in inventory + template: src={{ template_role }}/templates/foo.j2 dest={{ output_dir }}/foo.txt + delegate_to: 127.0.0.254