Package Management (dnf)
Skill Level: Intermediate
1. Overview
You have already been introduced to dnf and the fundamentals of package management. Now we’ll progress to the more sophisticated capabilities of dnf and management of the repositories that back the highlevel tools.
2. Getting Started
For these exercises, you will be using the host node1
as user root
.
From host bastion
, ssh to node1
.
ssh node1
Use sudo
to elevate your privileges.
[[ "$UID" == 0 ]] || sudo -i
Verify that you are on the right host for these exercises.
workshop-dnf-checkhost.sh
You are now ready to proceed with these exercises.
3. More About dnf
3.1. Search
Not every tool is delivered in it’s own unique rpm package. Tools are often bundled into collective packages under a common name (category).
For example, let’s try to running the utility command called netstat.
netstat -tulpn
-bash: netstat: command not found
As you can tell, the netstat utility is missing from our platform. If you try to install the netstat package, you’ll discover that no such package exists.
So in order to track down which package contains our specified tool, we use the provides subcommand.
dnf provides netstat
net-tools-2.0-0.72.20160912git.el10.x86_64 : Basic networking tools Repo : rhel-10-for-x86_64-baseos-beta-rpms Matched from: Filename : /usr/bin/netstat net-tools-2.0-0.73.20160912git.el10.x86_64 : Basic networking tools Repo : rhel-10-for-x86_64-baseos-beta-rpms Matched from: Filename : /usr/bin/netstat
From this we can determine that a package called 'net-tools' provides the requested utility. So let us proceed to install it.
dnf install -y net-tools
netstat -tulpn
Great, it works!
3.2. Repo Query & Dependencies
Packages often (ie: the majority of the time) have dependencies on other additional packages which are required for a successful installation. Resolving those dependencies is one of the core fuctions of dnf.
In order to explore dependencies, we will use a nice little subcommand called repoquery which is equivalent to 'rpm -q'. With the added flag --requires you can quickly determine what additional packages are needed by a specified package.
Let us begin by getting information about a package called 'ncurses'
dnf info ncurses
What other packages does this depend on.
dnf repoquery --depends ncurses
Last metadata expiration check: 0:01:53 ago on Thu 01 May 2025 03:03:26 PM UTC. libc.so.6()(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3)(64bit) libc.so.6(GLIBC_2.3.4)(64bit) libc.so.6(GLIBC_2.33)(64bit) libc.so.6(GLIBC_2.34)(64bit) libc.so.6(GLIBC_2.4)(64bit) libc.so.6(GLIBC_2.7)(64bit) libc.so.6(GLIBC_ABI_DT_RELR)(64bit) libtic.so.6()(64bit) libtinfo.so.6()(64bit) ncurses-libs(x86-64) = 6.4-13.20240127.el10 ncurses-libs(x86-64) = 6.4-14.20240127.el10 rtld(GNU_HASH)
How about the other way around, what other packages have a dependency on ncurses.
dnf repoquery --whatdepends ncurses
frr-0:10.1-10.el10.x86_64 frr-0:10.1-3.el10.x86_64 frr-0:10.1-7.el10.x86_64 perl-Term-Cap-0:1.18-510.el10.noarch perl-Term-Cap-0:1.18-511.el10.noarch varnish-0:7.4.2-4.el10.x86_64 varnish-0:7.6.0-3.el10.x86_64 varnish-0:7.6.1-2.el10.x86_64
(NOTE: this output may differ from your result depending on what packages are available) From this ouptut you can determine what other tools are impacted if you were to attempt a dnf remove or dnf upgrade of ncurses.
3.3. Aliases
Aliases allow the user to abbreviate longer command sequences with short names (in the form <name=value>).
For example, if you’re tired of typing all the characters in dnf list and preferred dnf ls then you would create an alias like this.
dnf alias add ls=list
dnf ls
Well that’s kind of interesting but a pretty lame example. The real value comes when adding options to the command which vary from the defaults.
Let’s create an alias li to use as a substitute for list --installed but we’ll use a repoquery to change the output format.
dnf alias add li='repoquery --installed --qf %{installtime}\t%{vendor}\t%{arch}\t%{name}-%{version}'
dnf li
2025-03-11 22:55 Koji x86_64 gdbm-1.23 2025-03-11 22:55 Koji x86_64 gdbm-libs-1.23 2025-03-11 22:55 Red Hat, Inc. noarch appstream-data-10 2025-03-11 22:55 Red Hat, Inc. noarch basesystem-11 2025-03-11 22:55 Red Hat, Inc. noarch ca-certificates-2024.2.69_v8.0.303 2025-03-11 22:55 Red Hat, Inc. noarch crontabs-1.11^20190603git9e74f2d 2025-03-11 22:55 Red Hat, Inc. noarch crypto-policies-20250214 2025-03-11 22:55 Red Hat, Inc. noarch dbus-common-1.14.10 2025-03-11 22:55 Red Hat, Inc. noarch dnf-plugins-core-4.7.0 2025-03-11 22:55 Red Hat, Inc. noarch efi-filesystem-6 2025-03-11 22:55 Red Hat, Inc. noarch elfutils-default-yama-scope-0.192 2025-03-11 22:55 Red Hat, Inc. noarch fonts-filesystem-2.0.5 2025-03-11 22:55 Red Hat, Inc. noarch hwdata-0.379 2025-03-11 22:55 Red Hat, Inc. noarch initscripts-service-10.26
Or, how about an alias for listing the available packages
dnf alias add la='repoquery --available --qf %{reponame}\t%{arch}\t%{name}-%{version}'
dnf la
rhel-10-for-x86_64-appstream-beta-rpms noarch NetworkManager-config-connectivity-redhat-1.48.10 rhel-10-for-x86_64-appstream-beta-rpms noarch NetworkManager-config-connectivity-redhat-1.51.5 rhel-10-for-x86_64-appstream-beta-rpms noarch NetworkManager-config-connectivity-redhat-1.51.6 rhel-10-for-x86_64-appstream-beta-rpms noarch NetworkManager-config-connectivity-redhat-1.51.90 rhel-10-for-x86_64-appstream-beta-rpms noarch NetworkManager-config-connectivity-redhat-1.52.0 rhel-10-for-x86_64-appstream-beta-rpms noarch WALinuxAgent-2.9.1.1 rhel-10-for-x86_64-appstream-beta-rpms noarch WALinuxAgent-udev-2.9.1.1 rhel-10-for-x86_64-appstream-beta-rpms noarch adobe-mappings-cmap-20230622 rhel-10-for-x86_64-appstream-beta-rpms noarch adobe-mappings-cmap-deprecated-20230622 rhel-10-for-x86_64-appstream-beta-rpms noarch adobe-mappings-pdf-20190401 rhel-10-for-x86_64-appstream-beta-rpms noarch adwaita-cursor-theme-46.0 rhel-10-for-x86_64-appstream-beta-rpms noarch adwaita-icon-theme-46.0 rhel-10-for-x86_64-appstream-beta-rpms noarch alsa-firmware-1.2.4 rhel-10-for-x86_64-appstream-beta-rpms noarch alsa-sof-firmware-2024.03 <...output truncated...>
Here is how you see the list of the configured aliases.
dnf alias list
Alias ls='list' Alias li='repoquery --installed --qf %{installtime}\t%{vendor}\t%{arch}\t%{name}-%{version}' Alias la='repoquery --available --qf %{reponame}\t%{arch}\t%{name}-%{version}'
And lastly, how to delete an alias.
dnf alias delete la
3.4. Groups
Package groups are defined in the repository. Red Hat creates a few package groups in the distribution ISOs in order to make installations a little more covenient and consistent.
To see a list of available group names
dnf grouplist
Available Environment Groups: Server with GUI Server Minimal Install Workstation Virtualization Host Custom Operating System Available Groups: Container Management .NET Development Console Internet Tools RPM Development Tools System Tools
To install a group you use the groupinstall command. Since we are not interested in installing anything for this workshop, we’ll use the test flags that were introduced in the fundamentals unit.
dnf groupinstall "RPM Development Tools" -y --setopt tsflags=test
<...output truncated...> (28/30): unzip-6.0-68.el10.x86_64.rpm 2.1 MB/s | 194 kB 00:00 (29/30): zip-3.0-44.el10.x86_64.rpm 2.5 MB/s | 274 kB 00:00 (30/30): systemd-rpm-macros-257-9.el10_0.1.noarch.rpm 143 kB/s | 22 kB 00:00 ----------------------------------------------------------------------------------- Total 4.7 MB/s | 6.4 MB 00:01 Running transaction check Transaction check succeeded. Running transaction test Transaction test succeeded. Complete! The downloaded packages were saved in cache until the next successful transaction. You can remove cached packages by executing 'dnf clean packages'.
You could just as easily use the groupremove command to uninstall the package collection.
4. Repositories
DNF operates on the concept of package repositories, commonly referred to as repos.
-
System can have a single or many repos configured
Repos typically fall into 2 categories:
-
Traditional - static pool of packages organized into structured filesystem for local or remote access
-
Managed / Service - service that provides dynamic managed repos (ex: Red Hat Satellite)
4.2. Add Repo
Repo configuration files are stored in /etc/yum.repos.d/
Creating a repo config can be done:
-
by hand,
-
by using the dnf config-manager, or
-
by installing a package that contains the repo config (most common).
Installing a package with the repo config often has the added advantage of installing keys which validate sources and improve security of your host.
A common repo to add to RHEL development systems is EPEL. This repository (Extra Packages for Enterprise Linux) contains packages from the Fedora development community which have been compiled and verified for installation on RHEL. Software from EPEL offers a path to trying new things on RHEL which would not otherwise be possible.
The packages from EPEL are COMMUNITY SUPPORT ONLY!!! We are using EPEL for example purposes only. |
Let’s add the EPEL repo to our RHEL 10 host.
dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm
dnf repolist
Updating Subscription Management repositories. repo id repo name epel Extra Packages for Enterprise Linux 10 - x86_64 rhel-10-for-x86_64-appstream-beta-rpms Red Hat Enterprise Linux 10 for x86_64 - AppStream Beta (RPMs) rhel-10-for-x86_64-baseos-beta-rpms Red Hat Enterprise Linux 10 for x86_64 - BaseOS Beta (RPMs)
Now let’s list all of the repos provided with configuration we just installed. Notice how most of the repos are disabled. Should you need to install something from epel-testing repo, you could temporarily enable a repo by adding the --enable-repo=<name> flag to most dnf operations.
dnf repolist --all 'epel*'
Updating Subscription Management repositories. repo id repo name status epel Extra Packages for Enterprise Linux 10 - x86_64 enabled epel-debuginfo Extra Packages for Enterprise Linux 10 - x86_64 - Debug disabled epel-source Extra Packages for Enterprise Linux 10 - x86_64 - Source disabled epel-testing Extra Packages for Enterprise Linux 10 - Testing - x86_64 disabled epel-testing-debuginfo Extra Packages for Enterprise Linux 10 - Testing - x86_64 - Debug disabled epel-testing-source Extra Packages for Enterprise Linux 10 - Testing - x86_64 - Source disabled
dnf repolist --all 'epel*' --enablerepo=epel-testing
Updating Subscription Management repositories. repo id repo name status epel Extra Packages for Enterprise Linux 10 - x86_64 enabled epel-debuginfo Extra Packages for Enterprise Linux 10 - x86_64 - Debug disabled epel-source Extra Packages for Enterprise Linux 10 - x86_64 - Source disabled epel-testing Extra Packages for Enterprise Linux 10 - Testing - x86_64 enabled epel-testing-debuginfo Extra Packages for Enterprise Linux 10 - Testing - x86_64 - Debug disabled epel-testing-source Extra Packages for Enterprise Linux 10 - Testing - x86_64 - Source disabled
List the available pacakges from the EPEL repo
dnf list --available --repo epel
4.3. Disable Repo
Just like you can enable a repo temporarily, you can disable a repo temporarily as well.
dnf repolist --all 'epel*' --disablerepo=epel
For something more permanent, you can use config-manager to set the repo disabled.
dnf config-manager --set-disabled epel
dnf repolist --all 'epel*'
Or you could edit the config file manually to flip the enabled flag.
5. Conclusion
This concludes the unit.
Time to finish and return the shell to its home position.
workshop-finish-exercise.sh