Skip to content

A port of EL8 dnf bindings to Python 3.12 for Ansible 2.17+

License

Notifications You must be signed in to change notification settings

space88man/dnf-el8-python312

Repository files navigation

DNF Bindings for Python 3.12/EL8

The Problem: The Ansible "Ceiling" on EL8

On EL8-based distributions (RHEL, AlmaLinux, Rocky), Ansible is effectively capped at version 2.16. This is because Ansible 2.17+ requires a controller/target Python version ≥ 3.7. While EL8 provides Python 3.12, it does not provide the necessary C-extensions (bindings) for dnf or rpm for any version other than the system-locked Python 3.6.

To use Ansible 2.17+, administrators currently have to split their inventory or manually toggle ansible_python_interpreter, creating significant technical debt.

Reference: https://forum.ansible.com/t/python-3-7-impact-on-el8-future-for-el9/6229/12

Goals

The goal of this project is to provide relocatable install/site-packages/ contents, containing the Python 3.12 equivalents of

  • python3-gpg
  • python3-libcomps
  • python3-libdnf
  • python3-hawkey

The contents of the folder can be copied to an Ansible Python 3.12 virtual environment.

For these to be usable by Ansible for system tasks you would still need python3-dnf and python3.12-rpm packages which can be obtained from the platform.

What is "Respawning"?

When the Ansible controller runs a DNF task on an EL8 target using a modern Python (like 3.12), the module first attempts a native import dnf. If this fails, Ansible attempts to "respawn" the module by calling /usr/libexec/platform-python (Python 3.6).

Because Ansible 2.17+ dropped support for Python 3.6, this respawn fails. Consequently, DNF/RPM tasks are restricted to the legacy Ansible 2.16/Community 9.x ecosystem.

Bindings of Python 3.12 for EL8

This repository provides the "missing link": build scripts to compile the "Big 4" C-extensions specifically for Python 3.12 on EL8. This enables Ansible 2.17+ to manage EL8 nodes natively without respawning or falling back to legacy interpreters.

  • libdnf (python3-libdnf): The core C logic for DNF.
  • hawkey (python3-hawkey): The high-level API for query resolution.
  • gpgme (python3-gpg): GPG signing and verification.
  • libcomps (python3-libcomps): Handling of package groups and comps metadata.

python3-dnf

The python3-dnf package itself is pure Python and can be reused verbatim. In practice, this can be achieved by copying the /usr/lib/python3.6/site-packages/dnf folder into the target environment.

python3-rpm

python3.12-rpm is provided by the platform - it can be reused for the target environment by copying /usr/lib64/python3.12/site-packages/rpm or using ... --system-site-packages ... when creating the target environment.

SELinux

While a Python 3.12 equivalent of python3-libselinux might seem like a prerequisite, it is not a "hard" dependency for Ansible. If a native import selinux fails, the Ansible engine is designed to fallback to CLI-based mechanisms.

Thus, the "Big 4" focus remains on the DNF/RPM stack where no such CLI fallback exists for complex library interactions.

Implementation Notes

Relocatability & Shared Libraries

RPATH-Free Binaries: The build process is intentionally configured to avoid hardcoding RPATH or RUNPATH. These extensions are designed to bind directly to the EL 8 system libraries in /usr/lib64 (e.g., libdnf.so.2),

Deployment: The contents of install/site-packages/ are relocatable. You can rsync them into a host-specific virtual environment or—at your own risk (AYOR)—into the global system site-packages at /usr/lib64/python3.12/site-packages.

The SWIG Toolchain

SWIG 3/4: both the default SWIG 3 and modular SWIG 4.1 have been tested to work.

Feedback Loop

At this stage, we are providing reproducible build scripts rather than pre-compiled RPMs. We want to ensure the build process is robust across various EL8 minor versions (8.6 through 8.10) and collect user feedback on edge-case DNF behaviors before moving to a formal release.

Native Tooling & Dependencies

Source Parity: These scripts leverage official platform Source RPMs (.src.rpm) to ensure the resulting bindings are 1:1 functional matches with the system versions.

Builds: The scripts may perform partial/full autotools or cmake runs to generate headers.

Root Access Required: Because the build process must satisfy build-time dependencies (e.g., zchunk-devel, expat-devel, libsolv-devel), you must have root or sudo privileges on the build host to install the necessary development headers and .so links before starting the build.

Non-goals

This project does not attempt to:

  • replace or modify the system DNF stack
  • provide alternative dependency resolution logic
  • backport newer DNF features from EL9

About

A port of EL8 dnf bindings to Python 3.12 for Ansible 2.17+

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages