staging.inyokaproject.org

2024 Woche 40

6. Oktober 2024

Schalen am Strand
Schalen am Strand

Zu Beginn meiner Linuxnutzung hatte ich die Bash als meine Shell genutzt (war bzw. ist ja auch Standard), teilweise auch mit oh-my-bash . Irgendwann bin ich dann ueber Zsh und oh-my-zsh gestolpert und habe das dann hauptsaechlich genutzt. Auf Arbeit war es weiterhin ueberall Bash.

Ca. 2015 (?), nachdem ich meinen Terminal Emulator geaendert hatte (auf xiate , Blockpost in Arbeit), musste (?) auch die Zsh dran glauben. Denn ich hatte zwischenzeitlich immer mal wieder was von fish gehoert, aber der Mut zu aendern war nicht so gross 😉

fish #

Dank noqqe (mal wieder) wollte ich fish ca. 2018 nun doch mal etwas laenger austesten. Anscheinend wollte ich damals oh-my-zsh loswerden. Die Gruende weiss ich leider nicht mehr.

fish habe ich dann auch jahrelang eingesetzt (nicht nur unter Arch Linux sondern auch auf dem Arbeitsrechner (diverse MacBook Pros) und diversen Raspberry Pis ).

Der Wechsel war natuerlich einfach (auch dank dem hervorragenden Arch Linux Wiki ):

brew install fish
sudo pacman -S fish
sudo apt-get install fish

Allerdings habe ich nicht fish als Standardshell genutzt (sondern nur als interaktive Shell) indem ich weiterhin Bash als Standard hatte und eine simple .bashrc mit exec fish als Inhalt.

fisher #

Zur Pluginverwaltung kam bei mir fisher zum Einsatz. Zuletzt hatte ich folgende Plugins (andere Favoriten ) in Benutzung:

$ fisher ls
tohn/fish-git-util              # Convenient git utility functions
barnybug/docker-fish-completion # Completion for Docker
jorgebucaran/autopair.fish      # Auto-complete matching pairs
orefalo/g2                      # einfachere git Befehle
jorgebucaran/fisher             # fisher selbst
markcial/cprintf                # Printf with colors
jethrokuan/fzf                  # fuzzy-finder
brgmnn/fish-docker-compose      # docker-compose completions
jethrokuan/z                    # Pure-fish z directory jumping

oh-my-fish gibt es uebrigens auch. Z ist schon (statt autojump, fasd oder v) ziemlich cool, besonders in Verbindung mit fzf (hier ein alternatives Plugin fuer fish).

Weitere Links fuer fish #

Damals hatten mich neben dem Beitrag von noqqe auch folgende Links zu einem Wechsel bewogen:

Zsh (again) #

Allerdings hatte ich immer so meine Probleme mit fish. Zum einen konnte ich mich einfach nicht an die Syntax gewoehnen, wenn ich quasi ueberall sonst (in Scripts oder auf Arbeit) Bashsyntax verwende. In meinem Terminal waren Schleifen, Subshells usw. immer ein Problem (fuer mich) und ich musste daher immer extra kleine Scripte schreiben.

Auch sowas wie die Installation von z.B. conda waren immer aufwaendig/unmoeglich (wahrscheinlich weil fish nur als interaktive Shell gesetzt war). Und bis heute nutze ich den Hack, dass meine Standardshell immer noch Bash ist, indem in der .bashrc nach vielen Exports ein exec fish drin steht. Also irgendwie war ich nie rundum gluecklich. Auch ein paar Kleinigkeiten wie Tab Completions in/mit Ordnern und fehlende Completions bei git commit, wenn die Datei gerade mit git add hinzugefuegt wurde.

tl;dr es wurde Zeit fuer einen Wechsel. Da Zsh seit 5 Jahren die Standardshell unter macOS ist, habe ich sie auch wieder auserkoren. Mal sehen, was mich damals gestoert hatte 😅

Zumindest die Installation ist wieder recht einfach:

brew install zsh
sudo pacman -S zsh
sudo apt-get install zsh

