Articles

Packages and updates: installing, upgrading and knowing what changed

How dnf and apt resolve packages, and how to inspect or undo what an update changed.

Reading: 6 minServer & Virtualization

Article cover: Packages and updates: installing, upgrading and knowing what changed

A server’s software is not one program but thousands of packages — bundles of files with version metadata and a list of what they depend on — and the package manager is what turns a request like “install nginx” into a transaction: read the repository index, resolve dependencies, download, install, and record what happened. The install is the easy part. The reason updates deserve a sheet of their own is the aftermath: an upgrade can replace a library that a running service loaded at start-up, drop a new default configuration file next to the one you edited, or pull in software you never asked for, and the machine keeps running as if nothing had changed. Knowing what changed is the skill.

What a package manager is doing

A repository publishes a signed index of packages and their dependency information. On RHEL 9, dnf reads repository definitions under /etc/yum.repos.d/ and its own settings from /etc/dnf/dnf.conf; on Ubuntu, apt reads sources from /etc/apt/sources.list.d/, which on 24.04 LTS is the deb822 file /etc/apt/sources.list.d/ubuntu.sources. Installation is a dependency solve, not a copy: the manager chooses a set of package versions that satisfies every requirement at once, which is why a single request can add or change dozens of packages and why “it only updates one thing” is rarely true.

Refresh the index, then act

Two verbs are involved, and keeping them apart makes the change inspectable. First the local view of the repositories is refreshed, then the upgrades are applied. apt update refreshes the index; apt upgrade installs available upgrades and never removes an installed package. dnf can do both in one invocation, or you can separate them with dnf check-update and look before committing.

A security update is an ordinary package update whose advisory says it fixes a vulnerability — not a different kind of object. RHEL tags these advisories, so dnf upgrade --security installs only packages that fix one and dnf updateinfo lists them. Ubuntu ships security updates automatically through unattended-upgrades, whose allowed origins live in /etc/apt/apt.conf.d/50unattended-upgrades and default to the official Ubuntu repositories, the -security suite among them.

Task dnf (RHEL 9) apt (Ubuntu)
Refresh the index dnf check-update apt update
Apply upgrades dnf upgrade apt upgrade
Security fixes only dnf upgrade --security security origins in 50unattended-upgrades
See what changed dnf history list, dnf history info <id> /var/log/dpkg.log
Keep a package from being upgraded dnf upgrade --exclude=<pkg> (that run only) apt-mark hold (until unhold)
Undo a transaction dnf history undo <id> reinstall pkg=version

Knowing what changed, and undoing it

dnf keeps a numbered history of what each transaction did: dnf history list shows the transactions and dnf history info <id> expands one into every install, upgrade and erase. dnf history undo <id> performs the opposite of that transaction, and dnf history rollback <id> undoes everything after it. apt has no equivalent single undo: every package action is logged in /var/log/dpkg.log, a package can be pinned with apt-mark hold, and one package can be reinstalled at an exact version with apt install pkg=version. That asymmetry is worth internalising — on Debian-family systems, rollback is a decision you make per package, deliberately, before you press enter.

Why a silent update changes behaviour

Three mechanisms explain how an update that printed “Complete!” can still alter the system. First, a running process keeps the code it loaded at start, so updating a shared library such as glibc or openssl-libs changes nothing for a daemon until that daemon restarts; the fix is on disk but not in the running service. Red Hat documents which packages make a reboot advisable and ships dnf needs-restarting to report it. Second, a package can ship a new default configuration file beside the one you edited: RPM replaces neither version silently, and which of the two the service goes on reading depends on how the package marked that file — your version saved aside as .rpmsave while the shipped one takes over, or your version kept in place while the shipped default arrives as .rpmnew. Third, unattended upgrades can reboot the host themselves when a kernel update requires it. None of these is a fault; all three are reasons to read what a transaction touched.

Limits and the common error

A security update keeps the same major version and closes a defect; a release upgrade — dnf system-upgrade or Ubuntu’s do-release-upgrade — moves the system to a new distribution version and is a change of platform, not a patch. Treating the second as the first is the classic mistake. Two more: apt full-upgrade may remove packages to complete an upgrade where apt upgrade will not, so the two commands are not interchangeable; and adding an unofficial repository to get one package widens what every later upgrade may install — on Ubuntu, packages from universe and multiverse do not receive the same security maintenance as those from main.

Level and prerequisites. L2 — operational. It assumes the L1 fundamentals of the Linux filesystem and of users and permissions, and it names systemd only as the thing that restarts a service after an update.

Where to go next

References