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

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.

3.5. Clean

After a session of installing and/or upgrading packages, there can be quite a bit of leftover data using up your precious storage. To clean up the space, use the sub command 'clean'.

dnf clean all

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.1. List Repos

dnf repolist

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.

4.4. Remove Repo

Removing a repo is a pretty simple operation which can be done in a couple of ways:

  • remove (or rename) the config file in /etc/yum.repos.d

  • use dnf to remove the pkg which added the repo config

5. Conclusion

This concludes the unit.

Time to finish and return the shell to its home position.

workshop-finish-exercise.sh