Aaron Fischer Ingenieur, Vater, Heimwerker, Problemlöser

14 April, 2016

Arch Linux Pakete erstellen und Maintainer werden

TL;DR:

Eine Linux-Distribution wird von vielen freiwilligen Helfern stets aktualisiert und erweitert. Arch Linux hat mit AUR -- dem Arch User Repository -- einen meiner Meinung nach sehr guten Weg gefunden, wie sich jeder daran beteiligen kann. Ein Paket für Arch Linux zu erstellen und zu betreuen ist nicht schwer und erfordert nur ein bisschen Disziplin.

Bei Arch Linux gibt es die Entwickler, die das Kernteam der Distribution bilden. Sie entwickeln das Framework, treffen Entscheidungen und verwalten die core Pakete. Dann gibt es die Trusted User (TU), die Pakete in extra und community pflegen. Wer nicht zu diesem ausgewählten Kreis gehört, kann dennoch Pakete im AUR erstellen und betreuen. Die Pakete können durch Voting in community und dann evtl. sogar nach extra wandern, wenn sie gut betreut werden und viele User ihre Stimme dafür gegeben haben.

Ein solches Paket wollen wir bauen. Ich habe mir das Tool packrom ausgesucht, da ich es für ein kommendes Projekt benötige und es dazu noch kein Paket gibt.

Ein AUR Paket ist grundlegend eine Datei, die beschreibt woher der Sourcecode kommt, wie er zu compilieren ist, welche Abhängigkeiten er hat und welche Dateien wo im System untergebracht werden müssen. Diese Datei wird PKGBUILD genannt und muss nach einem bestimmten Schema aufgebaut werden. Dazu aber später mehr. Zuerst müssen wir uns mit der Software vertraut machen, die wir zu einem Paket schnüren wollen. Wir brauchen einige Informationen.

Projekt erkunden

Das Projekt packrom liegt auf Github in einem Unterverzeichnis. Daher können wir die Download-URL schon mal herausfinden. Da es ein Git-Repository ist, müssen wir sicherstellen, dass der User immer die selbe Version bekommt, egal wie weit die Entwicklung fortgeschritten ist. Wir suchen uns deshalb den letzten Commit heraus, der in diesem Ordner gemacht wurde. Das geht auf der Github-Seite ganz bequem. Die Download-URL ist für uns also git+https://github.com/Uzebox/uzebox.git#commit=7818bc4. Die Versionsnummer 1.3 können wir aus dem Header des Sourcecodes entnehmen.

aur

Weiter geht es mit der Lizenz. Diese Angabe ist extrem wichtig und muss korrekt angegeben werden. Im Sourcecode steht sie glücklicherweise. Bei den meisten anderen Projekten gibt es eine LICENSE Datei, in der die Lizenz beschrieben ist. Dann benötigen wir noch die erforderlichen Abhängigkeiten, die für diese Software erfüllt werden müssen. Hierzu ist nichts zu finden (steht meist in der README oder INSTALL), und auch beim Überfliegen des Sourcecodes konnte ich nichts erkennen. Also können wir davon ausgehen, dass wir keine Abhängigkeiten haben.

Trockentest

Als nächstes müssen wir herausfinden, wie die Software compiliert wird. Ein Blick in das Makefile verrät, dass wir mit make help eine Übersicht der Build-Möglichkeiten erhalten. Für uns relevant ist make release. Die Compiler-Flags können wir bei so einem kleinen Projekt ignorieren. Nach dem Ausführen erhalten wir ein einziges Binary, mit dem Namen packrom. Der Compile-Vorgang ist also mehr als trivial.

PKGBUILD

Erstellen wir nun unser Paket mit der PKGBUILD-Datei. Dazu legen wir ein neues Verzeichnis mit dem Namen packrom an und erstellen dort die PKGBUILD Datei (eine Bash-Datei):

# Maintainer: Aaron Fischer <mail@aaron-fischer.net>

pkgname=packrom
pkgver=1.3
pkgrel=1
pkgdesc='Uzebox(tm) ROM utility'
arch=('any')
license=('GPL3')
url='https://github.com/Uzebox/uzebox'
depends=()
makedepends=()
source=('git+https://github.com/Uzebox/uzebox.git#commit=7818bc4')
md5sums=('SKIP')

build() {
  cd "${srcdir}/uzebox/tools/packrom/"
  make release
}

package() {
  install -Dvm755 "${srcdir}/uzebox/tools/packrom/packrom" "${pkgdir}/usr/bin/packrom"
}

Der Kommentar am Anfang ist eine Konvention und enthält den Namen des aktuellen Maintainers und aller Contributors. Ich trage dort alle Namen ein, die am Paket durch Verbesserungsvorschläge, Bug-Reports oder Anpassungen mithelfen. Darunter kommen einige Variablen. Hier gibt es noch eine Menge mehr, doch dies ist das minimale Set:

