Chapter 19. Software management
The following chapter contains the most notable changes to software management between RHEL 9 and RHEL 10.
19.1. Notable changes to DNF
The repository metadata is now not downloaded by default
Previously, when you downloaded a repository’s metadata, the filelists metadata was downloaded by default. The filelists metadata is large and is typically not needed. With this update, this metadata is not downloaded by default, which improves responsiveness and saves disk space. The filelists metadata is also no longer downloaded or updated from repositories and is not loaded into the DNF transaction when you run a dnf
command. If the dnf
command requires the filelists metadata or includes a file-related argument, the metadata is loaded automatically.
When a package has a filepath dependency that requires filelists metadata to be resolved, the transaction fails with a dependency resolution error and the following hint:
(try to add '--skip-broken' to skip uninstallable packages or '--setopt=optional_metadata_types=filelists' to load additional filelists metadata)
If you want to re-enable the default filelist metadata downloading, you can add the filelists
value to the optional_metadata_types
option in the /etc/dnf/dnf.conf
configuration file.
The DNF debug
plug-in has been removed
The DNF debug
plug-in, which included the dnf debug-dump
and dnf debug-restore
commands, has been removed from the dnf-plugins-core
package. Depending on your scenario, you can use the following commands instead:
-
dnf list --installed
ordnf repoquery --installed
to list packages installed on your system. -
dnf repolist -v
to list repositories enabled on your system. dnf install $(</tmp/list)
to replicate packages installed on a source system to the target system. For example:Save a list of packages installed on a source system into the
/tmp/list
file:$ dnf repoquery --installed >/tmp/list
-
Copy the
/tmp/list
file to the target system. Replicate packages on the target system:
$ dnf install $(</tmp/list)"
The support for the libreport
library has been removed
The support for the libreport
library has been removed from DNF. If you want to attach DNF logs to your bug reports, you need to do it manually or by using a different mechanism.
dnf-plugins-core
rebased to version 4.7.0
The dnf-plugins-core
package has been rebased to version 4.7.0 that provides a new python3-dnf-plugin-pre-transaction-actions
package. This package includes a new pre-transaction-actions
DNF plugin that allows you to execute a command upon starting an RPM transaction. For more information, see the dnf-pre-transaction-actions(8)
manual page on your system.
19.2. Notable changes to createrepo_c
Default createrepo_c
compression has changed from gzip
to Zstandard
The createrepo_c
command now compresses non-database metadata with the Zstandard
(zstd
) compression algorithm instead of gzip
. Note that the database metadata still defaults to the bzip2
format. You can override the compression format by using the --general-compress-type
option.
SQLite databases are now not generated by default
To save disk space, the createrepo_c
command no longer creates SQLite databases next to XML files. You can explicitly create the databases by using the --database
option.
Support for creating the SQLite databases with the createrepo --databases
command is deprecated and will be removed in future RHEL major versions.
19.3. Notable changes to RPM
Red Hat Enterprise Linux 10 is distributed with RPM version 4.19. This version introduces many enhancements over its previous versions.
19.3.1. Improved user experience and security
A new rpmlua
command-line tool
This tool runs the RPM Lua interpreter in a standalone way that you can use for the development and testing of Lua scriptlets and macros. For more information, see the rpmlua(8)
man page on your system.
A new rpmsort
command-line tool
This tool allows you to sort RPM versions passed on standard input, similar to sort(1)
but with the awareness of RPM versioning scheme. For more information, see the rpmsort(8)
man page on your system.
A new dbus-announce
plug-in
This plug-in writes basic information about RPM transactions to the system D-Bus, for example, when packages are installed or removed. Other programs can subscribe to these signals to be notified of such events.
Downgrade support in --freshen
mode
Previously, you could use the --freshen
option only to upgrade packages that were already installed and skip packages that were not installed. With this enhancement, you can also use this operation to downgrade such packages. To do this, combine the --freshen
(F
) option with the --oldpackage
option.
19.3.2. Improved packaging experience
Support for dynamic spec
generation
You can now add subpackages during the build process by placing files containing spec
parts into a predefined location. For more information, see Dynamic Spec Generation.
A new --shell
option in the rpmspec
command-line tool
This option runs an interactive RPM macro interpreter that you can use for the development and testing of RPM macros, either in or outside of the context of a spec
file. For more information, see the rpmspec(8)
man page on your system.
Support for applying individual patches in %autopatch
You can now list specific patch numbers as positional arguments, for example, %autopatch 1 4 6
to apply patch numbers 1, 4 and 6.
Proper shell-like globbing and escaping in the %files
section
Wildcard patterns and escaping characters, such as backslashes and quotes, in filenames are now interpreted in a more conventional way, mirroring the behavior of shell interpreters such as Bash. Previously, undocumented limitations and exceptions to these rules could have unexpected results and could prevent the use of more complex patterns in the %files
section of a spec
file.
A new tag in source RPM packages containing the parsed and expanded contents of the spec
file
To help with analyzing packaging issues, a new RPMTAG_SPEC
tag is now added to source RPM packages. This tag includes the contents of the expanded spec
file in the form used during the build. You can view this tag by executing the rpm --qf ‘%{spec}’ -q /path/to/my/src.rpm
command.
Build parallelism now considers system resources
RPM now considers the available physical memory and address space when estimating the number of parallel processes and threads to use when building packages. This helps to prevent performance issues or build failures on systems with constrained resources, such as systems with a large number of CPUs but a limited amount of memory.
You can adjust these estimates by specifying the amount of memory a single process or thread is assumed to require for your build by defining the %_smp_tasksize_proc
and %_smp_tasksize_thread
macros, respectively. Both macros have the default value of 512 MB. For example, if your system has performance issues, you can increase these values for RPM to allocate fewer CPUs for the build. Likewise, if your system is underutilized, you can decrease these values for RPM to allocate more CPUs.
For more information, see Macros for controlling build parallelism.
Payload compression with zstd
now supports multi-threading
The zstdio
compression method now accepts an optional T
parameter that specifies the number of threads to use when compressing payload during the build. This can help reduce the build time of large packages. To enable this feature, set the %_binary_payload
and %_source_payload
macros accordingly. For more information, see the associated comment block in the /usr/lib/rpm/macros
file and the expected format table.
A new optional %conf
spec
file section
You can use this section to configure the unpacked sources for building instead of configuring them in the %prep
or %build
sections of a spec
file.
Lua-native macro integration
The embedded Lua interpreter has been updated to include the following enhancements:
Easy access to options and arguments through Lua tables.
Previously, you had to use the
rpm.expand()
function to access the options and arguments of parametric Lua macros. With this enhancement, these macros receive their options and arguments as theopt
andarg
local tables, respectively.Global macro context.
Macros can now be accessed through the
macros
table in the global Lua environment. This table can also be used to call parametric macros, including all built-in macros.New bindings for RPM version objects and I/O streams.
You can now create objects from RPM version strings by using the new
rpm.ver()
function. You can use these objects to perform the following actions:-
Obtain the individual pre-parsed EVR components through the
e
,v
, andr
fields, respectively. - Compare RPM version strings to each other.
You can also use the new
rpm.open()
function to open file streams that use RPM’s I/O features, such as transparent compression and decompression.-
Obtain the individual pre-parsed EVR components through the
For more information, see Lua in RPM.
New macros for convenient string operations implemented in Lua
You can now perform basic string operations, such as extracting a substring or obtaining the length, directly by using RPM macros, without having to execute shell subprocesses. For more information, see String operations.
Unified calling conventions for built-in and user-defined macros
The %foo arg
, %{foo arg}
, and %{foo:arg}
notations used for calling macros are now equivalent. Note, however, that there might still be minor exceptions and differences.
Multiple new built-in macros
Multiple new built-in macros are now available, most notably:
-
%{rpmversion}
for obtaining the version of RPM installed on the system. -
%{exists:…}
for testing a file’s existence. -
%{shescape:…}
for encompassing a string in single quotes (''
) for use in a shell command that expects a single argument.
New %preuntrans
and %postuntrans
scriptlets
The %preuntrans
and %postuntrans
uninstall-time scriptlets complement the existing install-time %pretrans
and %posttrans
scriptlets:
-
%preuntrans
scriptlets are executed before a transaction for packages that this transaction will remove. -
%postuntrans
scriptlets are executed after a transaction for packages that this transaction removed.
19.3.3. Other notable changes
User and group name resolution is now strictly local
When installing packages, RPM now obtains the information about users and groups from the passwd(5)
and group(5)
files on the local system, respectively, as opposed to using the Name Service Switch (NSS).
When building packages, the %defattr
directive now interprets the dash (-
) placeholder for the user and group attributes as root
, instead of obtaining the information about the actual ownership from disk. Similarly, files in source RPM packages, such as spec
files, source archives, or patch files, are now always owned by the root user and group, regardless of their ownership on disk.
The build tree (%_builddir
) is now removed by default after a successful build
Previously, rpmbuild(8)
only cleaned up the build directory in the --rebuild
mode, not in the more commonly used modes, such as -bb
. Consequently, multiple packages being built caused the unnecessary accumulation of files over time. With this enhancement, if you prefer to always keep the build tree, for example, to investigate a non-fatal build issue, you can use the --noclean
option.
The %patch
directive must now explicitly specify the patch numbers to apply
You can specify the patch number either of the following ways:
-
By using the
-P
option, for example,%patch -P1 -P2
to apply patch numbers 1 and 2. -
By passing the patch numbers as positional arguments, for example,
%patch 1 2
to apply patch numbers 1 and 2.
The %patchN
syntax, where N
is the patch number to apply, is now deprecated.
If no explicit patch number is specified with the %patch
directive, the build terminates with an error.
It is recommended that you use the %autosetup
macro whenever possible, instead of applying the individual patches manually with the %patch
directive. When you use %autosetup
, patches are applied automatically in the order identified by their patch numbers. As a result, the spec
file is easier to read and maintain. For more information, see Automating patch application.