Autorenarchiv: Jörg Kastning

Und schon wieder ist eine FrOSCon vorbei

Am 16. und 17. August 2025 fand die 20. Free and Open Source Conference (FrOSCon) an der Hochschule Bonn-Rhein-Sieg in Sankt Augustin statt.

Ich möchte mich ganz herzlich beim Orga-Team, C3VOC, allen helfenden Händen, Ausstellern, Vortragenden und Besucher:innen bedanken, die dieses Wochenende zu einem schönen Erlebnis gemacht haben.

Es folgt mein kurzer, ganz persönlicher Konferenzbericht.

Anreise am Freitag Nachmittag

Ich hatte am Freitag frei und konnte daher entspannt mit dem Auto bereits am Nachmittag anreisen. Kurz nach meiner Ankunft in Siegburg konnte ich dann schon Dirk, Sujeevan und ein neues Gesicht begrüßen. An dem neuen Gesicht hängt eine Person namens Gerald dran. Gerald, es freut mich dich kennen gelernt zu haben.

Wir sind in Siegburg ein Eis essen gegangen, haben das tolle Wetter genossen und uns mental auf das Abendessen vorbereitet, wo sich Ulf und Andreas zu uns gesellten.

Essen gut, Gespräche gut, Freitag gut.

Samstag – FrOSCon Tag 1

Am Samstag konnte ich dann auch Christoph und Christian begrüßen, die ich ebenfalls schon viel zu lange nicht mehr gesehen habe. Nach einer kurzen Begrüßung schwärmten wir aus und erkundeten die verschiedenen Stände.

Am Stand des Fedora & CentOS Projekts habe ich erstmalig meine Arbeitskolleginnen Julia Bley und Aleksandra Fedorova getroffen. Ich freue mich immer andere Red Hatter zu treffen, welche durch ihre Beiträge Community-Konferenzen unterstützen. Beide haben auch direkt mir Unterstützung angeboten, da ich bei einer der nächsten Konferenzen gerne einmal vorstellen möchte, wie aus Fedora und CentOS Stream ein Red Hat Enterprise Linux Release entsteht.

Kaum habe ich mich umgedreht, habe ich mit Armin Warda und Christoph Görn gleich noch zwei weitere Red Hatter getroffen. Hier muss irgendwo ein Nest sein. Schön auch euch mal wiedergesehen zu haben. :-)

Das Vortragsprogramm hielt dieses Jahr einige interessante Vorträge für mich bereit. So hörte ich um 10:00 Uhr zuerst OpenCloud: Unsere Learnings für eine einfache, stabile Filecloud (Link zur Aufzeichnung) von Tobias Baader und Klaas Freitag. An dieser Stelle nochmals Danke für euren tollen Vortrag und die guten Gespräche, die wir anschließend noch geführt haben. Ich freue mich, wenn wir in Kontakt bleiben.

Verpasst habe ich leider AI slop attacks on the curl project von Daniel Stenberg. Ich werde mir aber auf jeden Fall die Aufzeichnung ansehen, da ich nur Gutes über diesen Vortrag gehört habe.

Um 14:30 habe ich den OpenVox Vortrag (Link zur Aufzeichnung) von und mit Martin Alfke gehört. Es hat mich gefreut zu hören, dass die Foreman und OpenVox Communities offenbar gut zusammenarbeiten und sich gegenseitig unterstützen. Sie tragen somit dazu bei, dass ein etabliertes Konfigurations-Management-Werkzeug weiterhin frei bleibt und nicht hinter einer proprietären Lizenz verschwindet.

Schießlich war ich um 17:00 Uhr mit meinem Vortrag Bootable Containers (Link zur Aufzeichnung; PDF zum Download) dran. Danke an alle Hörer:innen für euer Interesse und eure Aufmerksamkeit. An dieser Stelle gehen Grüße raus an meinen Kollegen Andreas Bleischwitz. Danke für den Post-Talk-QA und schön auch dich mal wiedergesehen zu haben.

Der 1. Tag klang mit dem Social Event aus. ich habe den innenhof der Hochschule schon lange nicht mehr so voll erlebt. Es war wirklich sehr schön.

Sonntag – FrOSCon Tag 2

Ich hatte schlecht geschlafen. Zum Glück gab es im Hotel einen guten Kaffee, der mich auf die Beine brachte.

Auf der FrOSCon führte mein erster Weg nochmals zu Klaas von OpenCloud. Ich hatte versprochen ihnen Informationen zum Red Hat Partnerprogramm zu senden und brauchte noch eine E-Mail-Adresse, um diese Aufgabe direkt abschließen zu können. Ich freue mich, wenn ich euch in der Zukunft als Partner in unserem Ecosystem Catalog finden kann und wünsche euch auf jeden Fall viel Erfolg mit eurem Projekt.

Als nächsten möchte ich mich bei Susanne Schütze für den Vortrag Festplattenverschlüsselung mithilfe vom TPM 2.0 (Link zur Aufzeichnung) bedanken. Dieser war nicht nur unterhaltsam sondern auch sehr informativ. Du ersparst mir damit, selbst durch etliche Kaninchenbauten zu kriechen. Vielen Dank für deinen Vortrag!

Ebenfalls informativ fand ich den Vortrag Delegate authentication and a lot more to Keycloak with OpenID Connect (Link zur Aufzeichnung) von Alexander Schwarz. Ich muss mich aufgrund anderer Projekte beherrschen, hier direkt ein neues Wochenendprojekt zu starten. ;-)

Und ein weiteres Dankeschön geht raus an Dirk für seinen Vortrag Vom Techniker zum Leader (Link zur Aufzeichnung). Danke, dass wir an deiner Erfahrung teilhaben durften.

Damit war ein tolles Wochenende mit guten Vorträgen und tollen Menschen auch schon wieder vorbei. Es hat mir große Freude bereitet dabei gewesen zu sein und ich freue mich auf ein Wiedersehen, vielleicht schon im nächsten Jahr am 15. und 16. August 2026. Save the date!

Links zu weiterführenden Informationen der Projekte

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

Meine Anwendungsfälle für die Nutzung großer Sprachmodelle in 2025

