Yocto – Paket-Management

In diesem Beitrag zeige ich, wie du ein Debian-Paket-Repository für dein Yocto-Image einrichtest. Damit kannst du Anwendungen zentral auf einem Server bereitstellen und von einem laufenden System aus aktualisieren, ohne jedes Mal das Image neu auf eine SD-Karte schreiben zu müssen.

Das Paket-Repository wird Debian-Pakete zur Verfügung stellen, und das Yocto-Image wird um die notwendigen apt-Werkzeuge erweitert. Ich zeige dir, wie du ein Shell-Skript erstellst, das aus der Yocto-Build-Verzeichnisstruktur ein Debian-konformes Repository generiert. Das fertige Repository wird anschließend mit einem Webserver in einem Docker-Container bereitgestellt. Der Docker-Container erkennt zudem Änderungen an den Paketen automatisch und aktualisiert das Repository selbstständig.

Debian-Paketmanagement aktivieren

Als Erstes passen wir die Datei local.conf im Konfigurationsverzeichnis (conf) des Build-Verzeichnisses rpi-build an und erweitern die Variable PACKAGE_CLASSES um das DEB-Paketsystem:

Anschließend wird das Image-Rezept raspilab-image.bb erweitert, um das Debian-Paketmanagement und das Tool apt hinzuzufügen:

Unterschiede zwischen Yocto und Debian Repository-Struktur

Die Verzeichnisstruktur der Debian-Pakete in Yocto unterscheidet sich deutlich von der Struktur eines Debian-konformen Repositories:

Während Yocto eine einfache Struktur verwendet, trennt Debian den Paketpool klar von den Indexdateien. Um diese Struktur zu erzeugen, nutzen wir ein spezielles Shell-Skript.

Automatisiertes Repository per Skript erstellen

Zusammen mit ChatGPT habe ich ein Shell-Skript entwickelt, das automatisch die Debian-konforme Repository-Struktur erstellt. Das Skript sowie das passende Dockerfile findest du in meinem GitHub-Repository.

Im Kopf des Skripts werden einige wichtige Variablen gesetzt:

  • REPO_BASE verweist auf das Verzeichnis mit den Yocto-erzeugten .deb-Dateien. Im Docker-Container zeigt dies meist auf ein gemountetes Volume.
  • WEBROOT ist das Zielverzeichnis für das Debian-konforme Repository, aus dem der Webserver die Daten bereitstellt.
  • DIST und COMPONENT geben Struktur und Namen des Repositories an, etwa „stable/main“.
  • TMPROOT ist ein temporäres Arbeitsverzeichnis, das nach der Index-Erstellung wieder gelöscht wird.

Das Skript erledigt anschließend folgende Schritte:

Vorbereitung des Zielverzeichnisses: Bestehende Daten werden entfernt, um sicherzustellen, dass die Repository-Struktur sauber neu aufgebaut wird.

Symlink-Erstellung: Statt die .deb-Dateien zu kopieren, werden symbolische Links erstellt, um Speicherplatz zu sparen und Zeit zu sparen.

Architektur-Erkennung: Das Skript analysiert die Dateinamen der Pakete, um die Zielarchitekturen zu ermitteln, für die Paketlisten erstellt werden sollen.

Index-Erstellung pro Architektur: Dies ist der aufwändigste und wichtigste Teil des Skripts.
Für jede erkannte Zielarchitektur wird ein separates temporäres Verzeichnis erstellt, das die Struktur eines Debian-Paketpools nachbildet. Dort werden symbolische Links zu den passenden .deb-Paketen eingefügt. Anschließend wird mit dpkg-scanpackages eine Paketliste erzeugt, die alle verfügbaren Pakete und deren Metadaten wie Version, Abhängigkeiten, Prüfsummen und vor allem der Pfad zur Datei im Repository enthält.

Dieser Pfad ist entscheidend, da apt genau diesen nutzt, um Pakete vom Server herunterzuladen. Die erstellte Liste wird dann in mehreren komprimierten Formaten (gzip, bzip2, xz, lzma) gespeichert, um maximale Kompatibilität mit verschiedenen Clients zu gewährleisten. Abschließend werden die Paketlisten in das richtige Verzeichnis im Repository verschoben.

Generierung der Release-Datei: Diese Datei enthält die Metadaten des Repositories, inklusive Prüfsummen.

Aufräumen: Temporär angelegte Verzeichnisse werden gelöscht, um das System sauber zu halten.

Bereitstellung des Paket-Repositories per Python-Webserver

Bevor wir das Repository in einem Docker-Container betreiben, kannst du es auch einfach mit dem in Python integrierten HTTP-Server testen. Dazu wechselst du in das Root-Verzeichnis des Repositories (z. B. /www-root) und startest den Webserver mit folgendem Befehl:

Das Repository ist nun unter http://localhost:8000 erreichbar und kann für Tests direkt in einem Yocto-System verwendet werden.

Bereitstellung des Paket-Repositories per Docker

Um das Paket-Repository dauerhaft und automatisiert bereitzustellen, empfiehlt sich der Einsatz eines Docker-Containers. Der Container übernimmt nicht nur die Bereitstellung per Webserver, sondern auch die Überwachung auf neue oder veränderte .deb-Pakete. Erkennt der Container Änderungen, wird das Repository automatisch neu aufgebaut.

Startskript für den Container

Das Startskript überwacht das Repository-Verzeichnis mithilfe von inotifywait und führt bei Bedarf das Script zur Repository-Erzeugung erneut aus:

Dockerfile

Das folgende Dockerfile installiert alle notwendigen Tools und kopiert die beiden Skripte in das Image:

Docker Compose Datei

Mit dieser Compose-Datei kannst du dein Repository mit einem Befehl starten. Sie bindet das Paketverzeichnis als Volume ein und startet den Webserver unter Port 8000:

Mit docker compose up --build -d wird das Repository erstellt und gestartet. Bei Änderungen an .deb-Dateien erfolgt automatisch ein Rebuild der Paketlisten. Das Repository steht nun unter http://localhost:8000 bereit.

Mit Docker Compose kannst du das Repository bequem bereitstellen:

Zum Anhalten:

Damit steht dir jederzeit ein aktuelles und automatisiertes Debian-Paket-Repository für dein Yocto-basiertes System zur Verfügung.