# danach (OS unabhaengig)
chsh -s $(which zsh)

Danach habe ich einfach mal zsh eingegeben (ohne ~/.zshrc). Und bin damit die Installation ganz normal durchgegangen mit den Standardwerten.

Allerdings sind die Defaults ziemlich langweilig. Also nutzen wir Plugins ✨

Plugins #

Erstmal brauchen wir einen Pluginmanager oder Framework. Nachdem ich einen Tag lang oh-my-zsh installiert hatte (und mich auch hier die Defaults genervt hatten) und Antigen leider nicht mehr weiterentwickelt wird, habe ich mich dank dem Artikel im Arch Linux Wiki fuer Zim entschieden (das war eine gute Entscheidung ).

Natuerlich wollte ich moeglichst viele Sachen von fish auch wieder in Zsh haben, z.B. Aliase (meistens Abkuerzungen fuer haeufig genutzte Befehle), aber auch:

  • Rueckwaertssuche in der History mit fzf
  • Tab Completions (u.a. fuer ssh)

Im Moment sieht meine ~/.zimrc so aus:

zmodule environment
zmodule input
zmodule direnv
zmodule fzf
#zmodule git # finde grosses G bisschen seltsam
#zmodule homebrew # ebenso hier mit brew
zmodule ssh
zmodule utility
zmodule termtitle
zmodule prompt-pwd
zmodule git-info
zmodule duration-info
zmodule zsh-users/zsh-completions --fpath src
zmodule zsh-users/zsh-syntax-highlighting
zmodule zsh-users/zsh-autosuggestions
zmodule ohmyzsh/ohmyzsh --root plugins/brew
#zmodule ohmyzsh/ohmyzsh --root plugins/docker
zmodule ohmyzsh/ohmyzsh --root plugins/docker-compose
zmodule ohmyzsh/ohmyzsh --root plugins/globalias
zmodule ohmyzsh/ohmyzsh --root plugins/z
zmodule hlissner/zsh-autopair
zmodule joke/zim-starship
zmodule /Users/uxgch/path/to/zsh-plugin # lokaler Kram (hauptsaechlich Aliases)
zmodule completion # muss fast ans Ende
zmodule ohmyzsh/ohmyzsh --root plugins/git

Zim ist fuer Zsh was Vundle fuer (neo)vim ist. Recht easy 😊

Weitere (Plugin)sammlungen:

Prompts/Themes #

Das ist echt ein Thema fuer sich. Bisher sah jede Prompt bei mir anders aus (und war meist eine geaenderte Version von oeffentlich verfuegbaren), aber ich glaube ich haette gerne etwas, was crossplattform ist.

Etwa eine Stunde lang hatte ich dank Zim bira (weitere Themes ) genutzt 😅

Und bin dann dank Modul fuer Zim zu Starship gewechselt. Als Vorlage habe ich mir Gruvbox Rainbow runtergeladen 🌈

Zusaetzlich dazu habe ich mir eine Nerdfont (genauer die “Hack Nerd Font”) installiert und in iTerm2 eingerichtet .

Sonstiges #

SSH #

Meine SSH-Config ist etwas umfangreicher (mehrere Includes, eigene UserKnownHostsFiles, mehrere Identities, mehrere Namen in einer Host-Zeile usw.)

Sehr aufgehalten hat mich die UserKnownHostsFiles. Die Hosts wurden naemlich einfach nicht angezeigt bei der Completion. Beheben konnte ich das durch folgende Zeile in der ~/.zshrc:

zstyle ':completion:*:(ssh|scp|sftp|rsh|rsync):*' hosts ${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_,~/.ssh/ssh-config/.known_}hosts{,_*}(|2)(N) /dev/null)"}%%[# ]*}//,/ }

History #

Bei der Migration von fish zu zsh bin ich grob dieser Anleitung gefolgt . Ich wollte eigentlich auch die History migrieren, hatte auch dieses kleine Programm dafuer genutzt. Allerdings gab es anscheinend irgendwo in meiner History einen Fehler und es konnte leider keine History migriert werden. Ist aber auch ok, ich hab sie ja noch als Datei in meinem Dateisystem rumfliegen.