Heute berichte ich über meine Nutzung großer Sprachmodelle (engl. Large Language Model, kurz LLM) und freue mich, wenn ihr eure Erfahrungen in den Kommentaren oder vielleicht sogar einem eigenen Blog mit mir teilt.

Ich konzentriere mich in diesem Text auf Beispiele, in denen mich die Nutzung von LLMs in meiner Arbeit unterstützt. Dies soll nicht darüber hinwegtäuschen, dass LLMs halluzinieren und falsche Antworten produzieren können. Auch hierzu finden sich diverse Beispiele, die den Fokus des Artikels jedoch verschieben und den Umfang sprengen würden.

Bilder für Präsentationen

Ich nutze ChatGPT und Gemini, um Bilder für Präsentationen zu generieren. Dabei hat bis jetzt ChatGPT die Nase vorn.

Zuvor habe ich Bilder entweder selbst erstellt oder Stunden mit der Suche in Datenbanken mit lizenzfreien Bildern verbracht. Dies war für mich stets eine sehr frustrierende Erfahrung. Nun kann ich beschreiben, was ich in einem Bild sehen möchte und die Künstliche Intelligenz in Form eines LLM generiert mir entsprechende Bilder. Dies bringt für mich eine große Zeitersparnis und ich habe weniger Stress.

Zusammenfassung langer Texte und Diskussionen

Damit ist jetzt nicht gemeint, dass ich mir E-Mails mit mehr als fünf Sätzen zusammenfassen lasse. Aber auf der Arbeit erlebe ich es häufig, dass ich mal kurz nicht in eine Google Group geschaut habe und plötzlich eine Diskussion mit 40-70 Beiträgen darin finde. Diesen Diskussionen zu folgen war in der Vergangenheit sehr zeitaufwendig bis hinzu unmöglich. Und wir haben sehr viele Maillinglisten.

Wir haben auf der Arbeit Google Workspace und ich gebe gerne zu, dass sich damit bereits ohne KI-Unterstützung super arbeiten lässt. Die nahtlose Integration von Gemini macht es allerdings noch besser.

Wenn ich eine E-Mail Diskussion öffne, kann ich mir mit einem Klick eine Zusammenfassung erstellen lassen. Folgender Prompt hat sich bisher als nützlich erwiesen, um mir einen Überblick zu verschaffen: „Erstelle eine kurze Zusammenfassung, die den Diskussionsgegenstand wiedergibt. Führe auf, wer welche Argumente vertritt. Falls es Lösungsvorschläge und Action Items gibt, liste diese stichpunktartig auf.“

Anhand der Zusammenfassung kann ich in kurzer Zeit beurteilen, ob eine Diskussion für mich von Relevanz ist oder nicht. Auch hier ist der Vorteil durch Nutzung der KI im Allgemeinen die Zeitersparnis und im Speziellen die gute Integration in die vorhandenen Werkzeuge. Ich würde mir nicht die Mühe machen, alle Nachrichten einer langen Diskussion in einen Prompt zu kopieren, um diese dann von einem LLM analysieren zu lassen.

Generierung von Textvorschlägen für E-Mails

Ich weiß, was ich sagen möchte und drücke mich gerne direkt aus. Das kommt in der Kommunikation mit internationalen Empfängern aus anderen Kulturkreisen nicht immer gut an. Ich schätze auch hier die gute Integration von Gemini in Google Mail, wo ich es manchmal als Formulierungshilfe nutze.

Gemini bietet 3-4 Antwortvarianten an, die in einer Vorschau im Nachrichtenfenster angezeigt werden. Manche sind fernab meiner Vorstellung, andere kommen erstaunlich nah heran. So kann ich die am besten zutreffende Antwort auswählen, kürze sie etwas ein, ergänze evtl. noch 1-2 Sätze und bin fertig.

Vorteile auch hier die Zeitersparnis und die etwas höflicher bzw. runder formulierten E-Mails.

Zusammenfassung von Videokonferenzen

Ihr ahnt vielleicht schon, wo es jetzt hingeht. Google Gemini integriert sich auch hervorragend in Google Meet. Und so haben wir in einer internen Besprechung mit Zustimmung aller Beteiligten die Funktion ausprobiert, ein Besprechungs-Protokoll zu erstellen. Wir waren positiv überrascht.

Die Besprechung wurde auf Deutsch durchgeführt. Gemini war für diese Sprache offiziell noch als Alpha markiert, was das Ergebnis umso beeindruckender macht. Nach der Besprechung wurde ein Google Doc mit einer deutschsprachigen Zusammenfassung erstellt und im Kalender in den Termin eingefügt, so dass alle Teilnehmer es finden und darauf zugreifen können.

Ich habe das Protokoll gelesen und musste lediglich einige Schreibfehler bei Namen und englischen Fachbegriffen korrigieren. Alle Teilnehmer waren sich einig, dass die wesentlichen Punkte korrekt zusammengefasst wurden. Bei englischsprachigen Meetings, welche aufgezeichnet werden, enthält die Zusammenfassung sogar die Zeitstempel, zu denen protokollierte Aussagen gemacht wurden.

Es muss nun also kein Protokollant mehr ausgelost werden und alle Teilnehmer:innen können sich auf die Besprechung konzentrieren.

Da sich die Zusammenfassung auf das Wesentliche konzentriert, finde ich diese noch besser als ein Transkript, welches auch die belanglosen Beiträge wiedergibt und viel Redundanz enthalten kann.

Als Organisator verlasse ich mich nicht blind auf die KI. Ich lese das Protokoll zeitnah nach der Besprechung und korrigiere es ggf. Es ist bei uns auch nicht unüblich, dass Teilnehmer:innen auch im Nachgang zu einer Besprechung Ergänzungen und Korrekturen zum gemeinsamen Dokument beitragen.

Google NotebookLM

Google NotebookLM bietet eine Umgebung, in der mit KI-Unterstützung Inhalte von PDFs, Google Docs & Slides sowie Webseiten verarbeitet werden können. Ich möchte die Nutzung anhand eines konkreten Beispiels erläutern.

Leider habe ich mir die konkreten Prompts und detaillierten Antworten nicht gespeichert, so dass ich meine Erfahrung aus dem Gedächtnis aufschreibe.

