Chapter 8 ⏱️ 50 min read 📚 Intermediate

Manage Software Packages

Master software management using DNF/YUM. Learn to install, update, remove packages, manage repositories, work with package groups, and handle AppStream module streams on RHEL 9.

🎯 Introduction

Package management is a core skill for Red Hat administrators. RHEL uses RPM (Red Hat Package Manager) format packages managed by DNF (Dandified YUM) - the successor to YUM. DNF handles dependency resolution, repository management, and transaction history.

Key Concepts

  • RPM Package: Pre-compiled software bundle (.rpm file)
  • Repository: Collection of packages with metadata
  • DNF/YUM: High-level package managers (handle dependencies)
  • rpm: Low-level tool (no automatic dependency resolution)
  • AppStream: RHEL 9 repository with multiple software versions
  • BaseOS: Core operating system packages
📘 DNF vs YUM

On RHEL 9, yum is a symbolic link to dnf. Both commands work identically. DNF is faster, more efficient, and has better dependency resolution than YUM.

RHEL 9 Repository Structure

Repository Content
BaseOS Core OS packages (kernel, systemd, bash)
AppStream Applications, languages, databases (multiple versions)
Extras Additional tools and utilities

📦 DNF/YUM Basics

Installing Packages

# Install a package
sudo dnf install httpd

# Install multiple packages
sudo dnf install httpd mariadb-server php

# Install without confirmation
sudo dnf install -y nginx

# Install specific version
sudo dnf install httpd-2.4.51

# Download package without installing
sudo dnf download httpd

# Install downloaded RPM with dependencies
sudo dnf install ./httpd-2.4.51-7.el9.x86_64.rpm

# Reinstall a package
sudo dnf reinstall httpd

Updating Packages

# Check for updates
sudo dnf check-update

# Update all packages
sudo dnf update

# Update specific package
sudo dnf update httpd

# Update to latest security patches only
sudo dnf update --security

# Update without updating kernel
sudo dnf update --exclude=kernel*

# Download updates without installing
sudo dnf update --downloadonly

Removing Packages

# Remove a package
sudo dnf remove httpd

# Remove with dependencies
sudo dnf autoremove httpd

# Clean up unused dependencies
sudo dnf autoremove

# Remove old kernel versions (keep latest 3)
sudo dnf remove --oldinstallonly --setopt installonly_limit=3

Searching and Querying

# Search for package
dnf search nginx
dnf search web server

# Find which package provides a file
dnf provides /usr/sbin/httpd
dnf provides */semanage

# Show package information
dnf info httpd

# List all packages
dnf list all

# List installed packages
dnf list installed

# List available packages
dnf list available

# List recent packages
dnf list recent

# Show package groups
dnf group list

# Check if package is installed
dnf list installed httpd

Package Information

# Display package details
dnf info httpd

# Show dependencies
dnf repoquery --requires httpd

# Show what depends on this package
dnf repoquery --whatrequires httpd

# List files in package
dnf repoquery -l httpd

# Show changelog
dnf changelog httpd

DNF History

# Show transaction history
sudo dnf history

# Show details of specific transaction
sudo dnf history info 5

# Undo a transaction
sudo dnf history undo 5

# Redo a transaction
sudo dnf history redo 5

# Rollback to specific transaction
sudo dnf history rollback 10

# List all transaction IDs
sudo dnf history list

Cleaning Up

# Clean cache
sudo dnf clean all

# Clean only metadata
sudo dnf clean metadata

# Clean packages
sudo dnf clean packages

# Remove duplicate packages
sudo dnf remove --duplicates

# Check for problems
sudo dnf check
💡 Pro Tips
  • Use dnf whatprovides to find which package provides a command
  • Add -y to skip confirmation prompts in scripts
  • Use dnf history to track and undo package changes
  • The dnf repoquery command is powerful for package research

🗄️ Managing Repositories

Viewing Repositories

# List all enabled repositories
dnf repolist

# List all repositories (enabled and disabled)
dnf repolist all

# Show detailed repo information
dnf repoinfo

# Show specific repository
dnf repoinfo baseos

Repository Configuration Files

