Fix Python encodings
This role ensures the python3-libs package is installed,
as well as verifies the necessary encoding file is in the system
– and if not, it is fetched directly from the CPython repository.
Important!
Make sure to call this role from a playbook without gathering facts!
(Set gather_facts: false ~ otherwise it makes no sense to use this role!)
Details
When Ansible tries to invoke modules on target machines, it relies on the call [1] to ZipFile module from the Python standard library [2]. The handling of zip files requires to support necessary encodings, which should typically be CP437 (Code Page 437 [3]) and UTF-8 (but sometimes it can be also CP1252/Windows-1252 or ISO-8859-1 [4]).
When attempting to run Ansible modules against some freshly provisioned hypervisors, sometimes, rarely, but still from time to time, we encounter:
PLAY [Prepare the hypervisor.] ************************************************
TASK [Create zuul user name=zuul, state=present] ******************************
fatal: [hypervisor]: FAILED! => {
"changed": false,
"module_stderr": "
Warning: Permanently added '(...)' (ED25519) to the list of known hosts.
Traceback (most recent call last):
File \"<stdin>\", line 107, in <module>
File \"<stdin>\", line 99, in _ansiballz_main
File \"<stdin>\", line 35, in invoke_module
File \"/usr/lib64/python3.9/zipfile.py\", line 1286, in __init__
self._RealGetContents()
File \"/usr/lib64/python3.9/zipfile.py\", line 1371, in _RealGetContents
filename = filename.decode('cp437')
LookupError: unknown encoding: cp437
",
"module_stdout": "",
"msg": "MODULE FAILURE See stdout/stderr for the exact error",
"rc": 1
}
In Red Hat distributions it should come from the python3-libs package,
where it is shipped as just compiled Python file:
# rpm -qal python3-libs | grep -i 'encodings/cp437'
/usr/lib64/python3.9/encodings/cp437.pyc
However, in some installations we either seem to lack python3-libs
or simply that file is removed accidentally by some cleaning tool.
Unfortunately, it looks like a problem that occur from time to time [5].
This role ensures the python3-libs package is installed,
as well as verifies the necessary encoding file is in the system
– and if not, it is fetched directly from the CPython repository [6].
To make sure it is all doable, everything in this role is performed via Ansible
raw action plugin [7] that does not invoke the modules subsystem [8]
on the target host.