DNF, YUM, and RPM on Red Hat-Based Systems
Manage RPM-based systems with DNF or DNF5, understand YUM compatibility, inspect packages with RPM, review transaction history, and verify installed files.
Learning objectives
By the end of this lesson
- Distinguish DNF or DNF5 transaction management from low-level RPM database operations.
- Inspect enabled repositories, package candidates, capabilities, files, advisories, and transaction history.
- Preview installs, upgrades, removals, and synchronization before applying changes.
- Use RPM queries and verification output without misinterpreting legitimate configuration drift.
- Create a read-only package change-review bundle on an RPM-based system.
1. DNF resolves repository transactions; RPM maintains package state
RPM-based distributions separate high-level repository operations from low-level package operations. Modern Fedora systems use DNF5, while many enterprise and compatible distributions continue to expose dnf; yum may be a compatibility command. The rpm utility queries and verifies installed packages and can operate on individual RPM archives, but normal installations should use DNF so dependencies and repositories are handled coherently.
flowchart TB R[".repo files and repository metadata"] --> D["DNF or DNF5"] I["Installed RPM database"] --> D D --> S["libsolv dependency solution"] S --> T["Transaction preview"] T --> V["Package signature and digest checks"] V --> P["RPM transaction"] P --> F["Files, scripts, services, and triggers"] P --> I Y["yum compatibility command"] -. maps to .-> D
Because DNF generations and plugins differ across releases, use dnf --version, dnf5 --version, and local manual pages before assuming an option exists.
2. Inspect repositories and candidates
Repository definitions are commonly stored under /etc/yum.repos.d, with global configuration under /etc/dnf. Each repository can define a base URL or mirror configuration, enabled state, GPG checks, metadata expiration, exclusions, priorities through plugins or policy, and signing keys.
pm=''
if command -v dnf5 >/dev/null 2>&1; then
pm=dnf5
elif command -v dnf >/dev/null 2>&1; then
pm=dnf
elif command -v yum >/dev/null 2>&1; then
pm=yum
fi
[ -n "$pm" ] || { printf 'No DNF/YUM command found.\n' >&2; exit 1; }
"$pm" --version
"$pm" repolist
"$pm" info bash 2>/dev/null || true
"$pm" list --installed bash 2>/dev/null || true
# Read repository files without printing secret-bearing unrelated config.
grep -RhsE '^\[|^name=|^enabled=|^gpgcheck=|^repo_gpgcheck=|^baseurl=|^metalink=|^mirrorlist=' \
/etc/yum.repos.d 2>/dev/null | head -120Repository identity is part of package provenance. A package name and version alone are insufficient when the same build can appear in multiple enabled sources.
3. Query packages, capabilities, and file providers
RPM metadata supports package names, provides, requires, conflicts, obsoletes, file lists, scriptlets, signatures, and changelogs. DNF can search repository metadata; RPM can inspect installed packages or local archives.
package=${1:-bash}
# High-level queries; command availability differs by DNF generation.
"$pm" search "$package" 2>/dev/null | head -40 || true
"$pm" info "$package" 2>/dev/null || true
"$pm" provides '/usr/bin/bash' 2>/dev/null || true
# Installed package identity and files.
rpm -q "$package" --qf '%{NAME}\t%{EPOCHNUM}:%{VERSION}-%{RELEASE}\t%{ARCH}\n'
rpm -ql "$package" | head -40
rpm -qf /usr/bin/bash
# Dependencies and capabilities.
rpm -q --requires "$package" | head -40
rpm -q --provides "$package" | head -40
# Package scripts; review before manually installing an archive.
rpm -q --scripts "$package" | sed -n '1,100p'A capability can be supplied by a package whose name differs from the requested feature. Use provides and whatprovides-style queries rather than guessing package names.
4. Preview and reason about transactions
DNF commands normally display a transaction summary before confirmation. Automation should use explicit noninteractive controls only after the package set and repositories are constrained and logs are preserved.
package=${1:-jq}
# Cache-only or download-only options vary; start with a dry-run where supported.
if "$pm" --help 2>&1 | grep -q -- '--assumeno'; then
"$pm" --assumeno install "$package" || true
else
printf 'Use the displayed transaction prompt and answer no.\n'
fi
# Check for available upgrades without applying them.
"$pm" check-upgrade || status=$?
printf 'check-upgrade status=%s\n' "${status:-0}"
# Review transaction history where supported.
"$pm" history list 2>/dev/null | head -30 || true
# Compare installed packages with enabled repository state.
"$pm" distro-sync --assumeno 2>/dev/null || truecheck-upgrade may use a nonzero status to report available updatesDo not treat every nonzero package-manager status as a generic failure. Read the command's documented exit-status contract before writing CI or monitoring logic.
5. Verify installed files carefully
rpm -V compares installed files with metadata in the RPM database. It can report differences in size, digest, permissions, type, owner, group, modification time, capabilities, or links. Configuration changes may be legitimate; executable or library changes may indicate drift, manual modification, or compromise.
package=${1:-bash}
# Silence means no reported differences for the selected verification set.
rpm -V "$package" || true
# Verify package signatures and digests for a local archive.
rpm_file=$(find . -maxdepth 1 -name '*.rpm' -print -quit)
if [ -n "$rpm_file" ]; then
rpm -K "$rpm_file"
rpm -qp --qf '%{NAME} %{EPOCHNUM}:%{VERSION}-%{RELEASE} %{ARCH}\n' "$rpm_file"
rpm -qpl "$rpm_file" | head -40
fi
# Query install time and vendor for provenance context.
rpm -q "$package" --qf 'installed=%{INSTALLTIME:date}\nvendor=%{VENDOR}\npackager=%{PACKAGER}\n'Verification uses the installed package database as the expected baseline. It does not prove that the repository, signing key, or original package was trustworthy. Combine verification with repository policy, key management, incident timelines, and independent integrity controls.
6. Hands-on lab: create an RPM-family review bundle
This lab is read-only. It discovers the high-level manager, lists repositories, inspects one package, previews installation where supported, queries RPM state, and records recent transaction history.
lab="$HOME/devops-academy/linux/chapter09/lesson03"
mkdir -p "$lab"
package=${1:-jq}
if command -v dnf5 >/dev/null 2>&1; then
pm=dnf5
elif command -v dnf >/dev/null 2>&1; then
pm=dnf
elif command -v yum >/dev/null 2>&1; then
pm=yum
else
printf 'This lab requires an RPM-family package manager.\n' >&2
exit 1
fi
{
printf '=== os and manager ===\n'
cat /etc/os-release
"$pm" --version
printf '\n=== repositories ===\n'
"$pm" repolist
printf '\n=== package information ===\n'
"$pm" info "$package" 2>/dev/null || true
printf '\n=== transaction preview ===\n'
"$pm" --assumeno install "$package" 2>&1 || true
printf '\n=== installed rpm query ===\n'
rpm -q bash --qf '%{NAME}\t%{EPOCHNUM}:%{VERSION}-%{RELEASE}\t%{ARCH}\n'
printf '\n=== recent history ===\n'
"$pm" history list 2>/dev/null | head -30 || true
printf '\n=== verification example ===\n'
rpm -V bash || true
} > "$lab/rpm-review.txt"
less "$lab/rpm-review.txt"Verification checklist
7. Common mistakes
Using rpm -i for routine installation
Direct RPM installation bypasses normal repository dependency solving. Prefer DNF for ordinary workflows.
Assuming yum is always a separate legacy solver
On many systems it is a compatibility interface. Identify the actual implementation and version.
Treating all RPM verification differences equally
Expected configuration drift and unexpected binary changes require different responses.
Ignoring transaction history
History can identify when, why, and by which package operation state changed, though it is not a complete audit system.
8. Knowledge check
Question 1. Why prefer DNF over direct RPM installation?
Question 2. What can rpm -V reveal?
Question 3. What is a package capability?
9. Summary
DNF or DNF5 manages repository-aware RPM transactions; RPM provides low-level archive, database, query, and verification operations. Safe administration begins with repository and candidate inspection, uses transaction previews, preserves history, and interprets verification differences in context. Command details vary across DNF generations, so local version and manual-page checks are part of the workflow.
10. Further reading
- DNF5 command and transaction documentation.
- RPM Reference Manual and
rpm(8). - Fedora and enterprise-distribution package-management documentation for the installed release.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.