Ich betreibe einen Server für Laborumgebungen aus der Hetzner-Serverbörse. Zu diesem gab es eine IPv4-Adresse und ein IPv6-Subnetz. Des Weiteren hat Hetzner eine Richtlinie zur Nutzung von MAC-Adressen. In meinem Fall darf nur die MAC der physischen Netzwerkkarte auf dem Switch im Rechenzentrum erscheinen, nicht jedoch die virtuellen MACs meiner virtuellen Maschinen (VM). Möchte ich meinen Server als Hypervisor-Host verwenden und die darauf laufenden VMs im Internet erreichbar machen, benötige ich dafür ein geroutetes Netzwerk auf dem Hypervisor.

Prinzipiell weiß ich, was zu tun ist. Es gibt bei Hetzner auch eine Anleitung, wie man Debian für Proxmox entsprechend konfiguriert, die ich auf RHEL mit Network Manager adaptieren kann. Deshalb schien mir diese Aufgabe geeignet, um zu testen, wie sich ChatGPT und NotebookLM dabei schlagen.

Ich habe beide Lösungen dabei angewiesen, mit folgenden Quellen zu arbeiten:

Bei ChatGPT sind die URLs zu den Quellen in den Prompt einzugeben. Bei NotebookLM kann zu Beginn konfiguriert werden, welche Quellen im aktuellen Notebook zu verwenden sind. Diese kann man flexibel selektieren oder abwählen, um zu steuern, mit welchen Quellen die KI arbeiten soll.

Beiden Werkzeugen habe ich über den Prompt mitgeteilt, welche IPv6-Adresse ich auf der physischen Netzwerkkarte des Hosts nutzen möchte. Anschließend habe ich via Prompt eine zu RHEL 9 passende Schritt-für-Schritt-Anleitung gefordert, mit der die gewünschte Netzwerkkonfiguration umgesetzt werden kann. Die angebotenen Lösungen wurden in beiden Fällen durch weitere Prompts verfeinert.

ChatGPT

Die von ChatGPT generierte Lösung war komplex und falsch. Aufgrund meiner eigenen Erfahrung hatte ich direkt Zweifel und glaubte nicht, dass der vorgeschlagene wilde Mix aus Bridge und Teaming mit Master- und Slave-Interface auf der Bridge funktionieren würde.

Um meine Annahme zu verifizieren, habe ich die vorgeschlagene Lösung trotzdem umgesetzt und nach der Hetzner-MAC-Abuse-Meldung wieder zurückgebaut.

Ich hatte keine Lust, ChatGPT mit dem Ergebnis zu konfrontieren und weiter mit dem Bot zu chatten, da ich wenig Hoffnung hatte, dass ich noch zu einer funktionierenden Lösung komme.

NotebookLM

Hier hat mir die Erfahrung deutlich besser gefallen. Gemini hat auf meinen Prompt mit einer Zusammenfassung reagiert, welche Informationen über die bereitgestellten Quellen zu meinem Prompt bieten. Dabei wurden auch Referenzen mit ausgegeben, um direkt zur Quelle springen zu können. Im Anschluss gab es eine Schritt-für-Schritt-Anleitung mit Code-Beispielen. Zu jedem Code-Beispiel erfolgte dazu eine Erklärung, was man dort sieht und was die einzelnen Parameter bedeuten. Dies hat mir gut gefallen.

Die ersten zwei Anleitungen waren noch etwas ungenau, ließen sich jedoch durch weitere Prompts soweit verfeinern, dass ich sie fast 1-zu-1 übernehmen konnte.

Warum nur fast? Ich habe mir die in der Schritt-für-Schritt-Anleitung referenzierten Quellen angeschaut und mit den dortigen Informationen die Code-Beispiele weiter optimiert, so dass sie besser zu meiner Umgebung passen. Evtl. hätte Gemini dies mit besseren Prompts ebenfalls hinbekommen.

Auch diese Lösung habe ich implementiert und sie läuft bis heute. Die KI hat mich auf dem Weg zur Lösung unterstützt und ich musste nicht die vier Quellen komplett und im Detail lesen, um mir die Lösung komplett selbst zu erarbeiten. Ich bin mit dem Ergebnis sehr zufrieden.

Fazit

Künstliche Intelligenz und deren Nutzung ist nicht unumstritten. Der aktuelle Energiebedarf ist enorm und es ist zu befürchten, dass dies negative Umweltauswirkungen zur Folge hat. KI-Modelle können halluzinieren, was zu Fehlern führt, wenn man die Antworten der Modelle nicht verifiziert.

Die Weigerung, KI im Beruf zu benutzen und ihre Möglichkeiten zu erkunden, führt meiner Einschätzung nach jedoch nur dazu, dass man sich selbst benachteiligt. KI mag Arbeitsplätze nicht so schnell ersetzen. Aber Menschen, die KI effizient nutzen können, werden Menschen von Stellen verdrängen, die dies nicht können. Es erscheint mir daher sinnvoll, den Einsatz von KI im Beruf und Alltag zu erkunden.

Den größten Vorteil bietet mir die KI-Nutzung aktuell dort, wo sie gut in meine Anwendungen und Werkzeuge wie z.B. Mail, Videokonferenzen und Kalender integriert ist. Der Vorteil besteht überwiegend in Zeitersparnis. Ich habe die gewünschten Informationen schneller mit weniger eigenem Aufwand in ausreichender Qualität zur Verfügung, wobei die Qualität mit geringem Aufwand durch manuelle Überarbeitung schnell gesteigert werden kann, um ein gutes Ergebnis zu erzielen.

KI-Assistenten lassen sich nutzen, um die Zeit zur Lösung zu verkürzen. Ich hätte die Dokumentationen alle selbst lesen und mir die Lösung erarbeiten können. Ich bin mir jedoch sicher, dass ich dafür deutlich mehr Zeit hätte investieren müssen.

Im Endeffekt hilft mir KI dabei, mehr Aufgaben im gleichen Zeitintervall zu erledigen.

Wie kann ich die Unixzeit einer Variablen im Forgejo Workflow zuweisen?

Dies ist ein Beitrag der Sorte „Notiz an mich selbst“. Wenn sie euch ebenfalls hilft, umso besser.