Danke, dass du das hier via RSS liest! :)

2. Oktober 2024

Mit chezmoi lassen sich nicht nur einzelne Konfigurationsdateien verwalten, sondern auch ganze Verzeichnisse.

Auf meinen Rechnern sieht der Inhalt des Verzeichnisses ~/.config/zsh beispielsweise folgendermaßen aus.

 1zsh
 2├── aliase.zsh
 3├── completion.zsh
 4├── environment.zsh
 5├── functions.d
 6│   ├── clrhist
 7│   ├── sshf
 8│   ├── up
 9│   └── updpkgbuild
10├── functions.zsh
11├── options.zsh
12├── prompt.zsh
13├── .zhistory
14└── .zshrc

Führt man chezmoi add ~/.config/zsh aus, werden alle darin enthaltenen Dateien übernommen. Was aber nicht immer gewünscht ist.

Damit chezmoi bestimmte Dateien bzw. Verzeichnisse ignoriert, legt man in der Standardkonfiguration unter ~/.local/share/chezmoi die Datei .chezmoiignore an und trägt die Dateien / Verzeichnisse ein die ignoriert werden sollen. Will man nun, dass chezmoi die Datei .zhistory ignoriert, reicht es in dem Fall aber nicht, einfach .zhistory in die Datei zu schreiben. Man muss doublestar.Match verwenden. Somit würde bei diesem Beispiel der Eintrag **/.zhistory funktionieren.

Führt man nun chezmoi add ~/.config/zsh aus, sollte “chezmoi: warning: ignoring .config/zsh/.zhistory” angezeigt werden und die Datei sollte nicht übernommen werden.

Um Konfigurationsdateien auf mehreren Rechnern zu verwalten, kann man das Tool chezmoi nutzen.

Das Tool erstellt hierfür unter ~/.local/share/chezmoi ein lokales Git-Repository. Allerdings habe ich alle meine anderen Repositories in einem anderen Verzeichnis gespeichert. Daher habe ich mich gefragt, ob man das Standardverzeichnis von chezmoi ändern kann. Ja, kann man.

Hierfür legt man, falls nicht bereits vorhanden, die Datei ~/.config/chezmoi/chezmoi.toml an und trägt in dieser beispielsweise folgendes ein.

1sourceDir = "~/repository/dotfiles"

Führt man nun chezmoi init aus, wird das Repository nicht mehr in ~/.local/share/chezmoi, sondern im angegebenen Verzeichnis erstellt.

Die MZLA Technologies Corporation hat mit Thunderbird 128.3 ein planmäßiges Update für seinen Open Source E-Mail-Client veröffentlicht.

Neuerungen von Thunderbird 128.3

Mit dem Update auf Thunderbird 128.3 hat die MZLA Technologies Corporation ein planmäßiges Update für seinen Open Source E-Mail-Client veröffentlicht. Das Update bringt diverse Fehlerbehebungen und Verbesserungen unter der Haube, welche sich in den Release Notes (engl.) nachlesen lassen. Auch wurden diverse Sicherheitslücken geschlossen.

Der Beitrag Thunderbird 128.3 veröffentlicht erschien zuerst auf soeren-hentzschel.at.

30. September 2024

Die MZLA Technologies Corporation hat die erste Beta-Version von Thunderbird für Android veröffentlicht. Die App steht im Google Play Store sowie auf GitHub zum Download bereit.

Im Sommer 2022 wurde die Übernahme des E-Mail-Clients K-9 für Android durch die MZLA Technologies Corporation, Entwicklerin von Thunderbird, bekannt gegeben. Nun steht eine erste Beta-Version von Thunderbird für Android zum Download bereit, wahlweise über den Google Play Store oder via GitHub. Später soll auch noch F-Droid als zusätzliche Option dazukommen.