Weitere Variablen sind hier zu finden. Die beiden Funktionen build() und package() sind eigentlich selbsterklärend. In der build() Funktion sind alle nötigen Schritte aufgeführt, die zum Compilieren der Software in $srcdir benötigt werden. Die package() Funktion baut das Paket im Zielverzeichnis $pkgdir zusammen. In unserem Fall ist dies nur eine einzelne Datei, die wir mit dem install Befehl an die entsprechende Stelle kopieren können.

Die Philosophie (im Kontrast du Ubuntu) ist, die Software so nah am Ursprungszustand zu belassen wie möglich. Also keine unnötigen Patches, Config-Files oder ähnliches einbauen. Kann etwas nicht compiliert werden oder ist absolut nicht Kompatibel, ist der Entwickler (upstream) die erste Anlaufstelle. Entweder über den Bug-Tracker oder direkt die E-Mail Adresse aus dem Sourcecode suchen und den Entwickler anschreiben. Die Paket-Maintainer sind meist die ersten, die mit einer neuen Version in Berührung kommen.

Testen und bauen

Erstellen wir also unser neues Paket mit dem Tool makepkg:

makepkg -f

Es werden zwei Verzeichnisse src und pkg angelegt. Diese enthalten den Sourcecode und das fertige Paket. Hier kann man noch einmal prüfen, ob alles korrekt war. Lief alles erfolgreich durch, können wir noch namcap nutzen, um unser Paket auf die üblichen Schwachstellen zu testen, die nicht den Package Guuidelines entsprechen.

namcap PKGBUILD

Passt alles, können wir zum letzten Schritt übergeben. Es gibt eine sehr kontroverse Diskusion darüber, warum die Arch Linux Pakete ein Bash-File (PKGBUILD) verwenden, um das Paket zu definieren. Zum einen ist dies sehr flexibel, was extrem praktisch ist, da jede Software anders ist. Anderseits lässt sich ein Bash-File sehr schwer parsen, um die nötigen Informationen herauszufinden. Variablen können dynamisch zusammengebaut werden, in einem if stecken etc. Deshalb gibt es das Tool mksrcinfo, das eine .SRCINFO Datei erstellt, welche ein parserfreundliches Format hat. Macht mksrcinfo einen Fehler, kann man dies dann in der .SRCINFO Datei anpassen. In unserem Fall sollte dies aber keinerlei Probleme geben:

mksrcinfo

Unser Paket ist somit fertig und bereit für den Upload.

Deployment

Grundvoraussetzung ist der Besitz eines Accounts auf AUR. Hier hinterlegen wir in den Einstellungen den eigenen Public-Key und konfigurieren folgendes in unserer ~/.ssh/config:

Host aur.archlinux.org
  IdentityFile ~/.ssh/aur
  User aur

Ist das gemacht, können wir das Deployment starten. Seit ca. einem Jahr lässt sich dies ganz bequem über Git machen und man muss sich nicht mehr mit Web-Formularen herumschlagen.

git init .
git remote add origin git+ssh://aur@aur.archlinux.org/packrom.git
git fetch origin

git add PKGBUILD .SRCINFO
git commit -m "Package creation in version 1.3"
git push --set-upstream origin master

Danach ist unser Paket direkt live. Auf der Webseite lassen sich dann noch ein paar Tags vergeben. Das Paket kann dann wie gewohnt mit yaourt oder einem anderen Paketmanager-Interface installiert werden:

yaourt packrom

Maintaining

Ein letzter wichtiger Schritt fehlt aber noch: Das Paket ist nun in unseren Händen. Wenn die Entwickler eine neue Version herausbringen, muss auch unser Paket aktualisiert werden -- und das möglichst schnell. Deshalb ist es ratsam, sich geeignete Push-Notifications einzurichten. Bei Github ist die Watch-Funktion praktisch. Für Software die noch auf SourceForge liegt, kann eine E-Mail Notification eingerichtet werden. Auch empfehlenswert sind die devel- oder release- Mailinglisten, um am Ball zu bleiben. AUR-User können ebenfalls das Paket mit einem Out of Date-Flag versehen. Hier wird man ebenfalls per E-Mail benachrichtigt. Für statische Seiten gibt es diverse Online-Tools, die eine E-Mail Benachrichtigung schicken wenn sich der Inhalt der Seite ändert. Oder man bittet die Entwickler um eine kurze Info-Mail bei einer neuen Version.

Was also tun bei einer neuen Version? Die PKGBUILD muss angepasst werden, aber wie?

Passt wieder alles, muss die .SRCINFO Datei wieder aktualisiert werden:

mksrcinfo

Danach alles Commiten und pushen.

git add PKGBUILD .SRCINFO
git commit -m "What the change does"
git push

Ich hoffe, ich konnte dem ein oder anderen Mut machen, selbst ein Paket für AUR (oder eine andere Distribution!) zu erstellen. Wer sich das nicht traut kann auch ein Paket ohne Maintainer (Orphans) adoptieren und sich zukünftig darum kümmern. Aktuell sind 1233 Pakete in AUR ohne Maintainer. Einfach auf Adopt Package im rechten Kasten klicken. Viel Erfolg!