Förderjahr 2019 / Project Call #14 / ProjektID: 4430 / Projekt: IoT-WatchDog
Debian-Pakete sind der way-to-go, um eine Linux-Distribution up-to-date zu halten - wie wir es auch im IoT-Watchdog tun.
Der Weg vom Source zum Debian-Paket
Es existieren unzählige Anleitungen, Wege und Tools, Debian-Pakete zu bauen - Bis man selbst einen für die eigenen Anforderungen passenden Workflow gefunden hat, sind oft viele Versuche nötig. Unser Weg zum Erfolg nach unzähligen Versuchen und Konversationen mit Debian-Entwicklern hat schlussendlich über den Weg mit debuild geführt.
Unser Ablauf besteht aus 2 Schritten:
- Bauen eines Source-Paketes - hier werden die Quelltexte in ein Debian Paket verpackt.
- Bauen eines "binary"-Paketes aus dem Source-Paket - dieses ist dann zur Installation für den Benutzer gedacht.
Diese Schritte zum Bauen von Paketen laufen üblicherweise auf PCs oder Servern mit x86-64bit Architektur ab - wir wollen hier aber für Raspbian (auf Arm-Basis, 32bit) bauen, also auch "cross-compilen" - keine Angst, klingt komplizierter als es ist.
Vorbereitungen:
Vorher müssen am Build-System benötigte Pakete installiert werden (als root oder via sudo):
aptitude install devscripts build-essential lintian pbuilder qemu-user-static qemu-system-arm debhelper
Vor dem bau-Prozess müssen folgende Umgebungsvariablen gesetzt werden (als normaler Benutzer):
export DEBFULLNAME="Max Muster"
export DEBEMAIL="max.muster@mailbox.org"
Dateistruktur
Die kompletten Dateien für ein Beispiel-Projekt haben wir nach Github gelegt.
Ordner: Wir legen einen neuen Ordner (hier Debianpkgwork/) an, und in diesen Ordner unseren Arbeitsordner rein, zB so:
user@host /home/user/Debianpkgwork/ % git clone git@github.com:IoT-Watchdog/Example-Deb-pkg.git
Dann haben wir folgende Ordnerstruktur:
- Im Grundordner ~/Debianpkgwork/ landen dann die gebauten Pakete
- ~/Debianpkgwork/Example-Deb-pkg/ - hier liegt der Quellcode unseres zu paketierenden Programms
- ~/Debianpkgwork/Example-Deb-pkg/debian/ - Ordner für Metadaten
Wir starten im Ordner mit dem Quellcode der zu bauenden Software - hier legen wir einen Ordner namens "debian" an, in den folgende Dateien kommen:
- changelog: tricky syntax, am besten nur mit "debchange" bearbeiten
- rules - wird ausgeführt, Makefile format
- copyright - enthält die Lizenz
- compat - sehr kurz, inhalt "10"
- control - hier kommen die Meta-Informationen wie Dependencies hinein.
- $paketname.service - optional, wird wenn vorhanden nach /lib/systemd/system/ installiert und aktiviert
Nun müssen Dateien im Ordner debian/ initialisiert werden.
Wir verwenden den Paketnamen "hellodebian" als Beispiel.
Erstmaliges Generieren von debian/changelog mit debchange (dch):
dch --create --newversion 0.0.1 --package hellodebian
Dabei öffnet sich ein Editorfenster - nötiges ändern, abspeichern und schließen.
In Zukunft zum updaten:
dch -i # increment
Generieren des Source-Pakets
Debuild erwartet ein Makefile mit zumindest folgendem Inhalt:
ifeq ($(PREFIX),)
PREFIX := /usr
endif
paketname:
echo "<debug>"
install: paketname
install -d $(DESTDIR)$(PREFIX)/bin/
install -D -m 0755 binaryname $(DESTDIR)$(PREFIX)/bin/
- Eventuelle Kompilierbefehle in "paketname:" einfügen - selbst wenn man nur Skripte installieren will, muss die Sektion jedoch trotzdem vorhanden sein!
- Jeder Ordner, in den Dateien hinkopiert werden muss zuerst angelegt werden - er existiert in der chroot-Umgebung wahrscheinlich noch nicht!
Im Ordner Debianpkgwork/Example-Deb-pkg führen wir (als user) folgendes aus:
debuild -i -us -uc -S
Im Ordner darüber (Debianpkgwork/) landen nun einige Dateien:
Aus dem tar.gz werden jetzt die Binary-Pakete gebaut...
Generieren des Binary-Pakets
Hier arbeiten wir mit pbuilder - der Befehl wird als user root im Ordner Debianpkgwork/ ausgeführt.
Zuerst muss die Build-Umgebung vorbereitet werden.
Für jede gewünschte Zielarchitektur - dies muss nur einmalig passieren (und lädt für armhf ca. 80 MB herunter):
mkdir -p /var/cache/pbuilder/raspbian-buster-armhf/aptcache/
wget http://archive.raspbian.org/raspbian/pool/main/r/raspbian-archive-keyring/raspbian-archive-keyring_20120528.2_all.deb
dpkg -i raspbian-archive-keyring_20120528.2_all.deb && rm raspbian-archive-keyring_20120528.2_all.deb
OS=raspbian DIST=buster ARCH=armhf pbuilder --create
mkdir -p /var/cache/pbuilder/debian-buster-amd64/aptcache/
OS=debian DIST=buster ARCH=amd64 pbuilder --create
Später sollte die Build-Umgebung regelmäßig (täglich) upgedatet werden:
OS=raspbian DIST=buster ARCH=armhf pbuilder update
OS=debian DIST=buster ARCH=amd64 pbuilder update
Das eigentliche Bauen der Packages dann mit:
OS=raspbian DIST=buster ARCH=armhf pbuilder build *.dsc
OS=debian DIST=buster ARCH=amd64 pbuilder build *.dsc
Die Pakete landen dann unter /var/cache/pbuilder/raspbian-buster-armhf/result/ bzw. /var/cache/pbuilder/debian-buster-amd64/result/.
Architekturunabhängig?
Wenn man ein architektur-uinabhängiges Paket bauen will (zB mit nur shellscripts oder web-Zeug:
- in der Datei debian/control die Zeile ändern auf Architecture: all
- bauen der Pakete (als root) mit: OS=raspbian DIST=buster pbuilder build $(ls -1 *dsc --sort=time|head -1)
Signing
Wie man Debian-Pakete korrekt signiert, behandeln wir in einem der nächsten Blogposts - stay tuned!