Ich hatte in folgendem Workflow versucht, die aktuelle Unixzeit in einer Umgebungsvariablen zu speichern, um sie in verschiedenen Schritten des Workflows wiederverwenden zu können. Mein Test-Workflow sah wie folgt aus:

name: test

on:
  push:
    branches: workflow_tests

env:
  UNIXTIME: $(date +%s)

jobs:
  test:
    runs-on: podman
    steps:
      - run: echo Debug output
      - run: echo Current unix time is ${{ env.UNIXTIME }}
      - run: sleep 10
      - run: echo Current unix time is ${{ env.UNIXTIME }}

Leider entsprach die Ausgabe nicht meiner Erwartung.

  • Ergebnis der ersten Ausgabe: 1747991617
  • Ergebnis der zweiten Ausgabe: 1747991629

In https://matrix.to/#/#codeberg.org:matrix.org erklärte mir jacksonchen666, dass $(date +%s) vermutlich als String an UNIXTIME übergeben wird. Die Auswertung durch die Shell findet dann erst im jeweiligen Workflow-Schritt statt. Ob das stimmt, weiß ich nicht, es klingt jedoch plausibel.

Christoph aus dem gleichen Matrix-Kanal schlug folgende Lösung vor:

echo "MY_VAR=foo" >> $GITHUB_ENV

Hier wird in der Shell der Wert foo der Variablen MY_VAR zugewiesen und diese anschließend in der Workflow-Umgebung verfügbar gemacht. Für mein Beispiel sieht das nun so aus:

name: test

on:
  push:
    branches: workflow_tests

jobs:
  test:
    runs-on: podman
    steps:
      - run: echo Debug output
      - run: echo "UNIXTIME=$(date +%s)" >> $GITHUB_ENV
      - run: echo Current unix time is ${UNIXTIME}
      - run: sleep 10
      - run: echo Current unix time is ${UNIXTIME}

Und schon stimmt die Ausgabe der UNIXTIME in beiden Schritten überein. Ich habe wieder was dazu gelernt. :-)

Meinung: DNS4EU – Kurz vorm Klo in die Hose gesch…

In diesem Jahr wird in Deutschland und der EU neben Künstlicher Intelligenz auch viel über digitale Souveränität diskutiert. Es ist kein Geheimnis, dass Europa bei IT-Anwendungen, Diensten und -Produkten den Anschluss an Nordamerika und Asien verloren hat bzw. sich freiwillig in eine Abhängigkeit begeben hat. Da erscheint DNS4EU wie ein kleiner LIchtblick.

Ein DNS-Dienst, betrieben in der EU, konform zur Datenschutz-Grundverordnung (DSGVO). Das hört sich erstmal gut an — ist es aber nicht.

Wie eine Recherche des IT-Consultant Jens Link ergab: „…,geht im Prinzip der gesamte Traffic durch Netze einer Firma außerhalb der EU.“ Genau gesagt durch Großbritanien, welches seit 2020 nicht mehr Mitglied der EU ist. Das ist aus mindestens den folgenden zwei Gründen ungünstig.

DNS-Datenverkehr ist meistens unverschlüsselt. Jede Person mit Zugriff auf den Datenverkehr kann mitlesen, wer wann welche Internetseite oder genauer gesagt Domain aufruft. Das ist nunmal so, unabhängig davon welche Route der Datenverkehr im Internet einschlägt.

England ist Mitglied der sogenannten Five Eyes, einer engen Kooperation der Geheimdienste aus Australien, Canada, England, Neuseeland und den USA. Für die Dienste dieser Staaten sind EU-Bürgerinnen und Bürger Angehörige von Drittstaaten, deren Daten zu geheimdienstlichen Zwecken gesammelt und ausgewertet werden dürfen. Spätestens seit der globalen Überwachungs- und Spionageaffäre ist bekannt, dass dies auch geschieht.

Was nützt es also, einen Dienst zu haben, dessen Betreiber sich zwar an die DSGVO im speziellen und die europäische Rechtsordnung im allgemeinen halten müssen, der gesamte Datenverkehr aber über jemanden geleitet wird, der daran nicht gebunden ist?

Den Ansatz und die Idee hinter DNS4EU finde ich gut, die Umsetzung mangelhaft. Solange der Datenverkehr den Rechtsraum der EU verlässt, bietet DNS4EU keinen Mehrwert zu bestehenden Diensten. Da bleibe ich lieber bei dnsforge.de oder den DNS-Resolvern meiner Internetdiensteanbieter.

Weitere Artikel zum Thema DNS in diesem Blog:

Zwischen Microblogging, TikTok-Videos und Social Media – Wo steht das Bloggen heute?

Ich lese und schreibe gerne. Lesen kann ich fast überall, ohne meine Umgebung zu stören. Gleichzeitig habe ich meine Ohren frei, um meine Konzentration schnell auf andere Dinge lenken zu können, ohne dass sich jemand durch Kopfhörer auf bzw. in meinen Ohren ausgeschlossen fühlt.

Ähnlich ist es mit dem Schreiben. Ich kann schreiben, während nebenbei das Fernsehen oder Radio läuft oder ich im Park oder einem Biergarten sitze. Podcasts und Videos lassen sich in diesen Umgebungen nur schwierig aufzeichnen.

Zudem bin ich in einer Zeit aufgewachsen, wo die Internetbandbreite noch so schmal war, dass an die flächendeckende Verbreitung von Audio und Video noch nicht zu denken war.

So ist das geschriebene Wort bis heute mein Favorit für die Aufnahme und Verbreitung von Wissen. Und damit sind Blogs für mich auch heute ein wichtiger und geschätzter Bestandteil des Internets, die für mich einen hohen Stellenwert besitzen.

Ich habe noch kein einziges TikTok-Video gesehen und kann dessen Stellenwert für die Gesellschaft nicht beurteilen. Ich finde generell nur sehr wenig Gefallen an Internetvideos, da sich bei mir der Eindruck verfestigt hat, dass diese häufig in die Länge gezogen werden, um noch eine Werbeunterbrechung oder Produktplatzierung unterbringen zu können. Ich fand bisher nur sehr wenige Videos hilfreich.

Wir Menschen sind jedoch teils sehr unterschiedlich und so ist mir bewusst, dass es natürlich auch eine Nutzergruppe gibt, welche Videos jederzeit den Vorzug vor einem Blogartikel gibt. Das ist auch vollkommen in Ordnung. Nutzt das Medium, welches euch am meisten anspricht.

