Hi,

I am hoping that someone can explain a difference in behaviour when using 
the API, where success is achieved when using Python 2 (2.7 tested) and a 
failure occurs when using Python 3 (3.6 and 3.8 tested).

The outcome of running the same code with the 2 versions of Python are as 
follows (ansible == latest, but occurs on 2.9, 2.10 etc):

*Python 2.7*

./py2/bin/python test.py; echo $?  --> 0

# extract of full output
controller1 | SUCCESS => {
    "msg": "a0492524b4da454d992d9987481cacf2"
}
node1 | SUCCESS => {
    "msg": "a0492524b4da454d992d9987481cacf2"
}

Ignore the fact that the machine ID is identical, as that is purely due to 
instances running from the same base image.

*Python 3.6*

./py3/bin/python test.py; echo $?  --> 2

# extract of full output
[WARNING]: Unhandled error in Python interpreter discovery for host node1: 
'>' not supported between instances of 'NoneType' and 'int'
An exception occurred during task execution. To see the full traceback, use 
-vvv. The error was: TypeError: '>' not supported between instances of 
'NoneType' and 'int'
node1 | FAILED! => {
    "msg": "Unexpected failure during module execution.",
    "stdout": ""
}

controller1 | SUCCESS => {
    "msg": "a0492524b4da454d992d9987481cacf2"
}

I have attached the steps to reproduce the issue. 

It seems to relate to the connection plugin, whereby unless a local 
connection  is used then running with Python 3 will error, whereas Python 2 
will not.

Cheers,

Ceri

-- 
You received this message because you are subscribed to the Google Groups 
"Ansible Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to ansible-devel+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ansible-devel/2506b674-b36b-41a4-be9b-54905b9104aen%40googlegroups.com.
# Pre-requisites

- python3.6
- virtualenv module for python3.6
- python2.7

# Prep

cd $(mktemp -d)
export CONTROLLER_IP=x.x.x.x NODE_IP=x.x.x.x

cat <<EOS > ./inventory.yaml
---
all:
  hosts:
    controller1:
      ansible_connection: local
      ansible_host: '{{ lookup("env", "CONTROLLER_IP") }}'
    node1:
      ansible_host: '{{ lookup("env", "NODE_IP") }}'
  children:
    controllers:
      hosts:
        controller1:
    nodes:
      hosts:
        node1:
    cluster:
      children:
        controllers:
        nodes:
...
EOS

cat <<EOS > ./.vault-pass
secret
EOS

cat <<EOS > test.py
import sys

from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.inventory.manager import InventoryManager
from ansible.module_utils.common.collections import ImmutableDict
from ansible.module_utils._text import to_bytes
from ansible.parsing.dataloader import DataLoader
from ansible.parsing.vault import VaultSecret
from ansible.playbook.play import Play
from ansible.plugins.callback.minimal import CallbackModule
from ansible.vars.manager import VariableManager
from ansible import context

context.CLIARGS = ImmutableDict(connection='ssh', forks=10, become=None, 
become_method=None, become_user=None, 
                                check=False, diff=False, 
inventory=['./inventory.yaml'])
loader = DataLoader()
loader.set_vault_secrets([('default', 
VaultSecret(_bytes=to_bytes(open('./.vault-pass', 
'rb').readlines().pop().rstrip()))),])
inventory = InventoryManager(loader=loader, sources=['./inventory.yaml'])
variable_manager = VariableManager(loader=loader, inventory=inventory)
passwords=dict()

results_callback = CallbackModule()
tqm = TaskQueueManager(inventory=inventory, variable_manager=variable_manager, 
loader=loader, passwords=passwords, stdout_callback=results_callback)
play_source = dict(name="Ansible Play", hosts='cluster', gather_facts='no',
                   tasks=[
                       dict(action=dict(module='setup', 
args=dict(gather_subset='min'))), 
                       dict(action=dict(module='debug', args=dict(msg='{{ 
ansible_machine_id }}'))),])
play = Play().load(play_source, variable_manager=variable_manager, 
loader=loader)
result = tqm.run(play)

sys.exit(result)
EOS

python3 -m virtualenv -p python2.7 py2
./py2/bin/pip install ansible

python3 -m virtualenv -p python3.6 py3
./py3/bin/pip install ansible

./py3/bin/ansible-vault encrypt --encrypt-vault-id default 
--vault-password-file ./.vault-pass inventory.yaml

# Tests

./py2/bin/python test.py; echo $?

./py3/bin/python test.py; echo $?

Reply via email to