This page captures the key behaviors of modular DNF.
Ursine ("bare") packages are those that are not part of any module.
A module’s "context" is a unique hash value generated by the build system to distinguish binaries built for different Fedora releases as a result of stream expansion. See [module-stream-expansion].
Existing use of RPM-based operations must not change and must continue to work just as they always have.
DNF install/update commands can be invoked by using syntax of either
dnf module <command> $modspec … or
dnf <command> @$modspec ….
The "platform" pseudo-module cannot be explicitly enabled, installed, deleted, or have its stream changed.
A module is specified by its name, stream, version, context, and architecture (eg., "module:stream:version:context:arch").
If a module has a default stream defined on a system, "stream" may be omitted. Otherwise, "stream" must be explicitly provided.
For a given "module:stream", "version" can always be omitted. If "version" is not explicitly provided, the latest "version" for the given "module:stream" will be chosen.
If the module "context" is not specified, DNF will use heuristics to determine the appropriate "context". See [module-stream-expansion].
If the module "arch" is not specified, the system’s base architecture will be used.
Specifying a non-existent "module" name should fail.
Specifying a non-existent "stream" (for a valid "module") should fail.
Specifying specifying a non-existent "version" (for a valid "module:stream") should fail.
Specifying specifying a non-existent "context" (for a valid "module:stream:version") should fail.
Specifying a non-existent "arch" (for a valid "module:stream:version:context") should fail.
DNF must look for modular default stream and installation profile data in the repodata of the package installation repos—which is sourced from [fedora-module-defaults-repo] during the Fedora build and release process.
DNF must look for override data for modular default stream and
installation profile on the local system in
DNF must be able to list all modular content (modules, streams, enabled streams, default streams, profiles, module packages, profile packages).
Enabling a module stream makes all of its packages available on the system, but does not install them.
At most one stream of a module may be enabled at a time on a system.
Enabling a different stream of a module must be confirmed by the user (or "--assumeyes").
Enabling a different stream of a module will automatically disable the old stream.
If an uninstalled/unenabled module has a valid default stream configured, DNF will consider the default stream of the module and all of its packages available for resolving dependencies—and will automatically enable the default stream of that module if any packages from it are installed directly or indirectly (to resolve dependencies).
If an uninstalled/unenabled module:stream is listed as a runtime dependency of another module being installed or enabled, DNF will automatically enable that dependency.
Once a particular stream of a module has been enabled, DNF may not automatically enable a different stream.
Installing a module enables the specified stream (or default stream, if not specified) and installs all of the packages associated with the specified profile (or "default" profile, if not specified).
If a module does not explicitly have a "default" profile specified it its modulemd, DNF must pretend that it exists and is empty. See [mmd-spec-v2].
Each profile of a module stream must be able to be installed. However, a module’s profiles may conflict amongst themselves such that they cannot all be installed at the same time. (A hypothetical example would be a module that provides something analogous to the coreutils and coreutils-single packages in different profiles. The coreutils packages provide the same functionality, but conflict.)
Updating a module will update all installed packages that belong to the enabled module stream—regardless if the packages were installed by an install profile or ad-hoc.
Disabling a module does not remove any packages that belong to the module.
Disabling a module disables modules that depend on it—unless they still have packages installed.
Uninstalling a module removes all the packages that belong to the module and disables it.
Ad-hoc removal of all packages from an installed module does not disable the module.
A locked module cannot have a different stream enabled or be disabled—without first unlocking it.
Packages from module contexts that do not match the current transaction are disregarded. See [module-stream-expansion].
Any package in an enabled module takes priority over any ursine RPM with the same package name, regardless of which repositories those modules and packages may be in.
If there’s an ursine or modular RPM with a higher NVR than the hotfix one, the ursine or modular one wins. This is to ensure new proper updates override the temporary hotfix RPMs.