Wer mit mehreren Rechnern arbeitet, muss Konfigurationen auf allen Systemen wiederholen. Mit eigenen Metapaketen und einem Repository übertragen Sie Änderungen komfortabel auf alle Arch-Systeme.
Arch Linux gilt als eine der flexibelsten Linux-Distributionen überhaupt. Ausgehend von einem minimalen Grundsystem baut man sich sein persönliches System auf, vom Bootloader über den Lieblingseditor bis hin zum Fenstermanager oder einer grafischen Desktopumgebung. Am Ende gleicht dann kaum eine Arch-Installation der anderen – nicht ohne Grund verzichtet Arch auf eine grafische Installationsroutine.
Alleine mit der Installation eines Pakets endet die Konfigurationsarbeit in der Regel nicht. Wer sich intensiv mit seinem persönlichen System auseinandersetzt, erarbeitet über Jahre hinweg für Fenstermanager wie Openbox, den Editor Vim, die Zsh-Shell oder den Terminalmultiplexer Tmux eigene Konfigurationen und baut zusätzliche Plugins ein. In ähnlicher Art und Weise passt man praktisch jedes Programm auf seinem Rechner an.
Clever konfiguriert
Möchte man nun das liebgewonnene Arch-System auf einen anderen Rechner übertragen, etwa einen neuen Laptop, einen Tablet-PC oder in eine virtuelle Maschine, steht man vor einer zeitaufwendigen und unerfreulichen Arbeit – wer wiederholt sich schon gerne immer wieder? Obendrein ist die Personalisierung des Systems ein fortlaufender Prozess. Ideal wäre es, auch zukünftige Änderungen auf alle Geräte zu übertragen.
Viele Arch-Linux-Anwender schreiben sich daher eigene Installationsskripte. Nicht unüblich ist es auch, Konfigurationsdateien zusammen mit den Dotfiles aus dem Home-Verzeichnis mithilfe einer Versionsverwaltung zu sichern, etwa die .bashrc oder den Ordner (.config/). Dafür bietet sich beispielsweise eine lokale Git-Instanz an.
Zwar erleichtert dieses Vorgehen das Wiederherstellen eines Rechners, eignet sich jedoch nicht besonders dafür, eine Reihe von Geräten zu synchronisieren. In der Regel braucht man auf einem Notebook andere Pakete als auf einer Desktop-Workstation. Auch die Konfiguration der einzelnen Anwendungen und Dienste unterscheidet sich von Rechner zu Rechner.
Um die zweite Herausforderung zu lösen, gibt es einen einfachen Ansatz: In vielen Konfigurationsdateien, wie zum Beispiel auch der ~/.vimrc, lassen sich zusätzliche Einstellungen über einen Eintrag wie source ~/.vimrc.local einbinden. So kann man später die Grundkonfiguration blind von einem Rechner zum anderen kopieren, die jeweils individuellen Einstellungen bleiben erhalten.
Mithilfe von Metapaketen lassen sich beide Probleme lösen. Das erlaubt sowohl das Kopieren der Paketauswahl wie auch das Synchronisieren von Konfigurationsdateien. Die Seite “Creating a Meta-Package” beschreibt ein ähnliches Vorgehen [1], wir hosten die Dateien allerdings in einem lokalen Repository.
Arch-Metapakete
Ein Metapaket unterscheidet sich eigentlich nicht groß von einem normalen Paket, enthält jedoch keine Programmdaten. Stattdessen lässt es sich dazu verwenden, beispielsweise über die Metadaten Abhängigkeiten zu Gruppen zusammenzufassen oder Konflikte mit anderen Paketen zu definieren.
Installiert man ein solches Metapaket, zieht es automatisch alle als Abhängigkeiten definierten Pakete nach. Im Vergleich zu einer simplen Paketliste bietet dieses Vorgehen noch kaum einen Vorteil. Interessant wird es jedoch, sobald man Konfigurationsdateien, eigene Skripte oder Wrapper aus den Ordnern ~/.bin/ oder ~/bin/ in die Metapakete integriert.
Auf diesem Weg lassen sich die Konfigurationsdateien ohne zusätzlichen Aufwand zusammen mit dem Metapaket aktualisieren. Zudem speichert der Paketmanager Pacman, welche Datei aus welchem Paket stammt, und warnt, sobald eine über die Paketverwaltung installierte, aber von Hand modifizierte Datei auf dem Massenspeicher überschrieben werden soll. Pacman hängt in so einem Fall das Suffix .pacnew an die neu zu schreibende Datei (Listing 1).
Listing 1
# pacman -Rdd tux-vim Packages (1) tux-vim-0.0.1-2 Total Removed Size: 1.36 MiB :: Do you want to remove these packages? [Y/n] :: Processing package changes... (1/1) removing tux-vim [#######################] 100% warning: /home/tux/.vimrc saved as /home/tux/.vimrc.pacsave # mv .vimrc.pacsave .vimrc # pacman -S tux-vim [...] :: Processing package changes... (1/1) installing tux-vim [#######################] 100% warning: /home/tux/.vimrc installed as /home/tux/.vimrc.pacnew
So lässt sich leicht der Unterschied zwischen den Konfigurationen ausmachen [2]. Die PKGBUILD-Datei bietet auch eine Option zum Schreiben von Backup-Dateien, falls einmal ein Paket entfernt wird. Die Funktion kommt üblicherweise bei Diensten zum Einsatz, die Konfigurationen unter /etc/ ablegen. Sie lässt sich allerdings auch gut auf Dateien im Home-Verzeichnis übertragen [3].
Es empfiehlt sich, auch Beziehungen zwischen den Metapaketen zu definieren. So sollte zum Beispiel neben vim auch immer ctags und cscope installiert werden, ebenso zu zsh auch zsh-suggestions, zsh-syntax-highlighting, zsh-theme-powerlevel9k und andere praktische Kommandozeilentools, zusammen mit den entsprechenden Dotfiles. Die Gruppierung erfolgt dabei über die selbst erstellten Metapakete tux-vim und tux-zsh. Anstatt nun vim und zsh als Abhängigkeit von tux-base nachzuziehen, geschieht dies dann über die spezifischen Metapakete (Abbildung 1).