Microblogging und Social Media sind für mich persönlich Synonyme für Mastodon. Hier folge ich meinen Bekannten, Freunden und interessanten Personen, deren Beiträge mich interessieren. Ich selbst teile hier meine Gedanken, Tageslaune und weise auf neue Artikel in meinem Blog hin. Falls ihr daran interessiert seid, findet ihr mich unter @Tronde@social.anoxinon.de.

Microblogging sehe ich es bestenfalls als Ergänzung zu einem Blog. Mit den Threads auf den diversen Plattformen konnte ich mich nie anfreunden. Wenn jemand etwas in mehr als 512 Zeichen ausdrücken möchte, freue ich mich, wenn dies in einem Blog niedergeschrieben wird, den ich gemütlich am Stück lesen kann.

Dies war nun meine Meinung. Welchen Stellenwert besitzen Blogs für euch?

Dieser Beitrag ist Teil der #BlogWochen2025, welche von von Benedikt, Dirk und Robert zum runden Geburtstag ihrer Blogs ausgerufen wurden.

Was ist das Red Hat Offline Knowledge Portal und wie betreibt man es als systemd.service?

In diesem Tutorial erkläre ich, worum es sich beim Red Hat Offline Knowledge Portal handelt, unter welchen Voraussetzungen man es nutzen kann und wie man es als systemd.service auf dem eigenen Rechner betreibt.

An einigen Stellen verweise ich auf die offizielle Red Hat Dokumentation, um das Tutorial nicht unnötig zu verlängern.

Was ist das Red Hat Offline Knowledge Portal?

Wie der Name suggeriert, handelt es sich um eine offline nutzbare Version des Red Hat Customer Portal und unserer Knowledge Base, Errata, Produktdokumentation, CVE-Datenbank und Red Hat Security Data API. Das folgende Bildschirmfoto zeigt die Startseite.

Startseite des Red Hat Offline Knowledge Portal

Ausgeliefert wird es als OCI-kompatibles Container-Image über registry.redhat.io (Authentifizierung erforderlich). Informationen zum aktuellen Image und den Vorgängerversionen finden sich auch im Red Hat Ecosystem Catalog. Der Inhalt wird wöchentlich aktualisiert und als aktualisiertes Container-Image bereitgestellt.

Wofür soll das gut sein?

Als Systemadministratoren oder Technical Account Manager (TAM) möchten wir auch auf die im vorstehenden Abschnitt genannten Informationen zugreifen können, wenn wir uns in einer Umgebung befinden, in der ein Internetzugriff nicht möglich ist. Darunter fallen zum Beispiel:

  • Vom Internet getrennte bzw. isolierte IT-Umgebungen
  • Einige Züge der Deutschen Bahn
  • Besprechungsräume und Büros mit bescheidener Signalstärke für das Diensttelefon
  • Umgebungen, in denen der Zugriff auf die Online-Informationen ermüdend langsam ist

Ich persönlich möchte das Offline Knowledge Portal zum Beispiel gerne auf meinem Arbeitslaptop dabei haben, um unterwegs jederzeit auf die darin enthaltenen Informationen zugreifen zu können. Es ist so schnell, dass ich nicht mehr auf Zug-WLAN, langsame Mobilfunkverbindungen oder die langsame Online-Version (an einer Verbesserung wird gearbeitet) warten muss.

Wer kann das benutzen?

Folgende Voraussetzungen müssen erfüllt sein, um das Offline Knowledge Portal nutzen zu können:

  • Es wird eine aktive Red Hat Satellite Subscription benötigt
  • Gültige Customer Portal, Red Hat Developer oder Registry Service Account -Zugangsdaten
  • Internetzugang, um das Container-Image herunterladen zu können
  • Eine rootless Podman Umgebung in Version 4.4 oder aktueller, welche diese Anforderungen erfüllt
  • Ein gültiger Offline Knowledge Portal access key
  • Zugangsdaten für registry.redhat.io in einer Datei für eine automatisierte Anmeldung liegen vor; siehe container-auth.json(5) für weitere Informationen

Wie kann man das dann benutzen?

Wer die schnelle Lösung sucht, findet diese in Chapter 1. Launching Red Hat Offline Knowledge Portal. Ich zeige an dieser Stelle, wie man das Offline Knowledge Portal als systemd.service konfigurieren und dann wie einen normalen Dienst steuern kann. Im folgenden Codeblock findet ihr mein Podman Quadlet, mit dessen Hilfe der systemd.service generiert wird. Die Datei habe ich in diesem Pfade abgelegt: ~/.config/containers/systemd/rhokp.container.

:~$ cat .config/containers/systemd/rhokp.container
[Unit]
Description=Red Hat Offline Knowledge Portal

[Container]
AutoUpdate=registry
ContainerName=RHOKP
Image=registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
PublishPort=127.0.0.1:8080:8080
PublishPort=127.0.0.1:8443:8443
Pull=newer
Secret=rhokp_access_key,type=env,target=ACCESS_KEY

[Service]
# Extend Timeout to allow time to pull the image
TimeoutStartSec=900

[Install]
# Start by default on boot
# WantedBy=multi-user.target default.target

Erklärung des Abschnitts [Container]:

  • AutoUpdate=registry
    • Aktiviert automatische Updates für den Container
    • Podman prüft dabei, ob in der Container-Registry eine neuere Version des Container-Images vorhanden ist, wenn der podman-auto-update.timer abgelaufen ist
  • ContainerName=RHOKP
    • Gibt dem Container einen Namen
    • Dieser wird in der Ausgabe von podman ps angezeigt
  • Image=registry.redhat.io/offline-knowledge-portal/rhokp-rhel9:latest
    • Fully qualified container reference
    • Der Tag latest ist zu verwenden, damit automatische Updates funktionieren
  • PublishPort=
    • Da ich das Offline Knowledge Portal auf meinem Arbeitslaptop ausführe und nur selbst nutze, binde ich den Dienst an die IP-Adresse 127.0.0.1
    • Soll der Dienst im Netzwerk angeboten werden, ist eine entsprechend erreichbare IP-Adresse zu verwenden
  • Pull=newer
    • Mit dieser Pull-Policy wird bei jedem Container-Start geprüft, ob eine neue Image-Version in der Container-Registry verfügbar ist und lädt diese ggf. herunter
    • Auf diese Weise muss ich nicht auf den Ablauf von podman-auto-update.timer warten
    • Es macht es mir einfacher, das Image auf meinem Laptop aktuell zu halten
  • Secret=rhokp_access_key,type=env,target=ACCESS_KEY
    • Ich habe meinen Offline Knowledge Portal Access Key in einem Podman-Secret namens rhokp_access_key gespeichert, welches beim Container-Start in die Umgebungsvariable ACCESS_KEY gemappt wird
    • So stelle ich sicher, dass mein Zugangstoken nicht in der Ausgabe von podman inspect auftaucht oder mit dem Container in eine Datei gespeichert wird und ggf. unkontrolliert mein System verlässt