Die Veröffentlichung der ersten finalen Version von Thunderbird für Android ist derzeit für die vierte Oktoberwoche geplant. Dann wird es auch eine ausführlichere Vorstellung auf diesem Blog geben.

Der Beitrag Thunderbird Beta für Android veröffentlicht erschien zuerst auf soeren-hentzschel.at.

Dieser Artikel gibt meine Motivation für den Bau von Container-Images und die Vorgehensweise wieder und zeigt, wie ich mit Buildah meine OCI-kompatiblen Container-Images erstelle.

Es handelt sich dabei mehr um einen Erfahrungsbericht als ein Tutorial und ich erhebe keinen Anspruch auf Vollständigkeit. Das behandelte Beispiel ist jedoch zum Einstieg und zur Nachahmung für all jene geeignet, die Container ausführen können und diese gerne ohne Verwendung von Containerfiles bauen möchten.

Motivation

Ich möchte die Ansible-Rollen aus meiner Collection tronde.nextcloud mit Molecule und Podman-Containern testen. Als Zielplattform für das Deployment der Nextcloud unterstütze ich zunächst Debian und RHEL.

Die Tests sollen verifizieren, dass Nextcloud im Container in einer rootless-Podman-Umgebung bereitgestellt werden kann. Da der Test unter Verwendung von Podman-Containern durchgeführt werden soll, müssen diese Container eine solche rootless-Podman-Umgebung bereitstellen.

Für RHEL 8 und RHEL 9 habe ich entsprechende Container-Images gefunden. Für Debian bin ich nicht fündig geworden und habe daher beschlossen, diese Container-Images selbst zu erstellen.

Buildah ist das Werkzeug meiner Wahl, da:

  • Container-Images damit interaktiv erstellt werden können,
  • die verwendeten Befehle am Ende in einem Bash-Skript gesammelt werden können,
  • sich damit sogar interaktive Abfragen mit Heredocs beantworten lassen,
  • man kein containerfile(5) benötigt und
  • ich das Werkzeug noch nicht kenne und es gerne kennenlernen möchte.

Für mich sind dies ausreichend Gründe, um mich kopfüber in ein neues Container-Projekt zu stürzen. Wer mehr über die Beziehung von Buildah zu Podman erfahren möchte, dem empfehle ich den englischsprachigen Artikel: Buildah and Podman Relationship von Tom Sweeney.

Mein Weg zum Image

Um rootless Podman in einem Container zum Laufen zu bekommen, habe ich mich an dem englischsprachigen Artikel How to use Podman inside of a container von Dan Walsh orientiert. Das Ergebnis findet ihr in meinem GitHub-Repo tronde/container-image-forge.

Die folgenden Code-Blöcke zeigen Auszüge aus dem Skript buildah_create_debian_bookworm_with_rootless_podman.sh (Commit 7634ed8). Die enthaltenen Befehle werden unter dem jeweiligen Code-Block erläutert. Alle Befehle werden als normaler Benutzer ohne Root-Rechte ausgeführt.

# Name of target container image
tctri=debian_rootless_podman

