Ansible: playbook not running with python3

Viewed 3734

I have cloned ansible repository and setup following official ansible documentation.

I have setup from source directly, by creating venv for python3.

Running this: . venv/bin/activate && . hacking/env-setup does set up ansible environment. And if I write this (while venv is activated):

ansible-playbook --version

It outputs this:

ansible-playbook 2.8.5.post0
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/oerp/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/oerp/src/ansible/lib/ansible
  executable location = /home/oerp/src/ansible/bin/ansible-playbook
  python version = 3.6.7 (default, Mar 29 2019, 10:38:28) [GCC 5.4.0 20160609]

So it does show that it used Python version 3.6.7. And if I run unittests for my custom modules that have python 3.6 syntax, tests run fine (tests are run with tox as documented by ansible itself).

But it fails to run my module via playbook. And it looks like it is executing it using python2.

When I run this command:

ansible-playbook --extra-vars "target=local_stage" --connection=local /home/oerp/src/ansible-playbooks/buildout_test.yml -vvv

It throws this traceback:

The full traceback is:
Traceback (most recent call last):
  File "/home/oerp/.ansible/tmp/ansible-tmp-1570781848.1110492-2720137190388/AnsiballZ_focusate_buildout.py", line 114, in <module>
    _ansiballz_main()
  File "/home/oerp/.ansible/tmp/ansible-tmp-1570781848.1110492-2720137190388/AnsiballZ_focusate_buildout.py", line 106, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/oerp/.ansible/tmp/ansible-tmp-1570781848.1110492-2720137190388/AnsiballZ_focusate_buildout.py", line 49, in invoke_module
    imp.load_module('__main__', mod, module, MOD_DESC)
  File "/tmp/ansible_focusate_buildout_payload_JDfOK3/__main__.py", line 52
    path: str,
        ^
SyntaxError: invalid syntax

Clearly it does not recognize typing syntax. Looking at debug, I can see such binaries being executed:

<stage-my-domain.com> EXEC /bin/sh -c '/usr/bin/python /home/oerp/.ansible/tmp/ansible-tmp-1570781848.1110492-2720137190388/AnsiballZ_my_buildout.py && sleep 0'

In my environment /usr/bin/python --version, is Python 2.7.12

Debugging also shows this information:

<stage-my-domain.com> EXEC /bin/sh -c 'echo PLATFORM; uname; echo FOUND; command -v '"'"'/usr/bin/python'"'"'; command -v '"'"'python3.7'"'"'; command -v '"'"'python3.6'"'"'; command -v '"'"'python3.5'"'"'; command -v '"'"'python2.7'"'"'; command -v '"'"'python2.6'"'"'; command -v '"'"'/usr/libexec/platform-python'"'"'; command -v '"'"'/usr/bin/python3'"'"'; command -v '"'"'python'"'"'; echo ENDFOUND && sleep 0'

Does anyone know why ansible ignores activated venv and just use global python which is python2?

P.S. I also have ansible installed globally via apt-get install ansible.

1 Answers

venv is a bit tricky to use. It is tied to your session. Ansible uses a different session when gets executed than you as a user who logs in. You need to activate venv for that specific session that Ansible uses when gets executed.

You can try two things:

1: setting environment variables:

environment:
  PATH: "{{ ansible_env.PATH }}:/yourpython/bin"
  SOME: value

2: setting the Ansible python interpreter

https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#how-do-i-handle-python-not-having-a-python-interpreter-at-usr-bin-python-on-a-remote-machine

Setting the inventory variable ansible_python_interpreter on any host will tell Ansible to auto-replace the Python interpreter with that value instead. Thus, you can point to any Python you want on the system if /usr/bin/python on your system does not point to a compatible Python interpreter.

Some platforms may only have Python 3 installed by default. If it is not installed as /usr/bin/python, you will need to configure the path to the interpreter via ansible_python_interpreter. Although most core modules will work with Python 3, there may be some special purpose ones which do not or you may encounter a bug in an edge case. As a temporary workaround you can install Python 2 on the managed host and configure Ansible to use that Python via ansible_python_interpreter.

Related