DNF: RPM Package Management

Linux
Published

November 23, 2013

Modified

January 7, 2025

Usage

dnf1 is a command line interface for package management on Enterprise Linux…

  • …successor to and mostly compatible with yum use until RHEL 8
  • Both are front-ends to rpm to ease package installation for repositories

repolist & repoquery

DNF connects with all repositories defined in /etc/yum.repos.d/

# ...list all repositories
dnf repolist -v all

# ...list enabled repos only
dnf repolist enabled

# .list all packages in a repository
dnf repo-pkgs $repo_name list

repoquery searches for selected packages…

  • -l/--list …list of files in the package
  • -f/--file …limit the resulting set only to the package that owns
# list files within a package
dnf repoquery -l $package_name

# ...display package name that owns the given file
dnf repoquery -f $absolute_path

install & remove

Removes the specified packages …along with any packages depending on the packages …specify packages with <package-spec>

# remove a specific kernel package from the system
dnf remove -y \
      kernel-5.14.0-503.15.1.el9_5 \
      kernel-core-5.14.0-503.15.1.el9_5 \
      kernel-devel-5.14.0-503.15.1.el9_5 \
      kernel-headers-5.14.0-503.15.1.el9_5 \
      kernel-modules-5.14.0-503.15.1.el9_5 \
      kernel-modules-core-5.14.0-503.15.1.el9_5 \
      kernel-tools-5.14.0-503.15.1.el9_5 \
      kernel-tools-libs-5.14.0-503.15.1.el9_5

makecache

DNF maintains a local copy of repository data, aka metadata …directory /var/cache/dnf stores all cache files & metadata

Update and clean metadata

  • …sub-commands will automatically re-sync the metadata if it is expired
  • --refresh forces synchronization of all enabled repositories
# ...update metadata for the currently enabled repositories
dnf makecache

# ...delete all package repository metadata
dnf clean metadata

# ...clean up all the repository metadata & caches
dnf clean all

HTTP Squid proxies require a configuration to avoid caching of the repository metadata

  • …typically excluding repomd.xml files from being cached at all
  • …achieved by configuring the Squid service to not cache URLs with a pattern like
^http:\/\/mirror\.example\.org\/\w+\/[0-9]+.[0-9]+\/repodata\/\w+-\w+\.(xml|xml\.gz|sqlite\.bz2)

search & list

dnf subcommands to find and inspect packages…

  • search <package>…package by name
  • list <package>
  • list installed shows all installed packages
  • list recent
  • list --showduplicates ... list all versions of packages
  • info <package> shows package metadata
  • deplist <package>…dependencies of a package
  • provides <glob> find which package includes a file i.e. '*bin/bash'

Compare the packages installed on two nodes:

dnf-diff() {
        cmd="dnf list installed | tail -n +2 | xargs -n3 | cut -d' ' -f1,2"
        diff --side-by-side --suppress-common-lines \
                <(ssh root@$1 -C $cmd) <(ssh root@$2 -C $cmd)
}

group

Groups are virtual collections of packages…

dnf group                        # number of available/installed package groups
dnf group list --installed       # list installed groups
dnf group info <group>           # show package in a group

Group IDs…

  • --ids options lists group IDs
  • …use the @<group> notation to install with dnf install
>>> dnf group list --ids | grep development
   Development Tools (development-tools)
   C Development Tools and Libraries (c-development)
   D Development Tools and Libraries (d-development)
   RPM Development Tools (rpm-development-tools)
# install a group using the `@` prefix
>>> dnf install @development-tools

check-update & upgrade

check-update checks whether any updates at all are available for your system

  • list of the updates will be printed
  • …exit code will be 100 when there are updates available
  • …option --changelogs to print changes
dnf check-update
dnf check-update --changelogs $package_name

# ...alterantive way to list packages with updates
dnf repoquery --upgrades

updateinfo display information about update advisories

# ...displays just counts of advisory types
dnf updateinfo

# ...list of advisories
dnf updateinfo --list

# ...advisories details on a specific package
dnf updateinfo --info $package_name

upgrade packages to a new version…

# ...update each package to the latest version
dnf upgrade

# ...update a specific package
dnf upgrade $package_name

clean & autoremove

## ...clean up...
dnf list autoremove
dnf autoremove -y
dnf clean packages
dnf clean expire-cache

Transaction History

DNF keeps a running history of every command and transaction that it executes.

dnf history presents a table with following columns:

>>> dnf history
ID     | Command line             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
    32 | update                   | 2022-06-20 06:20 | C, E, I, O, U  |  114 EE
    31 | update -y                | 2022-06-13 06:53 | C, E, I, U     |   97 EE
    30 | install -y buildah       | 2022-06-10 13:10 | Install        |    1
    29 | install -y vagrant       | 2022-06-10 06:55 | Install        |   52
    28 | install -y gcc binutils  | 2022-06-10 06:53 | Install        |    1 EE
    27 | install kernel-devel     | 2022-06-10 06:52 | Install        |    7
    26 | install VirtualBox-6.1.x | 2022-06-10 06:50 | Install        |    2 E<
    25 | update                   | 2022-06-09 06:50 | Upgrade        |    3 >
    24 | update                   | 2022-06-08 06:09 | Upgrade        |   18
  • ID unique identifying number for each transaction
  • Command used to start the transaction
  • Execution date and time…
  • List of actions dnf took to complete the transaction
  • Number of packages alter followed with detail code

Actions & Error Codes

Possible action executed in the transaction:

Value Action Description
I Install Package(s) installed.
U Update Package(s) updated to a newer version.
E Erase Package(s) removed.
D Downgrade Package(s) downgraded to an older version.
O Obsoleting Package(s) marked as obsolete.
R Reinstall Package(s) reinstalled.

The number of altered packages can be followed by a code:

Value Description
< rpmdb database changed before the transaction ending
> rpmdb database changed after the transaction ended
* The transaction aborted before completion.
# Finished successfully…dnf returned a non-zero exit code
E Finished successfully…error or a warning was displayed
P Finished successfully…problems already existed in rpmdb database
s Finished successfully, -–skip-broken command-line was used…

history

List of sub-commands for dnf history:

  • list last show last transaction…
  • list last-x where x number of transaction ago
  • list <id> specify the ID…
  • list <sid>...<eid> range of IDs
  • info <id> examine a particular transaction in details
  • undo <id> revert a transaction (uninstall,downgrade)
  • redo <id> re-apply a transaction

Security Updates

dnf options to limit operation on security related packages:

  • --advisories= — packages corresponding to the advisory ID
  • --cve= — packages that fix a CVE
  • --security — packages that provide a fix for a security issue
  • --sec-severity= — packages that provide a fix for an issue of the specified severity

List security updates:

dnf updateinfo             # show counts for security updates
dnf updateinfo list        # list all advisories
dnf updateinfo list cves   # list all CVEs

# ^ with a severity level
dnf updateinfo list --sec-severity Critical

# show a specific advisories (for RockyLinux in this example)
dnf updateinfo --info RLSA-2022:176

Updates limited to security:

# upgrade (only) packages with security advisories
dnf upgrade --security

# upgrade packages related to a specific advisory
dnf upgrade --advisory=RLSA-2022:332

Determining whether any security updates are available for a package:

# Example: What version of glibc is installed?
>>> rpm -qa | grep glibc
glibc-langpack-en-2.28-151.el8.x86_64
glibc-common-2.28-151.el8.x86_64
glibc-headers-2.28-151.el8.x86_64
glibc-devel-2.28-151.el8.x86_64
glibc-2.28-151.el8.x86_64

# …check if a security advisory is available
>>> dnf updateinfo list | grep glibc
RLSA-2021:4358 Moderate/Sec.  glibc-2.28-164.el8.x86_64
RLSA-2021:4358 Moderate/Sec.  glibc-common-2.28-164.el8.x86_64
RLSA-2021:4358 Moderate/Sec.  glibc-devel-2.28-164.el8.x86_64
RLSA-2021:4358 Moderate/Sec.  glibc-headers-2.28-164.el8.x86_64
RLSA-2021:4358 Moderate/Sec.  glibc-langpack-en-2.28-164.el8.x86_64

Automatic Updates

Reasons against using automatic updates2 on nodes include the following:

  • …critical service …risk having unscheduled downtime
  • …custom software with strict package version requirements
  • …custom kernel, kernel modules, or application that depends on kernel versions
  • …environment that require meticulous change-control procedures
  • …third party RPM repositories that may conflict in versioning schemes
  • …unwanted side effects …(core) packages like openssl, openldap, databases, etc. can have an effect on many other seemingly unrelated packages

Enable DNF Automatic3 in case continues upgrade of packages is required:

# install the package
dnf install -y dnf-automatic

# enable automatic package installation in the configuration
>>> grep updates /etc/dnf/automatic.conf 
download_updates = yes
apply_updates = yes

# enable the service unit
systemctl enable --now dnf-automatic-install.timer
systemctl list-timers dnf-*

# check if updates are applied
dnf history

The default configuration as follows:

>>> systemctl cat dnf-automatic-install.{timer,service}
# /usr/lib/systemd/system/dnf-automatic-install.timer
...
[Timer]
OnCalendar=*-*-* 6:00
RandomizedDelaySec=60m
Persistent=true
...
# /usr/lib/systemd/system/dnf-automatic-install.service
...
[Service]
Type=oneshot
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
Environment="ABRT_IGNORE_PYTHON=1"
ExecStart=/usr/bin/dnf-automatic /etc/dnf/automatic.conf --timer --installupdates
...

