Package Version Locking
In production environments, certain critical packages must be pinned to specific versions to avoid compatibility issues from automatic updates. dnf-plugin-versionlock provides precise version locking capabilities.
Installing the versionlock Plugin
Section titled “Installing the versionlock Plugin”Install the Plugin
Section titled “Install the Plugin”dnf install -y dnf-plugin-versionlockVerify Installation
Section titled “Verify Installation”dnf versionlock --helpBasic Operations
Section titled “Basic Operations”Lock a Package at Its Current Version
Section titled “Lock a Package at Its Current Version”dnf versionlock add nginxLock to a Specific Version
Section titled “Lock to a Specific Version”dnf versionlock add nginx-1.20.1-14.el9Lock Packages Using Wildcards
Section titled “Lock Packages Using Wildcards”dnf versionlock add php-*List All Locked Packages
Section titled “List All Locked Packages”dnf versionlock listRemove a Lock for a Specific Package
Section titled “Remove a Lock for a Specific Package”dnf versionlock delete nginxClear All Locks
Section titled “Clear All Locks”dnf versionlock clearPractical Use Cases
Section titled “Practical Use Cases”Use Case 1: Locking the Kernel Version
Section titled “Use Case 1: Locking the Kernel Version”Prevent automatic kernel upgrades, suitable for environments with strict hardware driver compatibility requirements.
dnf versionlock add kerneldnf versionlock add kernel-corednf versionlock add kernel-modulesdnf versionlock add kernel-modules-coreVerify the lock is in effect:
dnf check-update kernel# Even if a new version exists, it will not appearUse Case 2: Locking Database Versions
Section titled “Use Case 2: Locking Database Versions”Production database upgrades require thorough testing first.
dnf versionlock add postgresql-serverdnf versionlock add postgresqldnf versionlock add postgresql-libsdnf versionlock add mariadb-serverdnf versionlock add mariadbdnf versionlock add mariadb-commonUse Case 3: Locking Web Server Versions
Section titled “Use Case 3: Locking Web Server Versions”dnf versionlock add nginxdnf versionlock add nginx-mod-*dnf versionlock add httpddnf versionlock add httpd-corednf versionlock add mod_sslUse Case 4: Locking Language Runtimes
Section titled “Use Case 4: Locking Language Runtimes”dnf versionlock add php php-cli php-common php-fpm php-mysqlnd php-pdodnf versionlock add nodejsdnf versionlock add npmLock File Details
Section titled “Lock File Details”View the Lock File
Section titled “View the Lock File”cat /etc/dnf/plugins/versionlock.listManually Edit the Lock File
Section titled “Manually Edit the Lock File”vi /etc/dnf/plugins/versionlock.listThe file format is one NEVRA (Name-Epoch:Version-Release.Arch) entry per line:
nginx-1:1.20.1-14.el9.x86_64Back Up and Restore Lock Configuration
Section titled “Back Up and Restore Lock Configuration”cp /etc/dnf/plugins/versionlock.list /root/versionlock-backup.listcp /root/versionlock-backup.list /etc/dnf/plugins/versionlock.listPackage Exclusion (Alternative to versionlock)
Section titled “Package Exclusion (Alternative to versionlock)”In addition to versionlock, you can use exclude to block specific packages from updating.
Global Exclusion in dnf.conf
Section titled “Global Exclusion in dnf.conf”echo "exclude=kernel* kernel-core*" >> /etc/dnf/dnf.confExclusion in a Specific Repository
Section titled “Exclusion in a Specific Repository”dnf config-manager --save --setopt=baseos.exclude="kernel*"versionlock vs exclude Comparison
Section titled “versionlock vs exclude Comparison”| Feature | versionlock | exclude |
|---|---|---|
| Pin to specific version | Yes | No (blocks entirely) |
| Allows downgrade | No | No |
| Package-level control | Exact NEVRA | Wildcards |
| Configuration location | Separate file | dnf.conf or repo files |
Using dnf history undo for Rollback
Section titled “Using dnf history undo for Rollback”Use this when a locked package was accidentally updated or you need to revert an operation.
View Transaction History
Section titled “View Transaction History”dnf history list --reverseView Transaction Details
Section titled “View Transaction Details”dnf history info <transaction-ID>Undo a Specific Transaction
Section titled “Undo a Specific Transaction”dnf history undo <transaction-ID> -yRedo a Transaction
Section titled “Redo a Transaction”dnf history redo <transaction-ID> -yAutomation Scripts
Section titled “Automation Scripts”Batch Lock Critical Packages
Section titled “Batch Lock Critical Packages”#!/bin/bash# Define the list of packages to lockLOCKED_PACKAGES=( "kernel" "kernel-core" "kernel-modules" "postgresql-server" "postgresql" "nginx" "php" "php-fpm" "php-cli")
for pkg in "${LOCKED_PACKAGES[@]}"; do echo "Locking: $pkg" dnf versionlock add "$pkg" 2>/dev/nulldone
echo "=== Current lock list ==="dnf versionlock listAudit Lock Status
Section titled “Audit Lock Status”#!/bin/bashecho "=== Version Lock Audit Report ==="echo "Date: $(date)"echo ""
# Temporarily disable versionlock to check for updatesecho "--- Updates blocked by version locks ---"dnf check-update --disableplugin=versionlock 2>/dev/null | \ grep -f <(dnf versionlock list 2>/dev/null | awk -F: '{print $1}' | sed 's/-[0-9].*//')
echo ""echo "--- Currently locked packages ---"dnf versionlock listEL 10 Notes: versionlock is the same as on EL 9
Section titled “EL 10 Notes: versionlock is the same as on EL 9”EL 10 still uses DNF 4 (4.20), and versionlock is still provided by dnf-plugin-versionlock, with the same usage and config file as EL 9:
| Item | EL 9 | EL 10 |
|---|---|---|
| Installation | sudo dnf install dnf-plugin-versionlock | Same |
| Config file location | /etc/dnf/plugins/versionlock.list | Same |
| File format | One NEVRA string per line | Same |
# Lock a packagednf versionlock add nginx
# List locked packagesdnf versionlock list
# Remove a lockdnf versionlock delete nginxcat /etc/dnf/plugins/versionlock.listRebuilding lock rules after an upgrade
Section titled “Rebuilding lock rules after an upgrade”If some lock rules stop working after the upgrade (the old NEVRA does not exist on EL 10), re-lock by package name. The idea: before upgrading, record which packages are locked on EL 9; after upgrading, re-lock them by name on EL 10 with versionlock add. This locks to versions that actually exist in the EL 10 repositories and avoids copying stale NEVRAs that point to non-existent versions.
Because the versionlock list holds name-epoch:version-release.arch NEVRA globs, truncating the package name with sed/awk is unreliable (e.g. java-17-openjdk or gcc-toolset-13-gcc get cut incorrectly). The safest approach is to archive the raw list for manual review — you usually lock only a handful of packages whose names you know:
# Save verbatim for cross-checking after the upgradednf versionlock list 2>/dev/null | tee /root/versionlock-el9.txt# Cross-check against /root/versionlock-el9.txt and list the packages you actually# want to lock here (example — replace with your real ones)for pkg in kernel nginx java-17-openjdk; do sudo dnf versionlock add "$pkg"done
sudo dnf versionlock listIf you lock many packages and need to extract names in bulk, resolving against installed packages with rpm is more reliable than truncating with sed:
# Strip the trailing .arch glob from each record, then let rpm resolve the canonical namednf versionlock list 2>/dev/null | sed 's/\.\*$//' | while read -r nevra; do [ -n "$nevra" ] && rpm -q --qf '%{NAME}\n' "$nevra" 2>/dev/nulldone | sort -u