Repository configurations are stored in:

  • /etc/yum.repos.d/*.repo - Repository definition files
  • /etc/dnf/dnf.conf - Main DNF configuration

Repository File Format

# Example: /etc/yum.repos.d/example.repo
[repository-id]
name=Repository Name
baseurl=https://repo.example.com/rhel9/
# or
metalink=https://mirrors.example.com/metalink?repo=rhel9
# or
mirrorlist=https://mirrors.example.com/mirrorlist?repo=rhel9
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-example

Common Repository Operations

# Enable a repository temporarily (one command)
sudo dnf install httpd --enablerepo=extras

# Disable a repository temporarily
sudo dnf install httpd --disablerepo=appstream

# Enable a repository permanently
sudo dnf config-manager --set-enabled extras

# Disable a repository permanently
sudo dnf config-manager --set-disabled extras

# Add a new repository
sudo dnf config-manager --add-repo https://example.com/repo/rhel9.repo

# Install config-manager if not present
sudo dnf install dnf-plugins-core

Procedure: Adding EPEL Repository

  1. Install EPEL release package:
    sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
  2. Verify repository is enabled:
    dnf repolist | grep epel
  3. Search for EPEL packages:
    dnf search htop
  4. Install package from EPEL:
    sudo dnf install htop

Creating a Local Repository

# Install required tools
sudo dnf install createrepo

# Create directory for packages
sudo mkdir -p /var/local-repo

# Copy RPM files
sudo cp *.rpm /var/local-repo/

# Create repository metadata
sudo createrepo /var/local-repo/

# Create repo file
sudo vi /etc/yum.repos.d/local.repo

[local]
name=Local Repository
baseurl=file:///var/local-repo
enabled=1
gpgcheck=0

# Clean and update cache
sudo dnf clean all
sudo dnf repolist

Repository Priority

# Install priority plugin
sudo dnf install dnf-plugin-priorities

# Set priority in repo file (lower number = higher priority)
[high-priority-repo]
name=High Priority Repo
baseurl=https://repo.example.com/
enabled=1
priority=1

[normal-repo]
name=Normal Repo
baseurl=https://other.example.com/
enabled=1
priority=10

GPG Key Management

# Import GPG key
sudo rpm --import https://example.com/RPM-GPG-KEY

# List imported keys
rpm -q gpg-pubkey --qf '%{name}-%{version}-%{release} --> %{summary}\n'

# Verify package signature
rpm --checksig package.rpm

# Install package without GPG check (not recommended)
sudo dnf install --nogpgcheck package.rpm

📚 Package Groups

Package groups are collections of related packages that can be installed together.

Working with Groups

# List all groups
dnf group list

# List all groups (including hidden)
dnf group list --hidden

# Show group information
dnf group info "Development Tools"

# Install a group
sudo dnf group install "Development Tools"

# Install group without optional packages
sudo dnf group install --with-optional "Server with GUI"

# Remove a group
sudo dnf group remove "Development Tools"

# Update a group
sudo dnf group update "System Tools"

# Mark group as installed (without installing packages)
sudo dnf group mark install "Development Tools"

Common Package Groups

Group Name Purpose
Development Tools Compilers, make, gcc, git
System Tools Administrative tools
Server with GUI Graphical environment for servers
Workstation Desktop applications
Virtualization Host KVM, libvirt, QEMU

Environment Groups

# List environments
dnf group list --ids

# Show environment details
dnf group info "Server with GUI"

# Install environment
sudo dnf install @"Server with GUI"

# Switch to graphical target
sudo systemctl set-default graphical.target

🔧 AppStream Modules

AppStream provides multiple versions of software through module streams. This allows you to choose specific versions of applications (e.g., Python 3.9 vs 3.11, PostgreSQL 13 vs 15).

Module Concepts

  • Module: Collection of packages (e.g., postgresql)
  • Stream: Version of the module (e.g., 13, 15)
  • Profile: Subset of packages for a use case (e.g., server, client)

Working with Modules

# List all modules
dnf module list

# List specific module streams
dnf module list postgresql

# Show module information
dnf module info postgresql

# Show specific stream
dnf module info postgresql:15

# List installed modules
dnf module list --installed

Enabling and Installing Modules

# Enable a module stream (doesn't install packages)
sudo dnf module enable postgresql:15

# Install default profile of enabled stream
sudo dnf module install postgresql:15

# Install specific profile
sudo dnf module install postgresql:15/server

# Enable and install in one command
sudo dnf install @postgresql:15/server

# Install multiple profiles
sudo dnf module install postgresql:15/{server,client}

Switching Module Streams

# Check current stream
dnf module list postgresql

# Reset module
sudo dnf module reset postgresql

# Switch to different stream
sudo dnf module enable postgresql:13
sudo dnf distro-sync

# Alternative: remove and install different stream
sudo dnf module remove postgresql:15
sudo dnf module reset postgresql
sudo dnf module install postgresql:13

Module Management

# Disable a module
sudo dnf module disable postgresql

# Remove installed module
sudo dnf module remove postgresql:15

# Reset module state
sudo dnf module reset postgresql

# Show module profiles
dnf module info --profile postgresql:15

Procedure: Installing Python 3.11 Module

  1. List available Python versions:
    dnf module list python3*
  2. View Python 3.11 module details:
    dnf module info python39:3.11
  3. Enable Python 3.11 stream:
    sudo dnf module enable python39:3.11
  4. Install Python 3.11:
    sudo dnf install python3
  5. Verify installation:
    python3 --version

Common Modules

Module Common Streams
postgresql 13, 15
python39 3.9, 3.11
nodejs 16, 18, 20
ruby 3.0, 3.1
⚠️ Module Stream Limitation

Only one stream of a module can be enabled at a time. To switch streams, you must first reset or disable the current stream.

⚙️ RPM Commands

The rpm command is the low-level package manager. It doesn't handle dependencies automatically.

Querying Packages

# List all installed packages
rpm -qa

# Query specific package
rpm -q httpd

# Show package information
rpm -qi httpd

# List files in package
rpm -ql httpd

# List documentation files
rpm -qd httpd

# List configuration files
rpm -qc httpd

# Show package dependencies
rpm -qR httpd

# Find which package owns a file
rpm -qf /usr/sbin/httpd

# Query package file (not installed)
rpm -qip package.rpm
rpm -qlp package.rpm

Installing/Removing with RPM

# Install RPM package (no dependency resolution)
sudo rpm -ivh package.rpm
# i = install, v = verbose, h = hash marks (progress)

# Upgrade package
sudo rpm -Uvh package.rpm
# U = upgrade (install if not present)

# Freshen (upgrade only if already installed)
sudo rpm -Fvh package.rpm

# Remove package
sudo rpm -e httpd

# Force remove (ignore dependencies - dangerous!)
sudo rpm -e --nodeps httpd

# Install without running scripts
sudo rpm -ivh --noscripts package.rpm

Verifying Packages

# Verify all installed packages
sudo rpm -Va

# Verify specific package
sudo rpm -V httpd

# Verify files from package
sudo rpm -Vf /usr/sbin/httpd

# Output codes:
# S = Size differs
# M = Mode differs (permissions)
# 5 = MD5 sum differs
# D = Device differs
# L = Link differs
# U = User ownership differs
# G = Group ownership differs
# T = mTime differs
# P = capabilities differ

Extracting RPM Contents

# Extract files from RPM without installing
rpm2cpio package.rpm | cpio -idmv

# Extract specific file
rpm2cpio package.rpm | cpio -idmv ./usr/bin/command
💡 RPM vs DNF

Use DNF when: Installing, updating, or removing packages (handles dependencies)
Use RPM when: Querying installed packages, verifying, or low-level operations

📝 Practice Questions

Question 1: What command installs httpd and all its dependencies?

  • A) rpm -ivh httpd
  • B) dnf install httpd
  • C) yum search httpd
  • D) rpm -Uvh httpd
Answer: B) dnf install httpd
DNF (and YUM) automatically resolve and install dependencies. RPM commands (rpm -ivh) do NOT handle dependencies automatically and will fail if dependencies are missing.

Question 2: How do you find which package provides the /usr/sbin/semanage command?

  • A) dnf search semanage
  • B) dnf provides /usr/sbin/semanage
  • C) rpm -qf /usr/sbin/semanage
  • D) dnf info semanage
Answer: B) dnf provides /usr/sbin/semanage
dnf provides (or dnf whatprovides) searches for which package provides a specific file. rpm -qf only works if the package is already installed. You can also use: dnf provides */semanage

Question 3: What's the correct way to switch from PostgreSQL 13 to PostgreSQL 15?

  • A) dnf install postgresql:15
  • B) dnf module reset postgresql && dnf module install postgresql:15
  • C) dnf update postgresql
  • D) dnf module enable postgresql:15
Answer: B) dnf module reset postgresql && dnf module install postgresql:15
To switch module streams, you must first reset the current stream, then install the new one. Alternatively: dnf module remove postgresql:13, then reset, then install postgresql:15.

Question 4: How do you list all files installed by the httpd package?

  • A) dnf list httpd
  • B) rpm -ql httpd
  • C) dnf info httpd
  • D) rpm -qa httpd
Answer: B) rpm -ql httpd
rpm -ql (query list) shows all files from a package. You can also use: dnf repoquery -l httpd. rpm -qa lists all installed packages, not files.

Question 5: What does 'dnf group install "Development Tools"' do?

  • A) Installs only the group metadata
  • B) Installs gcc, make, git, and other development packages
  • C) Lists available development tools
  • D) Creates a development environment
Answer: B) Installs gcc, make, git, and other development packages
Package groups bundle related packages. "Development Tools" includes compilers (gcc), build tools (make), version control (git), and libraries needed for software development.