Ansible collection carlijoy.compat — backport of ansible.builtin.dnf for EL8 + ansible-core >= 2.17 via /usr/libexec/platform-python
Project description
ansible-el-compat
Ansible collection carlijoy.compat — backport of ansible.builtin modules for EL8 + ansible-core >= 2.17.
No longer needed on ansible-core ≥ 2.21. The upstream fix landed in ansible/ansible#86432. This collection remains useful for ansible-core 2.17–2.20.
The problem
ansible-core >= 2.17 ships module code that uses from __future__ import annotations,
requiring Python 3.10+ on managed hosts. On AlmaLinux / Rocky Linux / RHEL 8,
python3-dnf is only available for Python 3.6 and 3.9 — so ansible.builtin.dnf
fails with a modern ansible-core.
Upstream fix in ansible-core 2.21
ansible-core 2.21 (currently pre-release) resolves this problem natively via
PR #86432. The fix splits the
dnf module into a modern-Python module layer and an older-Python CLI shim,
so ansible.builtin.dnf can once again run against EL8 hosts without requiring
Python 3.10+. If you are already on ansible-core ≥ 2.21, you can use
ansible.builtin.dnf directly and do not need this collection.
The solution
This collection backports ansible.builtin.dnf to EL8 by shipping a pre-built
binary module that is the original ansible.builtin.dnf from ansible-core 2.15
(the last release that fully supported EL8), bundled together with all of its
ansible.module_utils.* dependencies into a self-executing zip archive.
The bundle carries a #!/usr/libexec/platform-python shebang. Ansible detects
it as a binary module, copies it to the managed host, and runs it directly —
without the ansiballz wrapper — under /usr/libexec/platform-python, the EL8
system Python that has python3-dnf available. The result is 100% feature
parity with ansible.builtin.dnf on EL8 targets, regardless of which Python
interpreter drives ansible-core on the controller.
The bundle is regenerated by build-script/build_dnf_bundle.py (uses
uv run with ansible-core 2.15 pinned via inline script metadata).
Installation
via pip / uv (recommended)
pip install ansible-el-compat
# or
uv pip install ansible-el-compat
No ansible-galaxy required — the collection is discovered automatically from
site-packages/ansible_collections/.
via ansible-galaxy
ansible-galaxy collection install carlijoy.compat
Modules
carlijoy.compat.dnf
Backport of ansible.builtin.dnf for EL8. Accepts the same parameters as
ansible.builtin.dnf — it is that module, just packaged to run under the
right Python interpreter.
Common options
| Option | Type | Default | Description |
|---|---|---|---|
name |
str or list | required | Package name(s), version constraints supported |
state |
str | present |
present, absent, or latest |
enablerepo |
list | [] |
Repos to enable for this transaction only |
disablerepo |
list | [] |
Repos to disable for this transaction only |
disable_gpg_check |
bool | false |
Pass --nogpgcheck to dnf |
update_cache |
bool | false |
Run dnf makecache before the transaction |
Examples
- name: Install a package
carlijoy.compat.dnf:
name: htop
state: present
- name: Install multiple packages
carlijoy.compat.dnf:
name:
- htop
- curl
state: present
- name: Remove a package
carlijoy.compat.dnf:
name: telnet
state: absent
- name: Install from a specific repo only
carlijoy.compat.dnf:
name: rabbitmq-server <= 4
disablerepo: '*'
enablerepo: rabbitmq
state: present
- name: Upgrade, refreshing cache first
carlijoy.compat.dnf:
name: openssl
state: latest
update_cache: true
Migrating from ansible.builtin.dnf
# Before
- ansible.builtin.dnf:
name: httpd
state: present
# After
- carlijoy.compat.dnf:
name: httpd
state: present
For persistent repo enable/disable (not per-transaction), continue using
community.general.dnf_config_manager.
Development
git clone https://github.com/CarliJoy/ansible-el-compat
cd ansible-el-compat
uv sync --group dev
uv run prek install # install git hooks
uv run prek run --all-files # lint + type check
uv run pytest tests/ -v # integration tests (requires Docker)
Tests use testcontainers to spin up a real AlmaLinux 8 container with SSH and Python 3.12, then run Ansible against it. Docker must be available on the test host.
Rebuilding the backported bundle
uv run build-script/build_dnf_bundle.py
This downloads ansible-core 2.15 into an isolated environment (via the inline
uv script metadata), extracts ansible/modules/dnf.py and all transitive
ansible/module_utils/ dependencies, and writes the self-executing zip to
src/ansible_collections/carlijoy/compat/plugins/modules/dnf.
Attribution & Bundled Components
This collection bundles the original ansible.builtin.dnf module from
ansible-core 2.15, written by the Ansible project contributors. The bundle
is not a fork or reimplementation — it is that exact module, unchanged, just
repackaged to run under the EL8 system Python interpreter that has access to
python3-dnf. All credit for the actual dnf functionality belongs to the
original authors.
Why the module is bundled
ansible-core 2.17 introduced from __future__ import annotations across its
module code, which requires Python 3.10+ on managed hosts. On EL8 targets,
python3-dnf is only available for Python 3.6 and 3.9, so
ansible.builtin.dnf started failing. This collection solves that by bundling
the last ansible-core version (2.15) that fully supports EL8 and shipping it as
a binary module with a #!/usr/libexec/platform-python shebang that bypasses
the controller's Python choice entirely.
Links to the original source
- ansible/ansible repository: https://github.com/ansible/ansible
dnf.pyat v2.15.0: https://github.com/ansible/ansible/blob/v2.15.0/lib/ansible/modules/dnf.pyyumdnf.pyat v2.15.0: https://github.com/ansible/ansible/blob/v2.15.0/lib/ansible/module_utils/yumdnf.py
Thank you to the Ansible project and all Red Hat contributors for the work that
makes this compatibility shim possible. See the NOTICE file in this
repository for the complete attribution and license notices for every bundled
file.
License
GPL-3.0-or-later
The backported module bundle contains code from ansible-core, which is licensed under the GNU General Public License v3.0 or later. This collection is therefore also distributed under GPL-3.0-or-later.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ansible_el_compat-0.1.6.tar.gz.
File metadata
- Download URL: ansible_el_compat-0.1.6.tar.gz
- Upload date:
- Size: 259.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4e6823fedf4fd286ab1a12bf74f0900f59bc2be37e11e0d69c4cfb1eca0ec4f2
|
|
| MD5 |
6942a38576f4ab54e04adfa4793d0e39
|
|
| BLAKE2b-256 |
ef424deff0695190ea84d73ca400692dbd91e86e795f2239ceff428067feb0d9
|
File details
Details for the file ansible_el_compat-0.1.6-py3-none-any.whl.
File metadata
- Download URL: ansible_el_compat-0.1.6-py3-none-any.whl
- Upload date:
- Size: 168.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0f8d567b5ad1d295f497c558346f83e4d13f807627edb7b1ba9e25b39e49dc23
|
|
| MD5 |
82fd163975b8fafbf459c6e001290258
|
|
| BLAKE2b-256 |
caa7ee31ca56ee3b8a4cf6cb17ff7c070e13b3acc34dea04421f45586ad25a5e
|