Ansible builtin expect fails with python error

I have a playbook I’ve been using for a couple of years that uses the expect module to join a Linux host to the AD domain.
The relevant stanza is this:

  - name: Join system to AD
    expect:
      command: /bin/bash -c "/usr/sbin/realm join --user={{ ldap_user }} mydomain --computer-ou=OU=Servers"
      responses:
        (?i)Password: "{{ bind_password }}"
    notify:
    -  restart sssd

Username and bind password are prompted for at invocation.
As I said it’s been working fine, but I am setting up my first RHEL9 servers, RHEL9.2-EUS and it fails with this error:

Traceback (most recent call last):
  File "/tmp/ansible_expect_payload_f22xbqfd/ansible_expect_payload.zip/ansible/modules/expect.py", line 210, in main
AttributeError: module 'pexpect' has no attribute 'run'

pexpect and ptyprocess are installed by another playbook. Both are at current versions. Python version at the remote end is 3.9

Ansible version is

ansible-playbook [core 2.14.4]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/myuser/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/myuser/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible-playbook
  python version = 3.9.13 (main, Nov  9 2022, 13:16:24) [GCC 8.5.0 20210514 (Red Hat 8.5.0-15)] (/usr/bin/python3.9)
  jinja version = 3.1.3
  libyaml = True

This is obviously a python error, and probably related to the RedHat version but I can’t figure out why it would be unable to use a function out of the pexpect module. Is it missing a dependency?
Any help would be appreciated.

On the remote server? I’m asking as I’d guess that is where they are required and your post appears to indicate that this is on the Ansible controller? Of course I could be totally wrong, this is just a quick guess!

Yes, pexpect and ptyprocess are installed on the remote server by a previous ansible playbook that makes sure the environment is ready for ansible. It also installs python3,9 if it is not present, pip 3.9, etc.

post full execution plus error using -vvv, also note that 2.14 is pretty old at this point.

Also you should show pexpect version (module requires pexpect >= 3.3)

1 Like
TASK [Join system to AD] ***************************************************************************************************
task path: /home/danbak1/git/current-playbooks/AD.yml:44
<myhost> ESTABLISH SSH CONNECTION FOR USER: root
<myhost> SSH: EXEC sshpass -d10 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/home/danbak1/.ansible/cp/da4efc7913"' myhost '/bin/sh -c '"'"'echo ~root && sleep 0'"'"''
<myhost> (0, b'/root\n', b'')
<myhost> ESTABLISH SSH CONNECTION FOR USER: root
<myhost> SSH: EXEC sshpass -d10 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/home/danbak1/.ansible/cp/da4efc7913"' myhost '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489 `" && echo ansible-tmp-1728921680.1241539-3907961-267960157196489="` echo /root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489 `" ) && sleep 0'"'"''
<myhost> (0, b'ansible-tmp-1728921680.1241539-3907961-267960157196489=/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489\n', b'')
Using module file /usr/lib/python3.9/site-packages/ansible/modules/expect.py
<myhost> PUT /home/danbak1/.ansible/tmp/ansible-local-3902922r0c1y55b/tmpim5ot2eu TO /root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py
<myhost> SSH: EXEC sshpass -d10 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/home/danbak1/.ansible/cp/da4efc7913"' '[myhost]'
<myhost> (0, b'sftp> put /home/danbak1/.ansible/tmp/ansible-local-3902922r0c1y55b/tmpim5ot2eu /root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py\n', b'')
<myhost> ESTABLISH SSH CONNECTION FOR USER: root
<myhost> SSH: EXEC sshpass -d10 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/home/danbak1/.ansible/cp/da4efc7913"' myhost '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/ /root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py && sleep 0'"'"''
<myhost> (0, b'', b'')
<myhost> ESTABLISH SSH CONNECTION FOR USER: root
<myhost> SSH: EXEC sshpass -d10 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/home/danbak1/.ansible/cp/da4efc7913"' -tt myhost '/bin/sh -c '"'"'/usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py && sleep 0'"'"''
<myhost> (1, b'Traceback (most recent call last):\r\n  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 210, in main\r\nAttributeError: module \'pexpect\' has no attribute \'run\'\r\n\r\nDuring handling of the above exception, another exception occurred:\r\n\r\nTraceback (most recent call last):\r\n  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 107, in <module>\r\n    _ansiballz_main()\r\n  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 99, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 47, in invoke_module\r\n    runpy.run_module(mod_name=\'ansible.modules.expect\', init_globals=dict(_module_fqn=\'ansible.modules.expect\', _modlib_path=modlib_path),\r\n  File "/usr/lib64/python3.9/runpy.py", line 225, in run_module\r\n    return _run_module_code(code, init_globals, run_name, mod_spec)\r\n  File "/usr/lib64/python3.9/runpy.py", line 97, in _run_module_code\r\n    _run_code(code, mod_globals, init_globals,\r\n  File "/usr/lib64/python3.9/runpy.py", line 87, in _run_code\r\n    exec(code, run_globals)\r\n  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 258, in <module>\r\n  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 229, in main\r\nAttributeError: module \'pexpect\' has no attribute \'__version__\'\r\n', b'Shared connection to myhost closed.\r\n')
<myhost> Failed to connect to the host via ssh: Shared connection to myhost closed.
<myhost> ESTABLISH SSH CONNECTION FOR USER: root
<myhost> SSH: EXEC sshpass -d10 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="root"' -o ConnectTimeout=10 -o 'ControlPath="/home/danbak1/.ansible/cp/da4efc7913"' myhost '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/ > /dev/null 2>&1 && sleep 0'"'"''
<myhost> (0, b'', b'')
The full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 210, in main
AttributeError: module 'pexpect' has no attribute 'run'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible.modules.expect', init_globals=dict(_module_fqn='ansible.modules.expect', _modlib_path=modlib_path),
  File "/usr/lib64/python3.9/runpy.py", line 225, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib64/python3.9/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib64/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 258, in <module>
  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 229, in main