Weitere Informationen finden sich in den Manpages podman-systemd.unit(5) und podman-secret(1).

Bitte beachtet, dass ich die letzte Zeile mit WantedBy= auskommentiert habe, da ich den Service auf meinem Laptop nur bei Bedarf starte. Wenn ihr den Dienst auf einem Server laufen lassen möchtet, der automatisch mitstartet, kommentiert die Zeile einfach ein.

Mit den folgenden Befehlen wird aus dem Quadlet ein systemd.service generiert und gestartet.

:~$ systemctl --user daemon-reload
:~$ systemctl --user start rhokp.service
:~$ systemctl --user is-active rhokp.service
active

Zusammenfassung

  • Ich muss mir nicht mehr den CLI-Befehl zum Start des Offline Knowledge Portal merken
  • Ich habe es auf meinem Arbeitslaptop stets dabei und griffbereit
  • Gesteuert wird es über vertraute systemctl-Befehle
  • Automatische Updates sind ebenfalls möglich

Wenn euch die Idee gefällt und ihr die Vorraussetzungen erfüllt, probiert es selbst aus.

PS: Es ist erfreulich schnell!

Linux-Server mit oder ohne Swap-Partition bereitstellen?

Wir schreiben das Jahr 2025. Die Frage, ob man Linux-Server mit oder ohne Swap-Partition betreiben sollte, spaltet die Linux-Gemeinschaft in einer Weise, wie wir es seit dem Editor War nicht mehr gesehen haben…

So könnte ein spannender Film für Sysadmins anfangen, oder? Ich möchte aber keinen Streit vom Zaun brechen, sondern bin an euren Erfahrungen und Gedanken interessiert. Daher freue ich mich, wenn ihr euch die Zeit nehmt, folgende Fragen in den Kommentaren zu diesem Beitrag oder in einem eigenen Blogpost zu beantworten.

  • Stellt ihr Linux-Server mit Swap-Partition bereit und wie begründet ihr eure Entscheidung?
  • Hat euch die Swap-Partition bei sehr hoher Speicherlast schon mal die Haut bzw. Daten gerettet?
  • War der Server während des Swapping noch administrierbar? Falls ja, welche Hardware wurde für die Swap-Partition genutzt?

Eine kleine Mastodon-Umfrage lieferte bisher folgendes Bild:

Schaue ich mir meine eigenen Server an, so ergibt sich ein gemischtes Bild:

  • Debian mit LAMP-Stack und Containern: 16 GB RAM & kein Swap
  • RHEL-KVM-Hypervisor 1: 32 GB RAM & 4 GB Swap
  • RHEL-KVM-Hypervisor 2: 128 GB RAM & kein Swap
  • RHEL-Container-Host (VM): 4 GB RAM & 4 GB Swap

Bis auf den Container-Host handelt es sich um Bare-Metal-Server.

Ich kann mich nicht daran erinnern, dass jemals einem dieser Systeme der Hauptspeicher ausgegangen ist oder der Swapspeicher genutzt worden wäre. Ich erinnere mich, zweimal Swapping auf Kunden-Servern beobachtet zu haben. Die Auswirkungen waren wie folgt.

Im ersten Fall kamen noch SCSI-Festplatten im RAID zum Einsatz. Die Leistung des Gesamtsystems verschlechterte sich durch das Swapping so stark, dass bereitgestellten Dienste praktisch nicht mehr verfügbar waren. Nutzer erhielten Zeitüberschreitungen ihrer Anfragen, Sitzungen brachen ab und das System war nicht mehr administrierbar. Am Ende wurde der Reset-Schalter gedrückt. Das Problem wurde schlussendlich durch eine Vergrößerung des Hauptspeichers gelöst.

Im zweiten Fall, an den ich mich erinnere, führte ein für die Nacht geplanter Task zu einem erhöhten Speicherverbrauch. Hier hat Swapping zunächst geholfen. Tasks liefen zwar länger, wurden aber erfolgreich beendet und verwendeter Hauptspeicher wurde anschließend wieder freigegeben. Hier entstand erst ein Problem, als der Speicherbedarf größer wurde und die Swap-Partition zu klein war. So kam es zum Auftritt des Out-of-Memory-Killer, der mit einer faszinierenden Genauigkeit immer genau den Prozess abgeräumt hat, den man als Sysadmin gern behalten hätte. Auch hier wurde das Problem letztendlich durch eine Erweiterung des Hauptspeichers gelöst.

Ich erinnere mich auch noch an die ein oder andere Anwendung mit einem Speicherleck. Hier hat vorhandener Swap-Speicher das Leid jedoch lediglich kurz verzögert. Das Problem wurde entweder durch einen Bugfix oder den Wechsel der Anwendung behoben.

Nun bin ich auf eure Antworten und Erfahrungsberichte gespannt.

Ein Blog sollte man immer dabei haben — auch offline

Der Name meines Blogs ist Programm. Es dient mir als digitales Gedächtnis für IT-Themen, die mich mich beschäftigt haben und die nochmal interessant werden können. Es ist eine Art Wissensdatenbank, auf die ich auch gerne zugreifen können möchte, wenn ich mal keine Internetverbindung habe.

Inspiriert durch den heutigen Beitrag von Dirk, möchte ich hier kurz beschreiben, was ich tue, um eine statische Version meines Blogs zu erstellen, welche ich einfach auf dem Laptop, Smartphone oder Tablet mitnehmen kann.