Abbildung 1: Das selbst gebaute Paket test-zsh zieht bei der Installation automatisch Zsh samt passender Erweiterungen mit und kopiert auch gleich die richtigen Einstellungen ins System.
Letztendlich lassen sich in den Metapaketen auch Hooks definieren, die nach der Installation oder nach Aktualisierungen Dienste aktivieren oder Rechte von Dateien oder Ordnern korrigieren, die zuvor von Pacman mit Root-Rechten kopiert wurden. Die selbst gestrickten Metapakete bieten somit die Funktion eines Dotfile-Managers wie etwa Dots [4], ohne dass man zusätzliche Tools auf den Rechnern installieren muss. Das übliche pacman -Syu aktualisiert dann nicht nur das System, sondern spielt auch neue Konfigurationen ein und installiert neue benötigte Pakete, die man der Arbeitsumgebung hinzugefügt hat.
Einige der beschriebenen Funktionen ließen sich auch über Paketgruppen umsetzen, aber schon alleine an der Installation neuer Pakete würde eine entsprechende Lösung scheitern: Einmal installiert, zieht die Gruppe später zusätzlich definierte Pakete nicht automatisch nach. Für das Metapaket stellt diese Situation dagegen kein Problem dar – es erkennt die fehlende Abhängigkeit und spielt das Paket beim Aktualisieren des Systems kurzerhand ein.
Metapakete erstellen
Um unter Arch Linux ein Paket zu bauen, sind eine PKGBUILD-Datei und das Kommando makepkg erforderlich. Die PKGBUILD besteht aus simplen Anweisungen und Deklarationen, die Sie mit einem Editor bearbeiten können. Sie enthält alle Metadaten des Pakets und bildet so den zentralen Unterbau der Paketverwaltung. Das Arch-Wiki geht dementsprechend ausführlich auf die Datei und die unterschiedlichen Optionen ein [5].
Um nun das Paket zu bauen, gibt es viele Ansätze. Listing 2 zeigt den generellen Aufbau für die persönliche Konfiguration der Z-Shell anhand des Pakets tux-zsh. Mit tux übernehmen wir im Beispiel den Namen des Benutzers auf dem Testsystem; den Namen passen Sie im Folgenden an Ihren User an. Die Daten dürfen in einem beliebigen Ort im Dateisystem liegen, im Beispiel im Ordner pakete/ im Home-Verzeichnis.
Listing 2
$ tree .
.
|-- common.sh
|-- zsh
|-- _zprofile
|-- zsh.install
|-- _zshrc
|-- zsh.txt
Alle Dateien, die das Paket enthalten soll, müssen im selben Verzeichnis wie die PKGBUILD liegen. In der Datei zsh.install stehen die Hooks post-install() und post-update(), die der Paketmanager beim Installieren oder Aktualisieren des Pakets ausführt (Listing 3). Letztendlich definiert die zsh.txt die Abhängigkeiten des Metapakets (Listing 4).
Listing 3
post_install() {
# set zsh as my default shell
chsh -s /bin/zsh tux
}
post_upgrade() {
# pacman copies the files as root:root
chown -R tux: /home/tux/{.zshrc,.zprofile}
}
Listing 4
zsh zsh-syntax-highlighting zsh-theme-powerlevel9k
Um sich dann in der PKGBUILD nicht immer wiederholen zu müssen, lagern Sie grundlegende Anweisungen in die Datei common.sh im Stammverzeichnis der eigenen Metapakete-Sammlung aus (Listing 5). Den geschilderten prinzipiellen Aufbau befolgen Sie für alle Ihre Metapakete. Auf diese Art müssen Sie nur mit git tag die Versionsnummer setzen, die Version des Metapakets wird dann aus dem Tag abgeleitet (siehe Kasten “Git-Vorbereitungen”). Die Hooks aus der zsh.install und die Abhängigkeiten aus der zsh.txt bindet das System dann automatisch ein.
Listing 5
# package version
gittag=$(git describe --tags --always)
pkgver=${gittag%%-*}
pkgrel=${gittag##*-}
# home directory
home="\${pkgdir}"/home/tux
# add all files in this directory to the package
source=($(find . -maxdepth 1 -type f))
for i in $(seq 1 ${#source[@]}); do sha256sums+=(SKIP); done
# use .txt and .install if they exist for deps an hooks
config_from_files() {
[[ -f "$1.txt" ]] && depends=($(grep -v "^#" "$1.txt"))
[[ -f "$1.install" ]] && install="$1.install"
return 0
}
# for convenience
INSTALL_="install -D -o tux -g tux --verbose --backup --compare -m644"
INSTALLX="install -D -o tux -g tux --verbose --backup --compare -m750"
INSTALLD="install -d -o tux -g tux --verbose --backup --compare "
Git-Vorbereitungen
Um die eigenen Daten besser zu organisieren, greifen Sie auf die Versionsverwaltung Git zurück. Mit den ersten zwei Kommandos aus Listing 7 erstellen Sie das Datenverzeichnis. Mit git init initialisieren Sie das Git-Repository. Anschließend legen Sie das Verzeichnis für das Zsh-Paket an und kopieren die gewünschten Daten. Um das Git-Repository zu befüllen, müssen Sie nun einmalig Ihre Benutzerinformationen mit git config --global hinterlegen. Anschließend fügen Sie alle Daten aus dem aktuellen Verzeichnis zum Git-Repository hinzu, committen die Änderung und setzen einen Git-Tag mit der Version (Listing 6).
Listing 6
$ mkdir ~/pakete $ cd ~/pakete $ git init Leeres Git-Repository in /home/tux/pakete/.git/ initialisiert $ mkdir zsh $ cp ~/.zshrc ~/pakete/zsh/_zshrc $ cp ~/.zprofile ~/pakete/zsh/_zprofile $ git config --global user.email "mail@tuxhausen.de" $ git config --global user.name "Kalle Pinguin" $ git add . $ git commit [master (Root-Commit) 9f369a4] First 6 files changed, 61 insertions(+) create mode 100644 common.sh create mode 100644 zsh/.zshrc create mode 100644 zsh/PKGBUILD [...] $ git tag 1.0.0-1
Die für die persönliche ZSH-Konfiguration verantwortliche PKGBUILD finden Sie in Listing 7. Nach dem Erstellen der nötigen Dateien besteht der Großteil der zukünftigen Wartungsarbeit darin, die Paketlisten zu aktualisieren (Listing 8).
Listing 7
# Maintainer: Kalle Pinguin <mail@tuxhausen.de>
pkgname='tux-zsh'
pkgdesc="zsh personalization"
arch=('any')
license=('GPL2')
source ../common.sh
package_tux-zsh() {
config_from_files zsh
local home=$(eval echo "${home}")
# Install oh-my-zsh, autosuggestions and all the rest here
# Package home files as backup (replace initial _ for .)
for file in "${source[@]}"; do
local f=$(basename "${file}" | sed 's=^_=.=')
[[ "${f}" =~ ^\..* ]] || continue
$INSTALL_ "${file}" "${home}"/"${f}"
backup+=("home/tux/${f}")
done
}
Listing 8
$ pacman -Qqen > pkglist.txt $ pacman -Qqem > localpkglist.txt
Arch-Repository selbst hosten
Nachdem nun die selbst erstellten Pakete und Metapakete bereitliegen, gilt es, sie über ein Repository zwischen den eigenen Rechnern zu synchronisieren. Ein Repository besteht aus nicht mehr als einer Sammlung von Paketen sowie einer Datenbank, die die Pakete in einer Liste organisiert und Metadaten zu den einzelnen Paketen bereitstellt. Die Datenbankdatei erstellt später die Helper-Applikation repo-add.
Pacman unterstützt das Einlesen der Datenbank und der Pakete von unterschiedlichen Quellen. Dazu zählen das eigene Dateisystem (nützlich, um Pakete von USB oder CD/DVD einzuspielen) sowie Netzwerkdienste wie HTTP oder FTP. Dazu installieren Sie zum Beispiel einen Apache-Webserver und richten einen virtuellen Host auf Port 8888 ein. Den dafür nötigen Eintrag in der Datei /etc/apache2/sites-available/arch-repo.conf finden Sie in Listing 9. Mit sudo a2ensite arch-repo aktivieren Sie den Host.
Listing 9
Listen 8888 <VirtualHost *:8888> DocumentRoot /pfad/zu/repo </VirtualHost> <Directory /pfad/zu/repo> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory>
Sie müssen für den Einstieg aber keineswegs einen Webserver konfigurieren: Alternativ hosten Sie die Paketquelle über eine Samba- oder NFS-Datenfreigabe im lokalen Netzwerk. Beide Konfigurationen finden sich in den Beispielen, das Anbinden des Repositories über den Webserver ist allerdings auskommentiert.
Damit stehen jetzt alle benötigen Komponenten bereit. Es fehlt nur noch ein Skript, das alles miteinander verbindet (Listing 10). Sobald Sie Änderungen in der unter ~/pakete/ gesicherten Konfiguration vornehmen, führen Sie es aus. Es erstellt die Metapakete, schreibt eine neue Datenbankdatei und kopiert die Daten via SSH auf den Webserver mit dem Repository oder – wie hier im Beispiel – in ein lokales Verzeichnis (Abbildung 2).
Listing 10
#!/bin/bash set -e for d in $(ls -d */); do (cd $d && makepkg -f -c); done pkgs=$(find -name 'tux-*.pkg.tar.xz') repo-add tux.db.tar.xz $pkgs ### Kopieren der Pakete via SSH auf einen Webserver: # scp tux.db $pkgs server:/pfad/zu/repo ### Kopieren der Daten in einen Ordner, der etwa über ### eine Netzwerkfreigabe im LAN zur Verfügung steht cp tux.db $pkgs /home/tux/repo git clean -fd .

Abbildung 2: Ein Blick in den Ordner mit der eigenen Paketquelle. Alternativ lagern Sie Ihre Pakete auf einen Webserver aus, sodass die Paketquelle auch über das Internet zur Verfügung steht.
Damit Pacman das neue Repository verwendet, fügen Sie es noch der Paketverwaltung hinzu. Dazu dient ein Eintrag in der Datei /etc/pacman.conf (Listing 11). Er wird auf allen Systemen fällig, die auf das Repository zugreifen sollen. Installieren Sie nun über die Paketverwaltung die eigenen Meta- und Konfigurationspakete (hier im Beispiel tux-zsh), aktualisiert das System auch automatisch die eigene Paketsammlung samt Konfigurationen (Listing 12).
Listing 11
### Repository über einen Webserver aufrufen # [tux] # SigLevel = Optional TrustAll # Server = http://webserver:8888/ ### Repository in lokalem Verzeichnis oder ### über eine ins Dateisystem gemountete Freigabe [tux] SigLevel = Optional TrustAll Server = file:///home/tux/repo
Listing 12
$ sudo pacman install tux-zsh
[...]
resolving dependencies...
looking for conflicting packages...
Packages (4) tux-zsh-1.0.0-1
Total Download Size: 4.65 MiB
Total Installed Size: 7.91 MiB
Net Upgrade Size: 0.02 MiB
:: Proceed with installation? [Y/n]
Fazit
Um später die Zsh-Konfiguration zu verändern, bearbeiten Sie die Konfiguration in ~/pakete/zsh. Mit git add . und git commit, ausgeführt im Verzeichnis ~/pakete/, übertragen Sie die Änderung ins Git und setzen mit git tag Version dann eine neue Versionsnummer. Anschließend führen Sie wieder das Build-Skript aus, das ein neues Paket baut und es gleich ins Repository überträgt, aus dem dann sämtliche angebundenen Rechner das Update erhalten.
Die Flexibilität der Pacman-Paketverwaltung von Arch Linux unterstützt zahlreiche Optionen, das eigene System zu pflegen. Mit der vorgestellten Methode müssen Sie wichtige Einstellungen nicht für jedes Ihrer Systeme wiederholen, sondern lagern alles inklusive den Paketlisten in einem eigenen Repository. So lässt sich schnell ein System wiederherstellen oder ein neuer Rechner entsprechend der eigenen Vorstellungen aufsetzen.
Glossar
-
Dotfiles
-
Dateien und Ordner, deren Name mit einem Punkt (engl.: “dot”) beginnt, werden von unixoiden Betriebssystemen als versteckt behandelt.
Infos
-
“Creating a Meta-Package”: https://disconnected.systems/blog/archlinux-meta-packages/#creating-a-meta-package
-
“Pacman/Pacnew and Pacsave”: https://wiki.archlinux.org/index.php/Pacman/Pacnew_and_Pacsave
-
Definition eines Backups in der PKGBUILD-Datei: https://wiki.archlinux.org/index.php/PKGBUILD#backup
-
Das Arch-Wiki zu
PKGBUILD: https://wiki.archlinux.org/index.php/PKGBUILD





