ADMIN

2024

07

2024-06-27T12:00:00

Industrievernetzung

PRAXIS

050

Open-Source-Tipp

GNU-Tool

Dotfiles

Konfigurationsfiles zentral verwalten

Die richtige Einstellung

von Thorsten Scherf

Veröffentlicht in Ausgabe 07/2024 - PRAXIS

Die individuelle Konfiguration für Anwendungen wird in sogenannten Dotfiles gespeichert. Hierbei handelt es sich zumeist um versteckte Dateien im Heimatverzeichnis eines Benutzers. Für die zentrale Verwaltung solcher Dateien existieren mehrere Ansätze. Der Open-Source-Tipp in diesem Monat zeigt, wie Sie das GNU-Tool stow zusammen mit Ansible zur Verwaltung dieser Dateien einsetzen.

Üblicherweise suchen Anwendungen ihre Konfiguration entweder im Heimatverzeichnis eines Benutzers oder im Verzeichnis "~/.config". Letzteres ist der Standard für die Variable "XDG_ CONFIG_HOME". Diese ist Teil der allgemeinen XDG-Base-Directory-Spezifikation [1] der Cross-Desktop Group (XDG). Die Spezifikation umfasst mehrere Standards für die Konfiguration von Desktopanwendungen, gilt aber ebenso auch für rein textbasierte Anwendungen.
Nun ist es durchaus wünschenswert, die eigenen Konfigurationsdateien nicht nur lokal vorliegen zu haben, sondern auch zentral zu speichern, beispielsweise innerhalb eines Git-Repositories. Es wäre natürlich relativ einfach, sämtliche Dotfiles lediglich in einem zentralen Verzeichnis vorzuhalten, das unter der Kontrolle von git steht, und dann einfach entsprechende symbolische Links auf diese Dateien zu setzen. Doch genügt dies nicht, denn auch die Anwendungen selbst müssen dort installiert sein, inklusive sämtlicher Abhängigkeiten und der eingesetzten Plug-ins, die wahrscheinlich von den jeweiligen Konfigurationen erwartet werden.
GNU stow und Ansible
Eine recht einfache, aber trotzdem mächtige Lösung für dieses Problem besteht im Einsatz der beiden Tools stow und Ansible. Letzteres dürfe den allermeisten Lesern bekannt sein, stow [2] stammt aus dem GNU-Projekt und wurde ursprünglich dazu entwickelt, um manuell kompilierte Software mithilfe von symbolischen Links auf einem System zu verwalten. Ein netter Nebeneffekt ist, dass Sie diese Funktion natürlich ebenso gut auch auf Konfigurationsdateien anwenden können.
Üblicherweise suchen Anwendungen ihre Konfiguration entweder im Heimatverzeichnis eines Benutzers oder im Verzeichnis "~/.config". Letzteres ist der Standard für die Variable "XDG_ CONFIG_HOME". Diese ist Teil der allgemeinen XDG-Base-Directory-Spezifikation [1] der Cross-Desktop Group (XDG). Die Spezifikation umfasst mehrere Standards für die Konfiguration von Desktopanwendungen, gilt aber ebenso auch für rein textbasierte Anwendungen.
Nun ist es durchaus wünschenswert, die eigenen Konfigurationsdateien nicht nur lokal vorliegen zu haben, sondern auch zentral zu speichern, beispielsweise innerhalb eines Git-Repositories. Es wäre natürlich relativ einfach, sämtliche Dotfiles lediglich in einem zentralen Verzeichnis vorzuhalten, das unter der Kontrolle von git steht, und dann einfach entsprechende symbolische Links auf diese Dateien zu setzen. Doch genügt dies nicht, denn auch die Anwendungen selbst müssen dort installiert sein, inklusive sämtlicher Abhängigkeiten und der eingesetzten Plug-ins, die wahrscheinlich von den jeweiligen Konfigurationen erwartet werden.
GNU stow und Ansible
Eine recht einfache, aber trotzdem mächtige Lösung für dieses Problem besteht im Einsatz der beiden Tools stow und Ansible. Letzteres dürfe den allermeisten Lesern bekannt sein, stow [2] stammt aus dem GNU-Projekt und wurde ursprünglich dazu entwickelt, um manuell kompilierte Software mithilfe von symbolischen Links auf einem System zu verwalten. Ein netter Nebeneffekt ist, dass Sie diese Funktion natürlich ebenso gut auch auf Konfigurationsdateien anwenden können.
Stow verwaltet zusammengehörige Dateien in sogenannten Packages, die in einem Stow-Verzeichnis liegen. Als Zielordner bezeichnet stow das Verzeichnis, in dem es symbolische Links auf die Packages und die darin enthaltenen Dateien erzeugt. Dies ist zumeist das Heimatverzeichnis eines Benutzers, der Ordner "~/.config" oder eben der Ordner, der der Variablen "XDG_CONFIG_HOME" zugewiesen wurde. Verwenden Sie also beispielsweise "~/dotfiles" als stow-Verzeichnis, in dem sich das Package zsh mit der Datei "zshrc" befindet, rufen Sie stow wie folgt auf, um einen symbolischen Link im Heimatverzeichnis zu erzeugen:
stow --target $HOME --dir $HOME/dotfiles/ zsh
Das Ergebnis sieht dann so aus:
ls ~/.zshrc
/root/.zshrc -> dotfiles/zsh/.zshrc
Das Bild zeigt eine einfache Struktur eines stow-Verzeichnisses. Da es sich bei den Konfigurationsdateien ja oftmals um verstecke Dateien handelt, bietet stow ein ganz nettes Feature an, um nicht nur mit leeren Packages-Verzeichnissen zu arbeiten. So können Sie statt des Punkts am Anfang des Dateinamens auch einfach ein "dot-" verwenden. Rufen Sie stow dann mit der Option "--dotfiles" auf, macht stow daraus wieder einen Punkt und versteckt somit die Datei im Zielverzeichnis (Listing 1).
Das stow-Verzeichnis enthält Pakete, die wiederum aus Konfigurationsdateien bestehen.
Listing 1: Dotfiles mit "dot-" kennzeichnen
ls ~/dotfiles/zsh/dot-zshrc
/root/dotfiles/zsh/dot-zshrc
stow --dotfiles --target $HOME --dir $HOME/dotfiles/ zsh
ls -l ~/.zshrc
/root/.zshrc -> dotfiles/zsh/dot-zshr
Ansible-Rolle und Playbook
Um nun auch die einzelnen Softwarepakete und die jeweiligen Abhängigkeiten zu installieren, erzeugen Sie eine neue Ansible-Rolle. Innerhalb dieser Rolle können Sie dann auch das stow-Tool aufrufen, um die Konfigurationsdateien auf dem gewünschten System zu deployen. Eine neue Rolle erzeugen Sie beispielsweise mithilfe von ansible-galaxy:
ansible-galaxy role init dotfiles
Das Tool legt eine passende Verzeichnisstruktur mit den notwendigen Dateien an, um eine neue Rolle zur Verwaltung der dotfiles zu entwickeln:
ls dotfiles/
defaults  files  handlers  meta  README.md  tasks  templates  tests  vars
Listing 2 zeigt, wie Sie in der Datei "defaults/mains.yml" einige Defaultvariablen setzen, um auf diese dann innerhalb der eigentlichen Task-Datei zurückgreifen zu können. Zumindest sollten Sie hier das Stow- und Target-Verzeichnis sowieso die Repository-URL für Ihre dotfiles angeben.
Listing 2:Defaultvariablen in "main.yml"
---
dotfiles_repo: "https://git.example.com/users/tscherf/dotfiles.git/"
dotfiles_repo_local_destination: "{{ ansible_env.HOME }}/dotfiles"
dotfiles_home: "{{ ansible_env.HOME }}"
Aufgaben definieren
In Listing 3 finden Sie einfache Beispiele für einige Tasks, die diese Ansible-Rolle nun ausführen soll. Es kommen ausschließlich Module zum Einsatz, die Teil des ansible-core-Pakets sind und somit auf jedem System zur Verfügung stehen, auf dem Ansible installiert ist. Als Modul für den Paketmanager kommt hier dnf zum Einsatz, aber natürlich können Sie stattdessen auch ein anderes Modul verwenden, je nachdem, welchen Paketmanager Sie zur Installation von Software einsetzen.
Listing 3: Tasks in "main.yml"
---
- name: Update dnf cache
  ansible.builtin.dnf:
    update_cache: true
  become: true
