This article showcases rpmdistro-repoquery, and describes how to use it to simplify doing RPM-based package operations across multiple distributions. This does not require using SSH to log into another host or starting a container or VM.
Whether you’re a packager, system administrator, or a user of Fedora Linux, CentOS Stream, or their derivatives (RHEL, AlmaLinux, Rocky Linux etc.), you might already be familiar with dnf repoquery. This tool allows you to query the repositories configured on the system for information about available packages, whether or not they are currently installed on the local machine.
This is great, within limits. For instance, on Fedora Linux, you can query packages built for stable and branched Fedora Linux releases and, if you install fedora-repos-rawhide, packages in the development branch. Sufficient care is required to make sure you don’t enable repos meant for different Fedora Linux releases by default and thus accidentally upgrade the running system.
Enter rpmdistro-repoquery: it comes with a set of repo definitions for different RPM-based distributions, but instead of putting them in /etc/yum.repos.d with the repositories meant for actual use, put them in /usr/share/rpmdistro-repoquery (or, if you so choose, you can clone the repository and use definitions that come in the checkout). DNF is then invoked with a custom configuration file and a custom cache location that points at one of the repos for one of the distributions rather than the default location.
The various supported distributions come with the relevant repositories enabled by default. Some have additional repositories that need to be enabled explicitly. For example, source repos are off by default. Also, CentOS Stream configurations come with additional repos for SIG packages that are off by default.
This opens up a lot of use cases. I highlight some of them below.
Note: The primary author of this tool, Neal Gompa, works on a lot of RPM-based Linux distributions. I became involved using it in ebranch.
Real-life rpmdistro-repoquery use cases
Quickly seeing if a CentOS Stream update has made it to the mirrors
In Fedora’s build system, updates go through Bodhi, and once they are marked testing or stable that means there is a compose containing those updates, and they tend to hit mirrors shortly after.
In CentOS Stream, the situation is more complicated, as the QA process is not visible to the public. Take clang for example: given a commit, and a matching Koji build on January 27th, can we be sure this is pushed out to the mirrors?
It turns out, as of February 9th, it’s not in the mirrors yet:
$ rpmdistro-repoquery centos-stream 9 clang 2>/dev/null clang-0:14.0.0-1.el9.i686 clang-0:14.0.0-1.el9.x86_64 clang-0:14.0.5-1.el9.i686 clang-0:14.0.5-1.el9.x86_64 clang-0:14.0.6-1.el9.i686 clang-0:14.0.6-1.el9.x86_64 clang-0:15.0.1-2.el9.i686 clang-0:15.0.1-2.el9.x86_64 clang-0:15.0.7-2.el9.i686 clang-0:15.0.7-2.el9.x86_64
Comparing what is packaged in different distributions
Scenario: you use / manage a heterogeneous fleet of different distributions. You want to find out if all the packages you need are available (because you might need to package what’s missing).
Let’s see if myrepos is available on openSUSE Tumbleweed (the rolling distribution):
$ rpm -q myrepos myrepos-1.20180726-14.fc37.noarch $ rpmdistro-repoquery opensuse-tumbleweed 0 myrepos $ rpmdistro-repoquery opensuse-tumbleweed 0 /usr/bin/mr mr-0:1.20180726-1.9.noarch
Searching by the Fedora Linux package name yields nothing, but in this case, searching by the binary shows a match (since those are in the RPM metadata): myrepos is available, but you’ll need a different package name in your configuration management.
This is a special case of the former. ebranch is a tool for branching Fedora Linux packages for EPEL.
Given that CentOS Stream (and its downstreams, such as Red Hat Enterprise Linux, AlmaLinux and Rocky Linux) only carries the subset of Fedora Linux packages that Red Hat is committed to supporting, EPEL provides a way for the community to maintain additional packages built against RHEL (or CentOS Stream).
A major problem here is dealing with dependency hell: a missing package might have several missing dependencies, which in turn have more missing dependencies… Getting retsnoop in EPEL 9 involves branching 189 packages in total!
ebranch utilizes rpmdistro-repoquery to compare what is available in Rawhide (rpmdistro-repoquery fedora rawhide) with what is available in CentOS Stream + EPEL (rpmdistro-repoquery centos-stream-legacy 8 and rpmdistro-repoquery centos-stream 9) to build up a transitive closure of missing dependencies and report on any dependency loops. ebranch also computes a chain build order for the missing dependencies, grouping packages that can be built in parallel.
Checking the impact of a soname bump
With rpmdistro-repoquery, finding the delta between any two distribution releases that it supports is trivial:
$ comm <(rpmdistro-repoquery fedora rawhide \ --provides libkdumpfile >/dev/null) \ <(rpmdistro-repoquery centos-stream 9 \ --provides libkdumpfile >/dev/null) libaddrxlat.so.2()(64bit) libaddrxlat.so.2(LIBADDRXLAT_0)(64bit) libaddrxlat.so.3 libaddrxlat.so.3()(64bit) libaddrxlat.so.3(LIBADDRXLAT_0) libaddrxlat.so.3(LIBADDRXLAT_0)(64bit) libkdumpfile = 0.4.1-5.el9 libkdumpfile = 0.5.0-3.fc38 libkdumpfile(x86-32) = 0.5.0-3.fc38 libkdumpfile(x86-64) = 0.4.1-5.el9 libkdumpfile(x86-64) = 0.5.0-3.fc38 libkdumpfile.so.10 libkdumpfile.so.10()(64bit) libkdumpfile.so.10(LIBKDUMPFILE_0) libkdumpfile.so.10(LIBKDUMPFILE_0)(64bit) libkdumpfile.so.9()(64bit) libkdumpfile.so.9(LIBKDUMPFILE_0)(64bit)
And likewise, finding the blast radius of said update:
$ rpmdistro-repoquery centos-stream 9 \ --whatrequires "libaddrxlat.so.2()(64bit)" libkdumpfile-devel-0:0.4.1-5.el9.x86_64 libkdumpfile-util-0:0.4.1-5.el9.x86_64 python3-libkdumpfile-0:0.4.1-5.el9.x86_64 $ rpmdistro-repoquery centos-stream 9 \ --whatrequires "libkdumpfile.so.9()(64bit)" drgn-0:0.0.22-1.el9.x86_64 libkdumpfile-devel-0:0.4.1-5.el9.x86_64 libkdumpfile-util-0:0.4.1-5.el9.x86_64 python3-libkdumpfile-0:0.4.1-5.el9.x86_64 $ rpmdistro-repoquery centos-stream-legacy 8 \ --whatrequires "libaddrxlat.so.2()(64bit)" libkdumpfile-devel-0:0.4.1-5.el8.x86_64 libkdumpfile-util-0:0.4.1-5.el8.x86_64 python3-libkdumpfile-0:0.4.1-5.el8.x86_64 $ rpmdistro-repoquery centos-stream-legacy 8 \ --whatrequires "libkdumpfile.so.9()(64bit)" drgn-0:0.0.22-1.el8.x86_64 libkdumpfile-devel-0:0.4.1-5.el8.x86_64 libkdumpfile-util-0:0.4.1-5.el8.x86_64 python3-libkdumpfile-0:0.4.1-5.el8.x86_64
Building OS images
mkosi is a tool for generating OS images; currently it contains the logic for different distributions (e.g. Fedora, CentOS), but this makes it hard to, for example, build an image for CentOS SIGs such as Hyperscale.
With Daan De Meyer’s refactor rpmdistro-repoquery’s repo files can now be reused by mkosi so in the future, tailoring what repositories are used to build an OS image should be much easier.
The contributors for this tool have found it very useful in our Linux distribution work, and we hope this article can help introduce it to others who likewise find it useful.
Please try it yourself — on Fedora Linux, and on any CentOS Stream or derivatives with EPEL enabled, simply do:
$ sudo dnf install rpmdistro-repoquery
If the distro you want to work with is not supported, pull requests are welcome! Likewise with suggestions or requests. If you want to package rpmdistro-repoquery in a different distribution, feel free to use the Fedora packaging as reference.