I have a highly used playbook which has a simple first task: yum
, suddently, ever since I've upgraded my MacOSX the yum
module stopped working
Example:
- name: Install git
become: yes
yum:
name : git
state: present
Gives:
>>> print(a['module_stderr'])
OpenSSH_9.7p1, LibreSSL 3.3.6
debug1: /etc/ssh/ssh_config line 21: include /etc/ssh/ssh_config.d/* matched no files
debug1: /etc/ssh/ssh_config line 54: Applying options for *
debug2: resolve_canonicalize: hostname x.x.x.x is address
debug1: Authenticator provider $SSH_SK_PROVIDER did not resolve; disabling
debug1: auto-mux: Trying existing master at '/tmp/ansible-ssh-x.x.x.x-22-mysql'
debug2: fd 3 setting O_NONBLOCK
debug2: mux_client_hello_exchange: master version 4
debug1: mux_client_request_session: master session id: 2
Traceback (most recent call last):
File "<stdin>", line 12, in <module>
File "<frozen importlib._bootstrap>", line 971, in _find_and_load rr
Traceback (most recent call last):ap>", line 951, in _find_and_load_unlocked
File "<stdin>", line 1, in <module>", line 894, in _find_spec
NameError: name 'false' is not defined. Did you mean: 'False'? find_spec
>>> le "<frozen importlib._bootstrap_external>", line 1131, in _get_spec
>>> le "<frozen importlib._bootstrap_external>", line 1112, in _legacy_get_spec
>>> or File "<frozen Fimportlib._bootstrap>", line 441, in spec_from_loader rn
>>> le "<frozen importlib._bootstrap_external>", line 544, in spec_from_file_location
>>> le "/tmp/ansible_ansible.legacy.dnf_payload_c428fwbu/ansible_ansible.legacy.dnf_payload.zip/ansible/module_utils/basic.py", line 5
>>> SyntaxError: future feature annotations is not defined
The error: SyntaxError: future feature annotations is not defined
usually related to an old version of python, but my remote server has Python3.9
and to verify it - I also added it in my inventory and I printed the ansible_facts
to make sure.
This error is across all of my servers, they haven't changed only my MaxOSX version (Sonoma
)
Tried using use_backend: yum/dnf/etc ...
all values i've tried.
Anyone has a clue ?
This appears that it could be similar to this issue.
In that example, the yum
/ dnf
module in Ansible >= 2.17
is said to use a paradigm called "module respawn" which re-spawns a Python interpreter that the bindings it requires are assumed to be installed on. After Ansible connects to a remote host via SSH, it copies python modules to the remote host as zip files "Ansiballz" (a play on words like "tarball
"). For the remote host, the python interpreter must meet the requirements of the python code included in the zip file, which contains such module code as yum
or dnf
modules, originating from the host running Ansible.
In the example linked issue above, it is mentioned that EL8 based hosts have an older platform-python
Python version1 which is not compatible with Ansible 2.17
's module code.
So, since you have not changed the remote hosts and only upgraded MacOS, it may be likely that something locally changed which is being copied over in the "Ansiballz" module code that is now incompatible with the remote host's python interpreter. Presumably changing MacOS version, you will likely have also updated Ansible version via Homebrew?
If so, try downgrading the version of Ansible you are using on your control host. (e.g. Try Ansible 2.16
instead if using 2.17
as in the example related issue above).
Also, the following error indicates that false
(probably from YAML or JSON's lowercase "false
" boolean primitive) is being evaluated in Python interpreter's context:
NameError: name 'false' is not defined. Did you mean: 'False'? find_spec
It could be that the playbook or module needs to be using False
in some place instead of false
.
1Note: The platform-python
version on RHEL 8 family systems is older than the other default python interpreters (3.6.8
). yum
/ dnf
use /usr/libexec/platform-python
, which is that older version. The following explanation is mentioned in the example issue:
And here’s where Ansible
2.17+
breaks: using “system” modules that requireplatform-python
to work. You can run any and all modules on your RHEL8 targets, provided they have a suitable python interpreter, except modules that use “system” python, such as DNF/YUM.
If this is the case, you may try setting ansible_python_interpreter=/usr/libexec/platform-python
just for those specific yum
or dnf
tasks that require this version:
- name: Install git
become: yes
yum:
name : git
state: present
## RHEL8 uses separate platform-python 3.6.8 (deprecated in Ansible 2.17+)
## See: https://forum.ansible.com/t/ansible-playbook-ansible-core-2-17-1-fails-on-target-with-python-3-9/6700/8
vars:
ansible_python_interpreter: /usr/libexec/platform-python
This assumes that the yum
module code from your MacOS system's Ansible version is still compatible with platform-python
version 3.6.8
. If that's not the case, then forcing another version and/or downgrading the macOS Ansible version may help.
In cases like this, it's best to have avoided the issue entirely by not using macOS's Ansible + Python.framework
versions (This also applies to Homebrew, because brew
's packages are rolling-release). This introduces change that can break things relying on Ansible's past behavior. I'd recommend creating an Ansible Docker container that is run on macOS (or any system needing to run playbooks). This way, you can ensure you version pin the master Ansible version and avoid upgrade breakage like you're currently observing. Maintaining and updating that Docker image, you'd likely run into the same issues, but you could at least solve them on your own project timeframe as hosts get upgraded.