AttributeError: module 'pexpect' has no attribute '__version__'
fatal: [myhost]: FAILED! => {
    "changed": false,
    "rc": 1
}

MSG:

MODULE FAILURE
See stdout/stderr for the exact error


MODULE_STDOUT:

Traceback (most recent call last):
  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 210, in main
AttributeError: module 'pexpect' has no attribute 'run'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 107, in <module>
    _ansiballz_main()
  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 99, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/root/.ansible/tmp/ansible-tmp-1728921680.1241539-3907961-267960157196489/AnsiballZ_expect.py", line 47, in invoke_module
    runpy.run_module(mod_name='ansible.modules.expect', init_globals=dict(_module_fqn='ansible.modules.expect', _modlib_path=modlib_path),
  File "/usr/lib64/python3.9/runpy.py", line 225, in run_module
    return _run_module_code(code, init_globals, run_name, mod_spec)
  File "/usr/lib64/python3.9/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/usr/lib64/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 258, in <module>
  File "/tmp/ansible_expect_payload_3n1p_k08/ansible_expect_payload.zip/ansible/modules/expect.py", line 229, in main
AttributeError: module 'pexpect' has no attribute '__version__'



MODULE_STDERR:

Shared connection to myhost closed.

And pexpect

[root@RHEL92-Template ~]# pip show pexpect
Name: pexpect
Version: 4.9.0
Summary:
Home-page:
Author:
Author-email:
License:
Location: /usr/local/lib/python3.9/site-packages
Requires:
Required-by: sos

Weird, it is like it is getting the ‘wrong’ pexpect:

>>> print(pexpect.__version__)
4.9.0

The target uses /usr/bin/python3 on myhost is it 3.9 and does it have the correct version of pexpect installed?

It is weird, and perplexing.
Yes, the only version of python on the system is 3.9. pexpect is installed with pip3.9. I specify that after getting burned by that a couple of years ago, so it should be the right version.

You have found it.
There was a module pre-installed at /usr/local/lib/python3.9/site-packages/ that has no run or version properties in init.py
I renamed it and copied the installed version from /usr/lib/python3.9/site-packages/pexpect.
Now it is giving a ptyprocess/python/pexpect version mismatch. SO I need to figure out how to specify the correct location when installing the python module or the correct python module within the playbook.
Anyway, I understand what’s going on now, so thank you
Dan Baker

1 Like

Uninstalling pexpect and ptyprocess and then reinstalling resolved the issue

1 Like