Dotfile management mit stow
Posted on So 07 August 2022 in Computer & Electronics
Jedes mal, wenn ich ein neues Laptop anschaffe, oder aus irgendwelchen Gründen das Betriebssystem neu installiere stehen drei Dinge an:
- System konfigurieren
- Daten aus Sync oder Backup kopieren
- Anwendungen konfigurieren
Den ersten Punkt habe ich weitgehend mit Ansible
automatisiert. Das sorgt dafür, dass alle wichtigen Dinge wieder installiert
werden und zentrale Funktionen wie z.B. ssh
auch gleich korrekt konfiguriert
sind. Programme, die ich spontan mal ausprobiere installiere ich direkt und an
Ansible vorbei, aber alles was ich wichtig finde kommt in mein Workstation
Playbook.
Punkt zwei ist auch kein Stress – ich habe auf Laptop und File-Server
unison
und synchronisiere
alles von/zu letzterem. So ist die Datenwiederherstellung schnell erledigt. Und
im Notfall gibt es auch noch das Server-Backup auf USB-Platte.
Bleibt Punkt drei. Unter LINUX liegen die Configs der verschiedenen Anwendungen
ja in "hidden files" aka dotfiles im home
-Folder des Users. Grundsätzlich
könnte ich diese in die Synchronisation einschließen, aber ich habe mich
bewusst dagegen entschieden, weil das zu Konflikten führt, wenn mehrere
verschiedene Computer sich mit dem Server synchronisieren. Auch existieren sehr
viele dotfiles die nicht backup-würdig sind, weil sie garkeine Konfiguration
enthalten, sondern irgendwelche App-spezifische Daten, oder aber zu Programmen
gehören, die ich längst nicht mehr nutze, oder nie wirklich konfiguriert habe.
Kurz: ich möchte mich eigentlich nur mit den dotfiles befassen, die ich auch
wirklich angepasst habe und nicht irgendwelche default configs sichern, die eh
von selbst wieder auftauchen. Nun könnte ich den copy
Mechanismus von Ansible
nutzen, um meine dotfiles wieder herzustellen – so mache ich das ja auch mit
den systemweiten config Files in /etc
. Aber das gefällt mir nicht so
richtig, weil es sich hier ja um user-spezifische Daten handelt, die sich von
Nutzer zu Nutzer unterscheiden. Eigentlich wäre das für mein Laptop egal, weil
ich eh der einzige Nutzer bin, aber es widerstrebt mir dennoch.
Bisher hatte ich das so gelöst, dass ich automatisch alle dotfiles (bis auf ein
paar Ausnahmen wie z.B. den Firefox cache) in einem tgz
Archiv sichere – in
Ordnern, die den jeweiligen hostname im Namen haben, so dass ich meine
verschiedenen Rechner sauber trenne kann. Im Falle einer Neuinstallation
bediene ich mich dann aus dieser Sicherung und kopiere alles, was mir wichtig
erscheint von Hand an den richtigen Ort. Das funktioniert und bisher ist mir
noch nie was verloren gegangen. Allerdings muss ich auch jedes mal daran
denken, was ich alles brauche. Und natürlich vergesse ich immer was. Das ist
nicht wirklich schlimm, denn ich merke es ja spätestens wenn ich das
betreffende Programm dann nutzen will und es nicht so läuft, wie gewünscht.
Dann also die nächste config kopieren – geht. Und so geht das dann mit mehreren
Programmen bis sich nach ein paar Tagen alles eingeschliffen hat. Geht, aber
wirklich elegant ist das nicht.
Das muss doch besser gehen
Manche Leute verwenden nun git
direkt in ihrem home
Verzeichnis, um die
dotfiles zu verwalten, aber das finde ich nur so mittel handlich. Seit einer
Weile wandern ja viele config files in ~/.config/
. Also das mit git
verwalten? Leider sind da aber einerseits noch nicht alle drin und zum anderen
ist auch dieser Ordner wieder voller Sachen, die ich nie wirklich angepasst
habe und daher auch nicht sichern und verwalten will. Schöner wäre es, wenn ich
alle liebevoll angepassten configs irgendwo zentral ablegen und dann davon ein
git
Repository daraus machen könnte – gepaart mit irgendwas, dass die
dotfiles dann dahin kopiert, wo sie hin gehören.
Kurz hatte ich überlegt, mir einen solchen Ordner anzulegen und dann ein
kleines Shell Skript zu basteln, mit dem ich diese Configs dann an den
richtigen Ort kopieren kann. Aber dann habe ich mich erinnert, dass es schon
ein gutes Tool für dieses Problem gibt, das ich zwar schon vor ewigen Zeiten
gesehen, aber irgendwie nie genauer angeschaut hatte:
stow
.
Dieses Tool erlaubt es, alle möglichen Files zentral zu speichern und dann via Symlinks dort bereitzustellen, wo sie eigentlich liegen müssen. Das klingt elegant.
Stow
Und das geht so:
Zunächst habe ich mir einen Folder für meine dotfiles angelegt:
mkdir -p ~/it/stow/dotfiles
Und in diesem Verzeichnis legen wir nun je einen Folder pro Package an. Ein Package kann dabei beliebig viel enthalten – eine einzelne Datei, alle Dateien für eine Anwendung, oder für eine Gruppe von Anwendungen, oder auch einfach alle Files, die wir so verwalten wollen.
Ich habe mich dafür entschieden, im Wesentlichen ein Package pro Anwendung zu haben:
> ll dotfiles/
clementine
digikam
filezilla
git
gnupg
i3
i3status
Insync
keepassxc
msmtp
mutt
offlineimap
rclone
rofi
shell
ssh
thunar
unison
virtualbox
xfce4
zsh
Jeder der Folder enthält nun die gewünschten config files inkl. Pfad ab ./
. Z.B.:
> tree -a i3
i3
└── .config
└── i3
└── config
> tree -a ssh/
ssh/
└── .ssh
├── authorized_keys
├── config
├── id_rsa
└── id_rsa.pub
Um diese config Files nun an Ort und Stelle zur Verfügung zu stellen machen wir dies:
stow -t /home/phil i3
stow -t /home/phil ssh
# oder alles auf einmal
stow -t /home/phil */
Und schon finden sich an den entsprechenden Stellen Symlinks auf die echten Files in unserem dotfile Folder:
> ll ~/.ssh
authorized_keys -> ../it/stow/dotfiles/ssh/.ssh/authorized_keys
config -> ../it/stow/dotfiles/ssh/.ssh/config
id_rsa -> ../it/stow/dotfiles/ssh/.ssh/id_rsa
id_rsa.pub -> ../it/stow/dotfiles/ssh/.ssh/id_rsa.pub
known_hosts
> ll -d .config/i3
.config/i3 -> ../it/stow/dotfiles/i3/.config/i3
Das ist praktischer, als wenn die Dateien dorthin kopiert worden wären, denn nun sind eventuelle Veränderungen der Dateien im dotfile-Ordner repräsentiert.
Wollen wir nun ein Package wieder deaktivieren geht das ebenfalls ganz einfach:
stow -t /home/phil --delete ssh
Und damit wir den target Pfad nicht jedes mal angeben müssen, speichern wir den
in .stowrc
– entweder im home
Folder, oder da wo wir auch die stow packeges
haben.
echo "--target=/home/phil" > .stowrc
# Und alle installieren
stow .
# deinstallieren
stow -D .
Zuguterletzt kann es noch praktisch sein, im stow folder ein
.stow-local-ignore
file anzulegen – ähnlich wie man es von .gitignore
kennt:
> cat .stow-local-ignore
.git
.gitignore
todo.md
README.md
So verhindert Ihr, dass diese Dateien ebenfalls in euer home directory verlinkt werden.
Und um das Ganze ordentlich zu versionieren brauchen wir den Ordner nur unter git Kontrolle zu stellen und schon ist alles wohlorganisiert. Zudem können wir nun z.B. je einen eigenen Branch für verschiedene Computer oder unterschiedliche Situationen anlegen, oder nach Herzenslust an einer Config rumschrauben, ohne Angst haben zu müssen, die ursprüngliche (funktionierende) Konfiguration nie wieder zusammen zu kriegen...