Test Acme Challenges: No module named http.client

I’m excited to try out the new github-oauth composer authentication support in the latest Trellis version!

I just upgraded my trellis project to the latest version 1.19.0, re-init the project with destroying my local box and running trellis init.
Locally everything is working fine again, however when I try to re-provision my remote server I get the following error during the letsencrypt : Test Acme Challenges task:

TASK [letsencrypt : Test Acme Challenges] **************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ImportError: No module named http.client
failed: [159.65.192.172] (item=example.com) => {...}, "module_stderr": "Traceback (most recent call last):\n  File \"<stdin>\", line 102, in <module>\n  File \"<stdin>\", line 94, in _ansiballz_main\n  File \"<stdin>\", line 40, in invoke_module\n  File \"/usr/lib/python2.7/runpy.py\", line 188, in run_module\n    fname, loader, pkg_name)\n  File \"/usr/lib/python2.7/runpy.py\", line 82, in _run_module_code\n    mod_name, mod_fname, mod_loader, pkg_name)\n  File \"/usr/lib/python2.7/runpy.py\", line 72, in _run_code\n    exec code in run_globals\n  File \"/tmp/ansible_test_challenges_payload_N_vGBn/ansible_test_challenges_payload.zip/ansible/modules/test_challenges.py\", line 5, in <module>\nImportError: No module named http.client\n", "module_stdout": "", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}
...ignoring

TASK [letsencrypt : Notify of challenge failures] ******************************
fatal: [159.65.192.172]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'failed_hosts'\n\nThe error appears to be in '/Users/username/path/to/project/trellis/roles/letsencrypt/tasks/nginx.yml': line 65, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Notify of challenge failures\n  ^ here\n"}

The error No module named http.client is caused since the test_challenges seems to be using python 2.7 while http.client was added in python 3?

I have no reference to any python 2.7 instance?
With pyenv I have set python 3.9.14 as my global version.

When I run trellis exec ansible --version, it outputs:

ansible 2.10.17
  config file = /Users/username/path/to/project/trellis/ansible.cfg
  configured module search path = ['/Users/username/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/username/path/to/project/trellis/.trellis/virtualenv/lib/python3.9/site-packages/ansible
  executable location = /Users/username/path/to/project/trellis/.trellis/virtualenv/bin/ansible
  python version = 3.9.14 (main, Jan  6 2023, 15:39:05) [Clang 14.0.0 (clang-1400.0.29.202)]

That also displays python 3.9.14?

The test_challenges.py file where http.client gets imported also has a shebang line that points to my python3 path.

Any thoughts why this is happening?
I have never seen this one before, thanks!

What does trellis check output?

Checking Trellis requirements...

Required:

[✓] Python [>= 3.8.0]: 3.9.14

Optional:

[✓] Vagrant [>= 2.1.0]: 2.2.18
[X] VirtualBox [>= 4.3.10]: not installed

So also the correct python version?
The paths in the error seem to be external:

/tmp/ansible_test_challenges_payload_N_vGBn/ansible_test_challenges_payload.zip/ansible/modules/test_challenges.py

And

File \"/usr/lib/python2.7/runpy.py\

Can’t find any reference to these files locally or in trellis?
Thanks!

P.S.
When I run python --version on the remote server, it outputs Python 2.7.18
and python3 --version gives me Python 3.8.10?

The original provisioning of the server was done with Trellis 1.13.0, could it be this was done with Python 2.7 and re-provisioning does not set the default to python3 or something along those lines?

When I rollback this commit, re-provisioning works again?

1 Like

As you last suspected, this error is only related to the version of Python on your server, nothing to do with your local machine.

Yeah this could be causing issues. I’m assuming both Python 2 and Python 3 are installed. You have a few options:

  1. try removing python2, leaving just python3
  2. install the python-is-python3 package (either manually or defining apt_packages_custom with it)

Though I’d still expect this to work due to the /usr/bin/python3 shebang, and as you said, that properly returns Python 3.8.10 :thinking:

1 Like

Thanks @swalkinshaw, I can confirm adding this in group_vars/all/main.yml:

apt_packages_custom:
  python-is-python3: "{{ apt_package_state }}"

Will fix this issue for re-provisioning servers that still use python 2.7 as default with trellis 1.19+.
After adding the python-is-python3 package, the server now uses python 3.8.10!

1 Like