versionskontrolliertes Arch-Linux-Setup

Verwaltung einer Arch Linux-Installation in GitLab

Einleitung

Arch Linux ist ein Betriebssystem, das bei jedem anders aussieht: Nutzer von Arch Linux passen ihr System üblicherweise im Laufe der Zeit immer weiter auf die eigenen Bedürfnisse und Vorlieben an, bis die Installation keiner anderen mehr gleicht. So auch bei mir: Im Laufe der Jahre, habe ich sehr viele kleine Helfer-Skripte geschrieben, die mir den Alltag erleichtern, benutzerdefinierte Shortcuts eingerichtet und meine häufig genutzten Programme stark modifiziert. Wie kann ich die Änderungen, die ich regelmäßig an meinem Setup vornehme optimal verwalten und sichern? Wie kann ich mein Setup auf mehreren Computern verwenden, ohne dass die Konfiguration auf beiden Computern Stück für Stück auseinander driftet?

Ich habe eine Lösung gefunden, die größtenteils auf einer Reihe von Blog-Artikeln von Michael Daffin basiert. Ich habe das Setup jedoch an meine Bedürfnisse angepasst und erweitert.

Die Idee

Mein Setup besteht eigentlich nur aus zwei Kernideen:

  1. Die Nutzung von dotbot zur Sicherung der Config-Dateien
  2. Der Verwaltung der installierten Programme mithilfe von Meta Packages

dotbot

Der einfachste Teil des Setups ist die Auslagerung aller Config-Dateien in ein Git-Repository. Hier kommt dotbot zum Einsatz. Mithilfe von dotbot können alle dotfiles in ein zentrales Repository verschoben werden. Das Tool erstellt anschließend Symlinks an den ursprünglichen Speicherorten der dotfiles. Das bietet zusätzlich den Vorteil, dass nun alle config-Dateien an einem zentralen Ort bearbeitet werden können. Anleitungen zur Einrichtung von dotbot gibt es bereits sehr viele, deshalb soll das nicht der Fokus dieser Anleitung sein.

Meta Packages

Was sind Meta Packages?

Arch verwendet den Paketmanager pacman. Die meisten Pakete haben Abhängigkeiten zu anderen Paketen. Pacman löst die Abhängigkeiten auf und installiert alle weiteren benötigten Pakete mit. Es gibt jedoch auch Pakete, die ausschließlich Abhängigkeiten zu anderen Paketen haben, selbst aber keinen Quellcode beinhalten. Das sind Meta Packages. Meta Packages fassen also sozusagen mehrere kleine Pakete zu einem großen Paket zusammen. Diesen Mechanismus machen wir uns zunutze: Wir erstellen ein Meta Package, das Abhängigkeiten zu allen Paketen hat, die wir für unser System benötigen.

Der Meta-Package-Baum

Wir können nicht nur ein Meta Package erstellen, das Abhängigkeiten zu allen benötigten Packages hat, wir können auch weitere Meta Packages als Abhängigkeiten definieren. Somit können wir unser System in einzelne Bereiche unterteilen. Das kann dann z.B. so aussehen (nur ein kleiner Ausschnitt aus meinem Baum):

Ein Ausschnitt aus meinem Baum aus Meta Packages

Der Vorteil? Wenn ich einen Computer nur für Office-Arbeiten nutzen, installiere ich einfach lukmert-office und schon habe ich alles installiert, was ich brauche.

Unser erstes Meta Package

Um unser erstes Paket zu erstellen, müssen wir nur eine PKGBUILD-Datei anlegen:

pkgname=lukmert-full
pkgver=1.0.0
pkgrel=1
pkgdesc="Some description"
arch=('any')
url='https://gitlab.com/lukas-mertens/arch-pkgs'
license=('MIT')
depends=(
	lukmert-archiving
	lukmert-graphics
	lukmert-desktop
	lukmert-dev-full
	lukmert-study
)

Diese Datei können wir nun mit dem Befehl makepkg -d -s -f bauen. Da wir eventuell unsere eigenen Meta Packages referenzieren, die unser System noch nicht finden kann, müssen wir die Option -d nutzen.

Unser eigenes Package-Repository

Weil wir unsere Packages nicht immer per Hand bauen wollen, erstellen wir unser eigenes Package-Repository mithilfe von GitLab-Pages. Ich gehe im Folgenden von folgender Ordnerstruktur aus:

.
├── .gitlab-ci.yml
├── aur-packages.conf
├── lukmert-base
│   ├── PKGBUILD
├── lukmert-desktop
│   └── PKGBUILD
├── lukmert-dev-android
│   └── PKGBUILD
...
├── Makefile

Am einfachsten ist es mein GitLab-Repository zu forken, um die Grundlage für das eigene Setup zu haben.

In der Makefile steckt die zentrale Logik zum Bauen der Pakete:

all::
	rm -rf public
	rm -rf aur
	mkdir aur
	cd aur && cat ../aur-packages.conf | xargs yay -G
	find . -type f -name PKGBUILD -execdir makepkg -d -s -f --noconfirm \;
	mkdir public -p
	cp **/*.tar.xz public -n
	cd aur && cp **/*.tar.xz ../public -n
	repo-add public/lukmert.db.tar.gz public/*.pkg.tar.xz
	cd public && tree -H '.' -L 1 --noreport --charset utf-8 > index.html
clean::
	rm -rf public
	rm -rf aur
	rm -rf **/*.tar.xz
	rm -rf **/src
	rm -rf **/pkg

Da wir später unser Paket einfach mit pacman installieren wollen, müssen wir noch einen kleinen Schritt bedenken, damit wir auch Pakete aus dem AUR nutzen können: Packages aus dem AUR müssen von uns gebaut und ebenfalls bereitgestellt werden.

WICHTIG: Wir bauen hier automatisiert Pakete aus dem AUR und vertrauen diesen bei der Installation. Das kann ein Sicherheitsrisiko darstellen, weil Pakete aus dem AUR nicht von den Arch-Maintainern kontrolliert werden und somit potenziell schädlich sein könnten.

Zuerst wird die PKGBUILD aller Pakete in der Datei aur-packages.conf heruntergeladen. Anschließend werden alle Pakete, sowohl die Pakete aus dem AUR, als auch unsere Meta Packages gebaut. Anschließend werden alle gebauten Pakete nur noch in den Ordner public verschoben, damit sie später per GitLab-Pages deployed werden können. Damit wir das Repository später auch einbinden können, wird aus allen erzeugten Paketen mit dem Befehl repo-add ein Package-Repository erzeugt. Der letzte Befehl ist optional: Er erzeugt noch eine index.html-Datei, damit wir später einen einfachen Dateiexplorer haben, um die gebauten Packages auch im Browser anzuzeigen.

Die .gitlab-ci.yml ist denkbar einfach:

image: whynothugo/makepkg

pages:
  script:
    - sudo pacman -S cmake tree --noconfirm
    - make
  artifacts:
    expire_in: 1 week
    paths:
    - public
  only:
    - master

Jetzt noch alles nach GitLab pushen und auf die CI-Pipeline warten. Wenn alles durchgelaufen ist, noch folgendes am Ende der /etc/pacman.conf anfügen (den Link natürlich anpassen):

[lukmert]
SigLevel = Optional TrustAll
Server = https://lukas-mertens.gitlab.io/arch-pkgs

Jetzt müsste es ausreichen sudo pacman -Syy auszuführen. Wenn alles geklappt hat, taucht jetzt ein weiteres Repository auf:

:: Synchronisiere Paketdatenbanken...
 core                  136,2 KiB   293 KiB/s 00:00 [-----] 100%
 extra                1649,5 KiB   408 KiB/s 00:04 [-----] 100%
 community               4,9 MiB   415 KiB/s 00:12 [-----] 100%
 lukmert                10,5 KiB  92,4 KiB/s 00:00 [-----] 100% 

Jetzt kann z.B. lukmert-full ganz normal mit sudo pacman -S lukmert-full installiert werden.

Das war es schon! Zum Abschluss noch einige Tipps:

  1. Nicht vergessen die Versionsnummer nach jedem Update der PKGBUILD hochzusetzen! Sonst erkennt pacman nicht, dass es Änderungen gab!
  2. Es ist empfehlenswert mit GitLab Pipeline Schedules einzurichten, dass die Pipeline jede Woche einmal durchläuft. Das sorgt dafür, dass die AUR-Packages einmal pro Woche neu gebaut werden und dann aktualisiert werden, wenn man pacman -Syu nutzt.

Wir hoffen wir konnten helfen! Sollte etwas unklar geblieben sein, freuen wir uns über eine Rückmeldung an blog@devsaur.de!

Lukas Mertens
Geschäftsführer

31.03.2020