Describe the bug
Affected code: pyinfra/facts/rpm.py, RpmPackageProvides class
On Fedora 43+, repoquery is no longer a standalone binary; it's a subcommand of dnf5. The fact's requires_command returns "repoquery", which generates a ! command -v repoquery >/dev/null guard that short-circuits the entire lookup. Result: virtual package provides are never resolved, and dnf.packages always tries to reinstall packages like iotop (provided by iotop-c). There's dnf-utils that provides repoquery command, but that only solves half of the problem.
On top of that, I think this code path also fails to account for situation where there are multiple packages that provide the same package as the one requested. Even with repoquery available as a standalone binary:
[@docker/51ac0676abff] Loaded fact rpm.RpmPackages
[@docker/51ac0676abff] >>> sh -c 'docker exec -i 51ac0676abff sh -c '"'"'sh -c '"'"'"'"'"'"'"'"'! command -v repoquery >/dev/null || ( repoquery --queryformat '"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'%{NAME} %{VERSION}-%{RELEASE}\n'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"'"' --whatprovides wget || true )'"'"'"'"'"'"'"'"''"'"''
[@docker/51ac0676abff] Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
[@docker/51ac0676abff] Last metadata expiration check: 0:10:31 ago on Sun Mar 29 20:53:43 2026.
[@docker/51ac0676abff] wget1-wget 1.25.0-2.fc43
[@docker/51ac0676abff]
[@docker/51ac0676abff] wget2-wget 2.2.0-6.fc43
[@docker/51ac0676abff]
[@docker/51ac0676abff] wget2-wget 2.2.1-1.fc43
[@docker/51ac0676abff]
[@docker/51ac0676abff] Loaded fact rpm.RpmPackageProvides (package=wget)
[@docker/51ac0676abff] >>> sh -c 'docker exec -i 51ac0676abff sh -c '"'"'sh -c '"'"'"'"'"'"'"'"'dnf install -y wget'"'"'"'"'"'"'"'"''"'"''
[@docker/51ac0676abff] Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
[@docker/51ac0676abff] Updating and loading repositories:
[@docker/51ac0676abff] Repositories loaded.
[@docker/51ac0676abff] Nothing to do.
[@docker/51ac0676abff] Package "wget2-wget-2.2.1-1.fc43.x86_64" is already installed.
[@docker/51ac0676abff]
To Reproduce
- Start a Fedora 43+ container (
docker run -it fedora), keep it running, grab its ID
- Run
pyinfra -vvv @docker/51ac0676abff dnf.packages iotop - iotop-c should get installed
- Run the same command again - notice that pyinfra tried to reinstall
iotop-c
- Install
dnf-utils on that container
- Run
pyinfra -vvv @docker/51ac0676abff dnf.packages iotop - wget2-wget should be installed
- Run the same command again - pyinfra will try to reinstall
wget2-wget
Meta
❯ pyinfra --support
If you are having issues with pyinfra or wish to make feature requests, please
check out the GitHub issues at https://github.com/Fizzadar/pyinfra/issues .
When adding an issue, be sure to include the following:
System: Linux
Platform: Linux-6.19.9-200.fc43.x86_64-x86_64-with-glibc2.42
Release: 6.19.9-200.fc43.x86_64
Machine: x86_64
pyinfra: v3.7
click: v8.3.1
distro: v1.9.0
gevent: v25.9.1
jinja2: v3.1.6
packaging: v26.0
paramiko: v3.5.1
pydantic: v2.12.5
python-dateutil: v2.9.0.post0
typeguard: v4.5.1
typing-extensions: v4.15.0
Executable: /home/yacoob/workarea/homelab/.venv/bin/pyinfra
Python: 3.14.3 (CPython, Clang 21.1.4 )
Installed via uv in a local venv.
Describe the bug
Affected code:
pyinfra/facts/rpm.py,RpmPackageProvidesclassOn Fedora 43+,
repoqueryis no longer a standalone binary; it's a subcommand ofdnf5. The fact'srequires_commandreturns"repoquery", which generates a! command -v repoquery >/dev/nullguard that short-circuits the entire lookup. Result: virtual package provides are never resolved, anddnf.packagesalways tries to reinstall packages likeiotop(provided byiotop-c). There'sdnf-utilsthat providesrepoquerycommand, but that only solves half of the problem.On top of that, I think this code path also fails to account for situation where there are multiple packages that provide the same package as the one requested. Even with
repoqueryavailable as a standalone binary:To Reproduce
docker run -it fedora), keep it running, grab its IDpyinfra -vvv @docker/51ac0676abff dnf.packages iotop-iotop-cshould get installediotop-cdnf-utilson that containerpyinfra -vvv @docker/51ac0676abff dnf.packages iotop-wget2-wgetshould be installedwget2-wgetMeta
Installed via
uvin a local venv.