DNF Package Management

Linux
Published

November 23, 2013

Modified

October 10, 2023

Commands

dnf 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 & erase

dnf install <package>
dnf downgrade <package>
dnf erase <package>

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

The level of support for security advisories depends on the upstream distribution. The dnf command supports multiple options to limit operation on security related packages:

Option Description
--advisories= Include packages corresponding to the advisory ID
--cve= Include packages that fix a CVE
--security Includes packages that provide a fix for a security issue
--sec-severity= Includes packages that provide a fix for an issue of the specified severity

List security updates (examples show security advisories):

dnf updateinfo                              # show counts for security updates
dnf updateinfo list                         # list all advisories
dnf updateinfo list cves                    # list all CVEs
dnf updateinfo list --sec-severity Critical # ^ with a severity level
dnf updateinfo --info RLSA-2022:176         # show a specific advisories
dnf upgrade --security                      # upgrade packages with security advisories
dnf upgrade --advisory=RLSA-2022:332        # upgrade only a specific advisory

Determining whether any security updates are available for a package. Following example uses glibc a core library used by almost every binary on the system:

# 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
# see what version is available and if it updates anything important
>>> 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
# update glibc based on the errata
>>> dnf upgrade --advisory=RLSA-2021:4358

Automatic Updates

Reasons against using automatic updates [^05] on nodes include the following:

  • It provides a critical service that you don’t want to risk having unscheduled downtime.
  • You installed custom software, compiled software from source, or use third party software that has strict package version requirements.
  • You installed a custom kernel, custom kernel modules, third party kernel modules, or have a third party application that depends on kernel versions (this may not be a problem if you exclude kernel updates, which is configurable in dnf.conf files)
  • Your environment requires meticulous change-control procedures.
  • You update from other third party DNF repositories which may conflict in versioning schemes for the same packages.
  • Unwanted side effects. Some packages can create annoying side effects, particularly ones which have cron jobs. Updates to base packages like openssl, openldap, sql servers, etc. can have an effect on many other seemingly unrelated packages.
  • Bugs. Many packages contain buggy software or installation scripts. The update may create problems during or after installation.

Enable DNF Automatic [^01] 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
# check if the nodes requires a reboot after package updates
>>> dnf needs-restarting

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 (i.e. wallclock) timers with calendar event expressions
  • RandomizedDelaySec delays the timer by a randomly selected, evenly distributed 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. This could be mitigated by configuring a higher scheduling police for dnf-automatic. Alternatively use a tool like dcmrp [^03] to prevent a corrupted package database.

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.*

References

[^01] DNF Automatic
https://dnf.readthedocs.io/en/latest/automatic.html

[^02] DNF Configuration Reference
http://dnf.readthedocs.org/en/latest/conf_ref.html

[^03] Tool to Correct RPM Database Corruption, Facebook
https://github.com/facebookincubator/dcrpm

[^04] DNF Package manager for RPM based distributions
https://dnf.readthedocs.io
https://github.com/rpm-software-management/dnf

[^05] Fedora Documentation - Automatic Updates
https://docs.fedoraproject.org/en-US/quick-docs/autoupdates

[^07] RPM Package Manager Project Page
https://rpm.org

[^09] Basic Yum Commands
http://yum.baseurl.org/wiki/YumCommands.html