AlmaLinux AppStream: enabled module stream past EOL with no warning from dnf
0 reputation · 10 Dec 2023, 21:50 UTC
0 reputation · 10 Dec 2023, 21:50 UTC
I want a reliable way to detect, before patching or provisioning, whether any enabled AppStream module stream on an AlmaLinux 9 system has passed its end-of-life date, so I can plan a stream switch before security updates stop.
From what I understand, only one stream per module can be enabled at a time, and an EOL stream remains installable but stops receiving updates. As far as I can tell, dnf does not warn when an enabled stream reaches EOL, and stream metadata (including EOL dates) is only refreshed on cache rebuilds, so stale metadata could hide lifecycle changes. I am also unsure how a stream switch interacts with installed packages: whether switching removes the old stream's packages before installing the new one, and whether a dnf module reset would leave orphaned RPMs that silently stop updating. Third-party repos like EPEL may also satisfy the same dependencies non-modularly, complicating the picture.
dnf module info) that exposes a stream's EOL date for scripting, or must this be tracked externally against published AlmaLinux lifecycle data?nodejs:18 to nodejs:20), what is the documented behavior for packages of the old stream, and how can downtime of dependent services be assessed in advance?dnf module reset, how can administrators identify orphaned packages that no longer map to any enabled stream?31275 reputation · 11 Dec 2023, 00:07 UTC
No: dnf has no supported command or metadata field that exposes an AppStream stream's end-of-life date, and it will not warn when an enabled stream passes EOL. EOL detection must be scripted externally against AlmaLinux's published lifecycle data, keyed off the module name and stream you read from dnf module list --enabled.
The modulemd metadata that dnf consumes describes streams by name, version, context, and summary — it does not carry a queryable EOL field. You can confirm this on any AlmaLinux 9 host:
dnf module info nodejs:18
# Output shows Name, Stream, Version, Context, Profiles, Summary — no EOL.Lifecycle dates live in AlmaLinux's release notes and lifecycle documentation, not in the repo metadata. So the practical pattern is:
dnf clean metadata && dnf makecache.dnf module list --enabled.module:stream pair against the published AlmaLinux EOL schedule (a small lookup table in your provisioning/patching pipeline is enough).dnf module switch-to nodejs:20 (or switch on older dnf builds) behaves like a targeted distro-sync: packages belonging to the old stream that are not satisfied by any other enabled stream or repository are removed, and the new stream's packages are installed. Packages that remain satisfiable non-modularly — for example via EPEL — are left in place, which can leave you with a mixed set.
To assess downtime risk in advance, always dry-run on the target host (or a clone):
dnf module switch-to nodejs:20 --assumenoRead the transaction summary carefully: anything in the "Removing" list that a running service depends on is your downtime window. If a service's packages exist only in the old stream, plan the switch as a maintenance event rather than a background patch.
dnf module reset nodejs disables the stream but does not remove its packages. Those RPMs simply stop receiving updates. Two ways to surface them:
dnf repoquery --unsatisfied
# or, with yum-utils installed:
package-cleanup --orphansTreat the output as a candidate list, not a removal list. Third-party repos that satisfy the same dependencies non-modularly can make intentionally installed packages appear orphaned, so verify each entry against rpm -q --whatrequires and your own provisioning records before removing anything.
This reflects established dnf/modularity behavior on RHEL-9-family systems; exact subcommand names (switch-to vs switch) vary slightly by dnf version, so check dnf module --help on your hosts. The EOL schedule itself is the piece you must keep current externally — no amount of dnf querying will substitute for it.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.