Ich verwende das Plugin Simply Static – The WordPress Static Site Generator, um eine statische Version meines Blogs zu erzeugen und als Zip-Archiv zu speichern. Möchte ich auf die statische Version meines Blogs zugreifen, entpacke ich das Zip-Archiv in ein Verzeichnis wie z.B. /tmp/simply-static/ und öffne anschließend in einem Webbrowser die Datei /tmp/simply-static/index.html.

Bildschirmfoto der statischen Version meines Blogs

So kann ich z.B. auch dann auf meine Artikel und Anleitungen zugreifen, wenn mein Webserver oder Internetzugriff nicht verfügbar ist. Die Suche auf der Seite funktioniert nur sehr eingeschränkt. Hier behelfe ich mir mit einer Dateisystemsuche im Terminal.

Ein paar Zahlen:

  • Dauer zur Erstellung des Zip-Archivs: ca. 10 Minuten
  • Größe des Zip-Archivs: 274 MB
  • Entpackte Größe: 355 MB
  • Rythmus der Erstellung: Wenn mir danach ist; in der Regel einmal pro Quartal

Mir gefällt an dieser Lösung, dass ich auf meinem mobilen Gerät keinen Container, ja noch nichmal einen Webserver, sondern nur einen Browser benötige. Das ist einfach, sparsam und robust.

Was haltet ihr davon ein Blog auf diese Weise offline verfügbar zu machen? Tragt ihr eure Blogs auch mit euch herum? Welche Werkzeuge nutzt ihr, um sie stets bei euch zu haben? Teilt euch gerne in den Kommentaren oder einem eigenen Blog mit.

Dieser Artikel ist Teil der #BlogWochen2025. Von Mai bis Oktober schreiben (zumindest) Robert, Dirk und ich über unterschiedliche Themen rund ums Bloggen. Du kannst gerne jederzeit einsteigen und mitmachen – die gesammelten Posts aller Teilnehmer:innen findest du auf dieser Seite und kannst sie auch als Feed abonnieren.

Codeberg.org mit Forgejo Actions, Runner, Workflows und ich

In diesem Artikel halte ich fest, was es mit den genannten Begriffen auf sich hat und was ich in den vergangenen Tagen mit ihnen angestellt habe. Dabei gehe ich auch auf das Warum ein, während Fragen nach dem Wie vorwiegend in den Verweisen im Text beantwortet werden.

Der Artikel dient mir als Dokumentation und meinen Leser:innen zur Unterhaltung und zum Wissenstransfer.

Codeberg.org

Codeberg ist eine demokratische, gemeinschaftsgetriebene, gemeinnützige Softwareentwicklungsplattform, die von Codeberg e.V. betrieben wird und sich um Codeberg.org, eine auf Forgejo basierende Software, dreht. Der Sitz des Vereins ist in Berlin. Hier wird Codeberg.org auch gehosted.

Auf Codeberg könnt ihr eure eigenen Freie Software-Projekte entwickeln, zu anderen Projekten beitragen, inspirierende und nützliche Freie Software durchstöbern, euer Wissen teilen oder euren Projekten mit Codeberg Pages ein Zuhause im Web geben, um nur einige Beispiele zu nennen.

Die beiden vorstehenden Abschnitte wurden übersetzt mit DeepL.com (kostenlose Version) und anschließend leicht angepasst und mit Links angereichert.

Mit Codeberg.org werden keine kommerziellen Interessen verfolgt. Man ist hier (nur) Nutzer und/oder Unterstützer, jedoch nicht selbst ein Produkt. Mir gefällt die Mission des Projekts. Daher bin ich dazu übergegangen, einen Teil meiner Repositories hier zu verwalten. Zwar bin ich kein Mitglied des Vereins, unterstütze diesen jedoch durch gelegentliche Spenden.

Actions, Runner und Workflows

Plattformen wie Codeberg.org, GitHub und GitLab unterstützen Softwareentwicklungsprozesse durch CI/CD-Funktionalität.

Ein Forgejo-Runner ist ein Dienst, der Workflows von einer Forgejo-Instanz abruft, sie ausführt, mit den Protokollen zurücksendet und schließlich den Erfolg oder Misserfolg meldet.

Dabei ist ein Workflow in der Forgejo-Terminologie eine YAML-Datei im Verzeichnis .forgejo/workflows eines Repositories. Workflows umfassen einen oder mehrere Jobs, die wiederum aus einem oder mehreren Steps bestehen. Eine Action ist eine Funktion zur Erfüllung häufig benötigter Aufgaben, bspw. Quelltext auschecken, oder sich bei einer Container-Registry einloggen etc. Siehe für weitere Informationen Abschnitt Hierarchy ff. im Forgejo Actions user guide.

Motiviert, meinen eigenen Forgejo-Runner zu installieren, haben mich zwei Blog-Artikel von meinem Arbeitskollegen Jan Wildeboer:

Durch den Betrieb eigener Forgejo-Runner kann ich bereits vorhandene Rechenkapazität nutzen. Es fallen für mich und den Verein Codeberg e.V. dadurch keine zusätzlichen Kosten an. Für die Installation auf RHEL 9 bin ich dem Forgejo Runner installation guide gefolgt, da das in Jans Artikel erwähnte Repository ne0l/forgejo offensichtlich nicht mehr gepflegt wird und nur eine veraltete Version des Runner enthält.

Ein Dankeschön geht raus an Jan für unseren kurzen und produktiven Austausch dazu auf Mastodon.

Wozu das Ganze?

Ich beschäftige mich beruflich seit einiger Zeit mit dem RHEL image mode und möchte demnächst einen meiner KVM-Hypervisor damit betreiben. Bis es soweit ist, arbeite ich eine Weile im „Jugend forscht“-Modus und baue immer wieder neue Versionen meiner Container-Images. Der Ablauf ist dabei stets derselbe:

  1. Containerfile(5) erstellen bzw. anpassen
  2. Container-Image mit podman-build erstellen
  3. Das erstellte Image mit podman-push in eine Container-Registry hochladen
  4. Das Deployment auf diversen Zielsystemen testen

Dazu verwende ich das RHEL 9 Bootc Base Image aus der Registry registry.redhat.io.

