Wie dnf.8.gz in den Container kam
Die folgende Geschichte soll mir zur Erinnerung und euch zur Unterhaltung dienen. Sie handelt von CentOS Stream 10, Containern und der Manpage dnf(8)
. Aber lest selbst.
Es war einmal ein Systemadministrator, der beim Training einige Subkommandos von dnf updateinfo
kennenlernte, von deren Existenz er bislang nichts wusste. Und diese Subkommandos heißen list
, info
und summary
. Neugierig schaute er in die Manpage dnf(8)
, doch zu seinem Erstaunen schwieg sich diese zu diesen Subkommandos aus.
Wut stieg in unserem Sysadmin auf. Wieder einmal haben sich die Entwickler keine Mühe gegeben, die Funktionalität ihrer Anwendung vernünftig zu dokumentieren. Die Qualitätssicherung hat geschlafen. So kann man doch nicht arbeiten. Doch nach dem ersten Wutanfall beschloss der Sysadmin, der Sache in Ruhe auf den Grund zu gehen, bevor er diesen Misstand anprangern würde.
Die Distribution des Sysadmins ist dafür bekannt, dass unter bestimmten Umständen Funktionalität von Upstream zurückportiert wird. Vielleicht hatte sich hier eine Diskrepanz eingeschlichen. Vielleicht war dieser Fehler in einer neueren Version ausgemerzt. Um dies schnell zu überprüfen, wollte unser Sysadmin einen Blick in dnf(8)
in Centos 10 Stream werfen. Dazu führte er folgende Befehle in einer Kommandozeile aus:
$ podman run --rm -it centos:stream10
[root@01ede4521839 /]# man 8 dnf
bash: man: command not found
[root@01ede4521839 /]#
Mit einem Augenrollen erinnerte sich unser Sysadmin daran, dass Container-Images nur das absolut Notwendige enthalten, um möglichst wenig Speicherplatz auf der Festplatte zu belegen. Darüber, was absolut notwendig ist, werden seit anbeginn des Containerzeitalters philosophische Streitgespräche geführt. Also prüfte unser Sysadmin, ob es einen vertrauten Paketmanager gab, um die Manpages nachzuinstallieren:
[root@01ede4521839 /]# dnf in man-db man-pages
CentOS Stream 10 - BaseOS 2.6 MB/s | 6.2 MB 00:02
CentOS Stream 10 - AppStream 1.5 MB/s | 2.4 MB 00:01
CentOS Stream 10 - Extras packages 3.3 kB/s | 3.5 kB 00:01
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
man-db x86_64 2.12.0-8.el10 baseos 1.3 M
man-pages noarch 6.06-3.el10 baseos 3.7 M
Installing dependencies:
groff-base x86_64 1.23.0-10.el10 baseos 1.1 M
less x86_64 661-3.el10 baseos 191 k
libpipeline x86_64 1.5.7-7.el10 baseos 53 k
Transaction Summary
================================================================================
Install 5 Packages
Total download size: 6.4 M
Installed size: 9.9 M
Is this ok [y/N]:
…
Installed:
groff-base-1.23.0-10.el10.x86_64 less-661-3.el10.x86_64
libpipeline-1.5.7-7.el10.x86_64 man-db-2.12.0-8.el10.x86_64
man-pages-6.06-3.el10.noarch
Complete!
[root@01ede4521839 /]# mandb
Processing manual pages under /usr/share/man...
Updating index cache for path `/usr/share/man/man7'. Wait...mandb: can't resolve man7/groff_man.7
mandb: warning: /usr/share/man/man7/man.7.gz: bad symlink or ROFF `.so' request
mandb: can't resolve man7/groff_man.7
mandb: warning: /usr/share/man/man7/man.man-pages.7.gz: bad symlink or ROFF `.so' request
Updating index cache for path `/usr/share/man/man3type'. Wait...done.
Checking for stray cats under /usr/share/man...
Checking for stray cats under /var/cache/man...
Processing manual pages under /usr/local/share/man...
Updating index cache for path `/usr/local/share/man/mann'. Wait...done.
Checking for stray cats under /usr/local/share/man...
Checking for stray cats under /var/cache/man/local...
45 man subdirectories contained newer manual pages.
2701 manual pages were added.
0 stray cats were added.
0 old database entries were purged.
[root@01ede4521839 /]# man 8 dnf
No manual entry for dnf in section 8
Resultat: Kein which
-Befehl verfügbar. Diese Container-Image-Kuratöre sparten aber wirklich an allem. Doch der obige Codeblock enthüllt noch mehr. Zwar war der Paketmanager dnf
installiert, auch die Manpages waren nun vorhanden, nur die Manpage dnf(8)
fehlte immer noch. Und so bemühte der Sysadmin wieder die Tastatur, um zu prüfen, ob die entsprechende Datei tatsächlich fehlt, welches Paket sie bereitstellt und um das Problem zu lösen. Sehet und staunet:
[root@01ede4521839 /]# stat /usr/share/man/man8/dnf.8.gz
stat: cannot statx '/usr/share/man/man8/dnf.8.gz': No such file or directory
[root@01ede4521839 /]# dnf provides /usr/share/man/man8/dnf.8.gz
…
dnf-4.20.0-9.el10.noarch : Package manager
Repo : baseos
Matched from:
Filename : /usr/share/man/man8/dnf.8.gz
[root@01ede4521839 /]# dnf reinstall dnf
Last metadata expiration check: 0:01:01 ago on Wed Jan 1 14:31:37 2025.
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Reinstalling:
dnf noarch 4.20.0-9.el10 baseos 478 k
Transaction Summary
================================================================================
Total download size: 478 k
Installed size: 2.5 M
Is this ok [y/N]:y
…
Reinstalled:
dnf-4.20.0-9.el10.noarch
Complete!
[root@01ede4521839 /]# stat /usr/share/man/man8/dnf.8.gz
File: /usr/share/man/man8/dnf.8.gz -> dnf4.8.gz
Size: 9 Blocks: 8 IO Block: 4096 symbolic link
Device: 0,111 Inode: 6118189 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-10-28 20:00:00.000000000 -0400
Modify: 2024-10-28 20:00:00.000000000 -0400
Change: 2025-01-01 14:32:59.692356995 -0500
Birth: 2025-01-01 14:32:59.691356987 -0500
Überzeugt, dass der Spuk nun ein Ende habe, versuchte es unser Sysadmin erneut:
[root@01ede4521839 /]# man 8 dnf
No manual entry for dnf in section 8
Moment! Die Datei ist da, die Manpage jedoch nicht? Sind hier dunkle Mächte am Werke? Nein, denn wie die folgenden Befehle offenbarten, lag die Ursache lediglich in kaputten Symlinks und fehlenden Paketen:
[root@01ede4521839 /]# ls -l /usr/share/man/man8/dnf.8.gz
lrwxrwxrwx. 1 root root 9 Oct 28 20:00 /usr/share/man/man8/dnf.8.gz -> dnf4.8.gz
[root@01ede4521839 /]# ls -l /usr/share/man/man8/dnf4.8.gz
ls: cannot access '/usr/share/man/man8/dnf4.8.gz': No such file or directory
[root@01ede4521839 /]# dnf provides /usr/share/man/man8/dnf4.8.gz
Last metadata expiration check: 0:05:59 ago on Wed Jan 1 14:31:37 2025.
…
python3-dnf-4.20.0-9.el10.noarch : Python 3 interface to DNF
Repo : baseos
Matched from:
Filename : /usr/share/man/man8/dnf4.8.gz
[root@01ede4521839 /]# dnf list python3-dnf
Last metadata expiration check: 0:06:16 ago on Wed Jan 1 14:31:37 2025.
Installed Packages
python3-dnf.noarch 4.20.0-9.el10 @System
Getrieben von Ungeduld und etwas Frust installierte unser Sysadmin nun auch das Paket python3-dnf.noarch
neu, in einem letzten, verzweifelten Versuch, endlich die lang ersehnte Manpage zu erhalten.
[root@01ede4521839 /]# dnf reinstall python3-dnf.noarch
…
Reinstalled:
python3-dnf-4.20.0-9.el10.noarch
Complete!
[root@01ede4521839 /]# man 8 dnf
DNF4(8) DNF DNF4(8)
NAME
dnf4 - DNF Command Reference
SYNOPSIS
dnf [options] <command> [<args>...]
DESCRIPTION
DNF is the next upcoming major version of YUM, a package manager for
RPM-based Linux distributions. It roughly maintains CLI compatibility
with YUM and defines a strict API for extensions and plugins.
Na endlich! Da war sie, die so lang ersehnte und schmerzlich vermisste Manpage. Und die Mühe unseres Sysadmins wurde mit der Erkenntnis belohnt, dass die gesuchte Information auch in dieser Version von dnf(8)
nicht enthalten war. Zufrieden wandte sich der Sysadmin nun dem Ticketsystem zu, um zu erfragen, warum die gesuchten Informationen nicht vorhanden sind und um eine Ergänzung anzuregen.
Und wenn er nicht gestorben ist, wartet er noch immer auf eine Antwort.
Und die Moral von der Geschichte?
Erwarte nicht Manpages in Container-Images zu finden. Unser Sysadmin wäre deutlich schneller am ZIel angelangt, hätte er direkt in den Quelltext geschaut: https://github.com/rpm-software-management/dnf/blob/master/doc/command_ref.rst