- name: Install stow and git
  ansible.builtin.package:
    name:
      - stow
      - git
    state: present
  become: true
- name: Install terminal applications
  ansible.builtin.package:
    name:
      - neovim
      - tmux
      - zsh
    state: present
  become: true
- name: Ensure dotfiles repository is cloned on target system
  ansible.builtin.git:
   repo: "{{ dotfiles_repo }}"
   dest: "{{ dotfiles_repo_local_   destination }}"
  become: false
- name: Build package list
  ansible.builtin.find:
    paths: ["{{ dotfiles_repo_local_destination }}"]
    depth: 1
    file_type: directory
  register: files
  become: false
- name: Deploy dotfiles
  with_items: '{{ files.files }}'
  ansible.builtin.command:
    cmd: stow --dotfiles --target= {{ dotfiles_home }} --dir {{ dotfiles_repo_local_destination }} {{ item.path | basename }}
    chdir: "{{ dotfiles_repo_local_destination }}"
  register: result
  changed_when: 'result.stderr is search("LINK: ")'
  become: false
Neben der Installation der beiden Pakete stow und git erfolgt ebenfalls die Installation der eigentlichen Anwendungen, für die Sie Konfigurationsdateien bereitstellen möchten. Im Anschluss kümmert sich ein Task darum, ein Checkout des Git-Repositories durchzuführen. Aus den einzelnen stow-Packages in diesem Repository wird dann eine Liste erzeugt. Im letzten Task verwenden Sie diese Liste dann, um mittels stow die Dateien der einzelnen Packages aus dem Target-Verzeichnis heraus zu verlinken.
Ansible-Playbook
Um diese Rolle nun auf einem System zu verwenden, können Sie das Playbook aus Listing 4 verwenden. Dieses geht davon aus, dass es auf dem System zum Einsatz kommt, auf dem Sie die Ansible-Rolle verwenden möchten. Wie auch die Rolle selbst, können Sie dieses natürlich entsprechend Ihrer eigenen Bedürfnisse anpassen. Das Playbook rufen Sie dann wie folgt auf:
ansible-playbook dotfiles-play.yml
Listing 4: Playbook "dotfiles-play.yml"
- hosts: localhost
  roles:
    - { role: dotfiles }
  become: true
Fazit
Zentral gespeicherte Konfigurationsdateien bieten den Vorteil, dass sie stets zur Verfügung stehen, auch auf neuen Systemen. Die Kombination aus Ansible und stow erlaubt eine einfache Verwaltung von Konfigurationsdateien und ermöglicht es ebenfalls, Softwarepakete und Plug-ins für Ihre Anwendungen zu installieren. Wer mehr über Ansible-Rollen erfahren möchte, dem sei ein Blick in die passende Ansible-Dokumentation empfohlen [3].
(dr)
Link-Codes