The timer executes every day at 6am with a maximum delay of 1 hour:

  • OnCalendar real time timers with calendar event expressions
  • RandomizedDelaySec delays the timer by a randomly selected amount

The service unit will configure very low priority for CPU cycles and IO by default:

  • Nice Sets the default nice level (scheduling priority) for executed processes. Takes an integer between -20 (highest priority) and 19 (lowest priority).
  • IOSchedulingClass Sets the I/O scheduling class for executed processes. Takes an integer between 0 and 3 or one of the strings none, realtime, best-effort or idle.
  • IOSchedulingPriority Sets the I/O scheduling priority for executed processes. Takes an integer between 0 (highest priority) and 7 (lowest priority). The available priorities depend on the selected I/O scheduling class (see above).

Package upgrade on nodes under heavy load may not finish the transaction and leave the local package database in an corrupted state.

  • …mitigate by configuring a higher scheduling police for dnf-automatic
  • …use a tool like dcmrp4 to prevent a corrupted package database
  • Note: Recent version of dnf are more robust concerning this issue

Pending Reboots

Identify packages that will require a system reboot after an update…

  • …typical examples include kernel*, systemd, glibc, udev, dbus
  • linux-firmware after microcode_ctl update

The needs-restarting sub-commands…

  • …determines whether the system should be rebooted:
  • …exit with code 1 if a reboot is recommended
# only report whether a reboot is required
dnf needs-restarting -r

# list affected systemd services that require restart
dnf needs-restarting -s

Version Lock

versionlock excludes packages from updates

In install the DNF plugin…

dnf install -y python3-dnf-plugin-versionlock

Basic commands…

# ...list all packages in version lock
dnf versionlock list

# ...remove all versionlock entries
dnf versionlock clear

Configuration

Configuration in /etc/dnf/plugins/versionlock.conf

  • …should contain main sections with enabled and locklist parameters
  • locklist …file which has the versionlock information
[main]
enabled = 1
locklist = /etc/dnf/plugins/versionlock.list

List of version locks (by default) in /etc/dnf/plugins/versionlock.list

apptainer-1.1*
kernel-0:4.18.0-372.*
kernel-core-0:4.18.0-372.*
kernel-modules-0:4.18.0-372.*
kernel-tools-0:4.18.0-372.*
kernel-tools-libs-0:4.18.0-372.*
lustre-client-0:2.12.9*
kmod-lustre-client-0:2.12.9*
munge-0:0.5.13*
slurm*-21.08.*

Example

Example to version lock the kernel package…

# lock to the current version of the kernel package
>>> dnf versionlock add kernel
Adding versionlock on: kernel-0:4.18.0-348.12.2.el8_5.*
Adding versionlock on: kernel-0:4.18.0-348.20.1.el8_5.*

# ...prevents updates
>>> dnf update kernel
Dependencies resolved.
Nothing to do.
Complete!

Configuration files including a lock for the kernel package:

>>> tail -n+1 /etc/dnf/plugins/versionlock.* 
==> /etc/dnf/plugins/versionlock.conf <==
[main]
enabled = 1
locklist = /etc/dnf/plugins/versionlock.list
==> /etc/dnf/plugins/versionlock.list <==
# Added lock on Thu May  5 11:57:40 2022
kernel-0:4.18.0-348.12.2.el8_5.*
kernel-0:4.18.0-348.20.1.el8_5.*

Once the lock is removed an update is possible again:

# remove a lock
>>> dnf versionlock delete kernel
Deleting versionlock for: kernel-0:4.18.0-348.12.2.el8_5.*
Deleting versionlock for: kernel-0:4.18.0-348.20.1.el8_5.*

>>> dnf update kernel
Failed to set locale, defaulting to C.UTF-8
Last metadata expiration check: 0:30:44 ago on Thu May  5 11:31:10 2022.
Dependencies resolved.
======================================================================================================================
 Package                     Architecture        Version                             Repository                  Size
======================================================================================================================
Installing:
 kernel                      x86_64              4.18.0-348.23.1.el8_5               gsi-alma-base              7.0 M
Installing dependencies:
 kernel-core                 x86_64              4.18.0-348.23.1.el8_5               gsi-alma-base               38 M
 kernel-modules              x86_64              4.18.0-348.23.1.el8_5               gsi-alma-base               30 M

Transaction Summary
======================================================================================================================
Install  3 Packages

Total download size: 74 M
Installed size: 90 M
Is this ok [y/N]: n
Operation aborted.

This means that security patches to a specific Red Hat kernel version can be applied without breaking Lustre compatibility:

# allow updates to a specific kernel package for a given minor release
>>> dnf versionlock add --raw 'kernel-0:4.18.0-348.*'

Adding versionlock on: kernel-0:4.18.0-348.*
>>> cat /etc/dnf/plugins/versionlock.list 
kernel-0:4.18.0-348.*