The rhel-bootc and user-created containers based on rhel-bootc container image are subject to the Red Hat Enterprise Linux end user license agreement (EULA). You are not allowed to publicly redistribute these images.

Quelle: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/using_image_mode_for_rhel_to_build_deploy_and_manage_operating_systems/introducing-image-mode-for-rhel_using-image-mode-for-rhel-to-build-deploy-and-manage-operating-systems#introducing-image-mode-for-rhel_using-image-mode-for-rhel-to-build-deploy-and-manage-operating-systems

Um vorstehender Anforderung gerecht zu werden, speichere ich das erzeugte Container-Image in einem privaten Repository auf Quay.io. Sowohl für registry.redhat.io als auch für quay.io ist ein Login erforderlich, bevor es losgehen kann.

Für mich bot sich hier die Gelegenheit, die Nutzung von Forgejo Workflows zu lernen und damit den Ablauf zur Erstellung meines RHEL Bootc Images zu automatisieren.

Forgejo Workflow und Runner-Konfiguration

Im folgenden Codeblock findet ihr meinen Forgejo Workflow aus der Datei .forgejo/workflows/build_image.yaml, gefolgt von einer Beschreibung der einzelnen Schritte. Zur Erklärung der Begriffe name, on, env, jobs, steps, run, etc. siehe Workflow reference guide.

name: build_image

on:
  push:
    branches: main

env:
  REPO_URL: https://codeberg.org/Tronde/rhel-bootc.git
  REPO_NAME: rhel-bootc
  IMAGE_NAME: quay.io/rhn-support-jkastnin/rhel-bootc:9.5

jobs:
  build:
    runs-on: podman
    steps:
      - run: dnf -y install git
      - run: echo ${{ secrets.RH_REGISTRY_TOKEN }} | podman login -u ${{ secrets.RH_REGISTRY_USERNAME }} --password-stdin registry.redhat.io

      - run: echo ${{ secrets.QUAY_ROBOT_TOKEN }} | podman login -u ${{ secrets.QUAY_USERNAME }} --password-stdin quay.io

      - run: git clone ${{ env.REPO_URL }}
      - run: podman build -f /workspace/Tronde/rhel-bootc/rhel-bootc/Containerfile -t ${{ env.IMAGE_NAME }}
      - run: podman push ${{ env.IMAGE_NAME }}
  1. Der Workflow wird jedes Mal ausgeführt, wenn ich einen Commit in den Branch main pushe
  2. Ich definiere einige Umgebungsvariablen, um bei Änderungen nicht alle Schritte im Workflow einzeln auf notwendige Änderungen prüfen zu müssen
  3. Mit `runs-on: podman` bestimme ich, dass der Workflow auf einem Runner mit dem Label podman ausgeführt wird; der entsprechende Runner started dann einen rootless Podman-Container, in dem die folgenden Schritte innerhalb von rootful Podman ausgeführt werden (nested Podman bzw. Podman in Podman)
  4. Git wird installiert
  5. Anmeldung an registry.redhat.io erfolgt
  6. Anmeldung an quay.io erfolgt
  7. Das Git-Repository wird geklont, um es auf dem Runner verfügbar zu haben
  8. Der Runner baut ein Container-Image (Erinnerung an mich selbst: Ersetze den hardcodierten Pfad durch eine Variable)
  9. Das erstellte Image wird in die Registry gepusht

Damit mein Runner den obigen Workflow ausführen kann, existiert auf diesem die Konfigurationsdatei /etc/forgejo-runner/config.yml, welche ich mit dem Kommando forgejo-runner generate-config > config.yml erstellt und anschließend angepasst habe. Der folgende Codeblock zeigt nur die Abschnitte, die ich manuell angepasst habe.

…
  fetch_interval: 20s
…
  labels: [
    "rhel-9-ubi:docker://registry.access.redhat.com/ubi9/ubi",
    "podman:docker://registry.access.redhat.com/ubi9/podman",
    "ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest",
    "act-runner:docker://node:20-bullseye",
    "centos-stream-9:docker://quay.io/centos/centos:stream9"]
…
  privileged: true
…

Ich greife mal die Zeile podman:docker://registry.access.redhat.com/ubi9/podman heraus:

  • podman: am Beginn der Zeile beinhaltet das Label, welches im Worflow mit runs-on verwendet wird
  • Mit dem Rest der Zeile wird bestimmt, in welchem Container-Image der Workflow ausgeführt wird
  • Ich habe mich für ubi9/podman entschieden, weil
    • ich bei Red Hat arbeite und daher
    • mit den Prozessen zur Erstellung unserer Images vertraut bin,
    • wodurch sich ein gewisses Vertrauen gebildet hat.
    • Ich vertraue unseren Images mehr, als jenen, die irgendein Unbekannter gebaut hat und deren Inhalt ich nicht kenne (man kann den Inhalt aber selbstverständlich überprüfen)
    • und ich so prüfen konnte, ob sich ein Image mit „unseren“ Werkzeugen bauen läst (nicht, dass ich daran gezweifelt hätte).

Die Angabe von privileged: true ist erforderlich, wenn man innerhalb des Containers ebenfalls mit podman oder docker arbeiten möchte.

Entscheidungen

Meinem weiter oben abgebildeten Workflow ist zu entnehmen, dass ich auf die Verwendung von Forgejo Actions verzichtet habe. Das hat folgende Gründe:

  • Für die Verwendung ist node auf dem Runner erforderlich
  • node ist im Image ubi9/podman standardmäßig nicht installiert
  • Node.js ist für mich das Tor zur Hölle und ich vermeide dessen Nutzung wenn möglich
  • Die Nutzung ist keine Voraussetzung, da ich mein Ziel auch so ohne Mehraufwand erreicht habe

Sobald die Workflows länger und komplexer werden, mag sich meine Einstellung zu Actions ändern.

Zusammenfassung

Ich habe gelernt:

  • Forgejo Runner zu installieren und zu konfigurieren
  • Wie Forgejo Workflows funktionieren und auf Codeberg.org genutzt werden können
  • Wie ich mir damit zukünftig die Arbeit in anderen Projekten erleichtern kann
  • Was für großartige Open Source Projekte Codeberg.org und Forgejo sind