# Get a base image
ctr=$(buildah from --pull=newer docker://docker.io/library/debian:bookworm)
  • Die Variable tctri nimmt den Namen des Container-Images auf, welches ich erzeugen werde
  • Die Variable ctr nimmt den Namen des Containers auf, welcher durch den buildah-from(1)-Befehl erzeugt wird; mit diesem Container wird im Folgenden gearbeitet
  • Die Option --pull=newer sorgt dafür, dass das Image nur dann aus der angegebenen Registry heruntergeladen wird, wenn es aktueller als das evtl. lokal gespeicherte Image ist
buildah run -- $ctr apt -y update
buildah run -- $ctr apt -y upgrade
buildah run -- $ctr apt -y install podman fuse-overlayfs libvshadow-utils libcap2-bin ca-certificates
  • Mit buildah-run(1) werden Befehle innerhalb des Arbeits-Containers ausgeführt
  • Ich aktualisiere die im Basis-Image enthaltenen Pakte und
  • installiere die für rootless Podman benötigten Pakete
  • Das Paket ca-certificates wird benötigt, um später Container-Images aus einer Registry herunterladen zu können
buildah run -- $ctr useradd podman
buildah run -- $ctr sh -c "echo podman:1:999 > /etc/subuid"
buildah run -- $ctr sh -c "echo podman:1001:64535 >> /etc/subuid"
buildah run -- $ctr sh -c "echo podman:1:999 > /etc/subgid"
buildah run -- $ctr sh -c "echo podman:1001:64535 >> /etc/subgid"
buildah run -- $ctr setcap cap_setuid+epi /usr/bin/newuidmap
buildah run -- $ctr setcap cap_setgid+epi /usr/bin/newgidmap
  • Mit den hier dargestellten Befehlen wird der nicht-privilegierte Benutzer podman erstellt
  • Die IDs für /etc/sub[g,u]id habe ich mir aus dem ubi9/podman-Image abgeschaut
  • Die setcap-Befehle sind notwendig, um rootless Podman ausführen zu können; ich habe sie durch Internetrecherche und Trial-and-Error zusammengestellt
buildah config -v /var/lib/containers $ctr
buildah config -v /home/podman/.local/share/containers $ctr
  • Das Image wird in der Lage sein, rootful und rootless Podman auszuführen
  • Mit den beiden Befehlen werden die Volumes hinzugefügt, die Podman als Container Storage nutzt
    • Rootful Podman verwendet /var/lib/containers
    • Rootless Podman verwendet /home/podman/.local/share/containers
buildah run -- $ctr chown -R podman:podman /home/podman
buildah run -- $ctr sh -c "mkdir -p /var/lib/shared/overlay-images /var/lib/shared/overlay-layers /var/lib/shared/vfs-images /var/lib/shared/vfs-layers; touch /var/lib/shared/overlay-images/images.lock; touch /var/lib/shared/overlay-layers/layers.lock; touch /var/lib/shared/vfs-images/images.lock; touch /var/lib/shared/vfs-layers/layers.lock"
buildah config --env _CONTAINERS_USERNS_CONFIGURED="" $ctr
  • Der Benutzer podman bekommt ein HOME-Verzeichnis
  • Ich erstelle die Verzeichnisse, die ich im Artikel [7] gefunden habe
  • Ich erstelle die Environment-Variable, die ich ebenfalls in genanntem Artikel [7] gefunden habe
buildah run -- $ctr apt -y reinstall uidmap
buildah run -- $ctr apt -y clean
buildah run -- $ctr rm -rf /var/lib/apt/lists/*
  • Aus mir nicht bekannter Ursache muss das Paket uidmap neu installiert werden, um ein UID/GID-Mapping sicherzustellen; dies scheint analog zur Neuinstallation der shadow-utils in Artikel [7] notwendig zu sein
  • Die beiden folgenden Befehle sollen den Paket-Cache aufräumen, um die Größe des resultierenden Images zu verkleinern, zeigen jedoch keinen sichtbaren Effekt
# Commit to an image
buildah commit --rm $ctr $tctri
# Alternative: Use this and add GPG fingerprint for image signing
# buildah commit --sign-by <fingerprint> --rm $ctr $tctri

# Tag the image just created
buildah tag $tctri $tctri:bookworm-$(date --iso)
  • Mit buildah-commit(1) wird der Inhalt des Arbeits-Containers $ctr in ein Container-Image namens $tctri geschrieben
  • Durch Angabe der Option --rm wird der Arbeits-Container entfernt
  • Die Kommentarzeile lässt erkennen, dass ich zukünftig beabsichtige, meine Images digital zu signieren
  • buildah-tag(1) fügt dem Image einen Tag mit Datumsstempel hinzu; siehe auch: Recommendations for tagging and versioning container images

Der Befehl buildah-commit(1) fügt dem neuen Image übrigens nur einen weiteren Layer hinzu, egal wie viele Befehle zuvor im Arbeits-Container ausgeführt wurden. Das erzeugte Image umfasst also die Layer des Basis-Image plus einen weiteren.

Zwischenfazit

An diesem Punkt habe ich ein Basis-Image ausgewählt, mithilfe von buildah zusätzliche Software installiert, einen Benutzer hinzugefügt und ein neues Image erzeugt.

Um den Build-Prozess zu automatisieren, habe ich die notwendigen Befehle in Bash-Skripte geschrieben und unter https://github.com/Tronde/container-image-forge abgelegt.

Die fertigen Images halte ich in der Registry https://quay.io/repository/rhn-support-jkastnin/debian_rootless_podman vor. Fühlt euch frei, diese für eigene Experimente zu benutzen, doch verwendet sie nur mit Vorsicht in Produktion. Ich erzeuge diese Images nur nach Bedarf neu, so dass die veröffentlichen Versionen veraltet und voller Sicherheitslücken sein können.

Validierung

Jetzt, wo die Images fertig sind, kann ich prüfen, ob sich rootless Podman darin auch wie gewünscht ausführen lässt.

Die Prozesse innerhalb des von meinem Container-Image instanziierten Containers laufen als Benutzer root. Um die Prozesse als Benutzer podman auszuführen, ist dies beim Aufruf von podman run explizit mit anzugeben. Der folgende Code-Block verdeutlicht dies und zeigt zugleich den ersten Fehler beim Versuch rootless Podman auszuführen.

]$ podman run --rm localhost/debian_rootless_podman:bookworm-2024-09-21 id
uid=0(root) gid=0(root) groups=0(root)
]$ podman run --rm --user podman localhost/debian_rootless_podman:bookworm-2024-09-21 id
uid=1000(podman) gid=1000(podman) groups=1000(podman)
]$ podman run --rm --security-opt label=disable --user podman --device /dev/fuse localhost/debian_rootless_podman:bookworm-2024-09-21 podman info
time="2024-09-21T18:43:35Z" level=error msg="running `/usr/bin/newuidmap 15 0 1000 1 1 1 999 1000 1001 64535`: newuidmap: write to uid_map failed: Operation not permitted\n"
Error: cannot set up namespace using "/usr/bin/newuidmap": exit status 1

Der Fehler deutet auf fehlende capabilities(7) hin. Um diese Hypothese zu testen, wiederhole ich den letzten Befehl mit der Option --privileged (siehe dazu podman-run(1)):

]$ podman run --rm --security-opt label=disable --user podman --device /dev/fuse --privileged localhost/debian_rootless_podman:bookworm-2024-09-21 podman info
host:
…

Damit funktioniert es. Leider geben sich viele Menschen an dieser Stelle mit dem Ergebnis zufrieden. Doch ich möchte diese Container nicht einfach mit --privileged ausführen. Also studiere ich die Manpage capabilities(7) und teste mich Stück für Stück heran, bis ich mit dem folgenden Kommando ebenfalls erfolgreich bin:

]$ podman run  --rm --user podman --security-opt label=disable --device /dev/fuse --cap-add=setuid,setgid,sys_admin,chown localhost/debian_rootless_podman:bookworm-2024-09-21 podman info
host:
…

Dies ist schon deutlich besser, da dem Container hiermit deutlich weniger Privilegien eingeräumt werden müssen. Das Thema Container-Privilegien und capabilities(7) werde ich noch genauer untersuchen. Eventuell folgt dazu dann auch ein weiterer Artikel. Für den Moment ist das Ergebnis gut genug.

Quellen und weiterführende Links

  1. Buildah.io
  2. Ansible Collection tronde.nextcloud
  3. Mein Wochenendprojekt Nextcloud im Container
  4. Podman Images im Red Hat Catalog
  5. Buildah and Podman Relationship von Tom Sweeney
  6. About Ansible Molecule
  7. How to use Podman inside of a container by Dan Walsh
  8. Using podman containers
  9. Having trouble getting started with rootless podman running rootless podman inside a Debian 12 image #23838
  10. Recommendations for tagging and versioning container images