Paketmanager opkg: Unterschied zwischen den Versionen

Aus Vu+ WIKI
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: „opkg ist ein Paketmanager, zugeschnitten auf die Bedürfnisse von Embedded Systemen. Die Aufgabe eines Paketmanagers ist, die auf einem System (z.B. unseren VU…“)
 
Zeile 1: Zeile 1:
opkg ist ein Paketmanager, zugeschnitten auf die Bedürfnisse von Embedded Systemen. Die Aufgabe eines Paketmanagers ist, die auf einem System (z.B. unseren VU+ Boxen) installierte Software zu verwalten. Die Software wird dazu in Pakete gebündelt. Mit dem Paketmanager können solche Pakete installiert, deinstalliert und gelöscht werden. Der Paketmanager ermöglicht es, Software-Pakete zentral zusammenzustellen und auch zentral zu verteilen. Dafür greift der Paketmanager auf den '''Feed''' zu - das ist das zentrale Repository, in dem alle Pakete zum Download für den Paketmanager bereitgestellt werden.
+
''opkg'' ist ein Paketmanager, zugeschnitten auf die Bedürfnisse von Embedded Systemen. Die Aufgabe eines Paketmanagers ist, die auf einem System (z.B. unseren VU+ Boxen) installierte Software zu verwalten. Die Software wird dazu in Pakete gebündelt. Mit dem Paketmanager können solche Pakete installiert, deinstalliert und gelöscht werden. Der Paketmanager ermöglicht es, Software-Pakete zentral zusammenzustellen und auch zentral zu verteilen. Dafür greift der Paketmanager auf den [[FEED|Feed]] zu - das ist das zentrale Repository, in dem alle Pakete zum Download für den Paketmanager bereitgestellt werden.
  
 
== Benutzung ==
 
== Benutzung ==
Für die komplette Liste der Befehle, die opkg kennt, gibt man einfach <code>opkg</code> in der Shell ein.
+
Für die komplette Liste der Befehle, die ''opkg'' kennt, gibt man einfach <code>opkg</code> in der Shell ein.
  
 
Die wichtigsten Befehle hier auf einen Blick:
 
Die wichtigsten Befehle hier auf einen Blick:
  
 
{|
 
{|
| opkg update || Akualisiert die Liste der am Feed verfügbaren Pakete
+
| <code>opkg update</code> || Akualisiert die Liste der am Feed verfügbaren Pakete
 
|-
 
|-
| okpg list-upgradable || Zeigt eine Liste aller Pakete an, für die es am Feed eine Aktualisierung gibt
+
| <code>okpg list-upgradable</code> || Zeigt eine Liste aller Pakete an, für die es am Feed eine Aktualisierung gibt
 
|-
 
|-
| opkg upgrade || Aktualisiert alle Pakete, für die es eine neuere Version am Feed gibt
+
| <code>opkg upgrade</code> || Aktualisiert alle Pakete, für die es eine neuere Version am Feed gibt
 
|-
 
|-
| opkg list || Zeigt eine Liste mit allen verfügbaren Paketen an
+
| <code>opkg list</code> || Zeigt eine Liste mit allen verfügbaren Paketen an
 
|-
 
|-
| opkg list-installed || Zeigt eine Liste mit allen installierten Paketen an
+
| <code>opkg list-installed</code> || Zeigt eine Liste mit allen installierten Paketen an
 
|-
 
|-
| opkg install <paketliste> || Installiert ein oder mehrere Pakete
+
| <code>opkg install <paketliste></code> || Installiert ein oder mehrere Pakete
 
|-
 
|-
| opkg remove <paketliste> || Deinstalliert ein oder mehrere Pakete
+
| <code>opkg remove <paketliste></code> || Deinstalliert ein oder mehrere Pakete
 
|}
 
|}
  
 
== Weiterführende Informationen ==
 
== Weiterführende Informationen ==
Für die Benutzung des Paketmanagers sind die jetzt folgenden Informationen nicht wichtig. Das wird sich schnell ändern, wenn man selber Pakete bauen möchte.  
+
Für die Benutzung des Paketmanagers sind die folgenden Informationen nicht wichtig. Das wird sich vermutlich ändern, wenn man selber Pakete bauen möchte.  
  
opkg benutzt drei Verzeichnisse für den Betrieb:
+
''opkg'' benutzt drei Verzeichnisse für den Betrieb:
 
{|
 
{|
| /etc/opkg/ || Konfiguration für opkg; hier wird die Liste aller Feeds abgelegt und die Liste der benutzten Architekturen definiert
+
| <code>/etc/opkg/</code> || Konfiguration für ''opkg''; hier wird die Liste aller Feeds abgelegt und die Liste der benutzten Architekturen definiert.
 
|-
 
|-
| /var/lib/opkg/ || Hier wird der Gesamt-Status der installierten Pakete gespeichert. Dies beinhaltet eine Liste aller Pakete, die am Feed verfügbar sind, als auch Listen mit allen Dateien, die von allen Paketen installiert wurden.  
+
| <code>/var/lib/opkg/</code> || Hier wird der Gesamt-Status der installierten Pakete gespeichert. Dies beinhaltet eine Liste aller Pakete, die am Feed verfügbar sind, als auch Listen mit allen Dateien, die von allen Paketen installiert wurden.  
 
|- style="vertical-align:top;"
 
|- style="vertical-align:top;"
| /usr/lib/opkg/ || Im Verzeichnis /usr/lib/opkg/alternatives werden informationen zu allen Programmen verwaltet, für die es mehrere Installations-Kandidaten gibt. Ein gutes Beispiel ist busybox, welches für eine Vielzahl von Standard-Unix-Programmen eine abgespeckte Variante zur Verfügung stellt. Wenn das Original-Programm ebenfalls installiert werden soll, soll natürlich nicht weiter die Busybox-Variante benutzt werden.
+
| /<code>usr/lib/opkg/</code> || Im Verzeichnis <code>/usr/lib/opkg/alternatives/</code> werden Informationen zu allen Programmen verwaltet, für die es mehrere Installations-Kandidaten gibt. Ein gutes Beispiel ist [[Busybox_und_deren_Befehle|busybox]], welches für eine Vielzahl von Standard-Unix-Programmen eine abgespeckte Variante zur Verfügung stellt. Wenn das Original-Programm ebenfalls installiert wird, soll natürlich nicht weiter die Busybox-Variante benutzt werden.
 
|}
 
|}
  
 
=== Paket-Informationen ===
 
=== Paket-Informationen ===
Informationen zu allen installierten Paketen legt opkg im Verzeichnis '''/var/lib/opkg/info/''' ab. In diesem Verzeichnis befindeen sich zu jedem installierten Paket mehrere Dateien:
+
Informationen zu allen installierten Paketen legt ''opkg'' im Verzeichnis <code>/var/lib/opkg/info/</code> ab. In diesem Verzeichnis befinden sich zu jedem installierten Paket mehrere Dateien:
  
 
{|
 
{|
Zeile 42: Zeile 42:
 
| ''paketname''.list || Liste aller vom Paket installierten Dateien
 
| ''paketname''.list || Liste aller vom Paket installierten Dateien
 
|-
 
|-
| optional ''paketname''.preinst || Script, welches vor Installation von ''paketname'' ausgeführt wurde
+
| ''paketname''.preinst || (optional) Script, welches vor Installation von ''paketname'' ausgeführt wurde
 
|-
 
|-
| optional ''paketname''.postinst || Script, welches nach Installation von ''paketname'' ausgeführt wurde
+
| ''paketname''.postinst || (optional) Script, welches nach Installation von ''paketname'' ausgeführt wurde
 
|-
 
|-
| optional ''paketname''.prerm || Script, welches vor Deinstallation von ''paketname'' ausgeführt wird
+
| ''paketname''.prerm || (optional) Script, welches vor Deinstallation von ''paketname'' ausgeführt wird
 
|-
 
|-
| optional ''paketname''.postrm || Script. welches nach Deinstallation von ''paketname'' ausgeführt wird
+
| ''paketname''.postrm || (optional) Script, welches nach Deinstallation von ''paketname'' ausgeführt wird
 
|-
 
|-
| optional ''paketname''.conffiles || Liste aller vom Paket installierten Konfigurationsfiles, die beim Update nicht überschrieben werden sollen
+
| ''paketname''.conffiles || (optional) Liste aller vom Paket installierten Konfigurationsfiles, die beim Update nicht überschrieben werden sollen
 
|}
 
|}
  
Zeile 101: Zeile 101:
  
 
=== Pakete selber bauen ===
 
=== Pakete selber bauen ===
Ein Paket ist eine Sammlung von zu installierenden Files, Metainformationen sowie vor und nach Installation auszuführenden Scripten. Als Paket-Format wurde dafür das unter Unix seit Ewigkeiten benutzte ar-Format benutzt, mit dem auch Bibliotheken für statische Libraries (.a-Files)  erstellt werden.
+
Ein Paket ist eine Sammlung von zu installierenden Dateien, Metainformationen sowie vor und nach Installation auszuführenden Scripten. Als Paket-Container-Format wird dafür das unter Unix seit Ewigkeiten benutzte ar-Format verwendet, mit dem auch Bibliotheken für statische Libraries (.a-Files)  erstellt werden.
  
In einer .ipkg-Datei befinden sich immer drei Dateien: '''control.tar.gz''', '''data.tar.gz''', '''debian-binary'''. In der Datei control.tar.gz befinden sich alle Meta-Daten zum Programm:
+
In einer .ipk-Datei befinden sich immer drei Dateien: '''control.tar.gz''', '''data.tar.gz''', '''debian-binary'''. In der Datei '''control.tar.gz''' befinden sich alle Meta-Daten zum Programm:
  
* control (diese Datei muss drin sein),
+
* <code>control</code> (diese Datei muss enthalten sein),
* conffiles (optional für Konfigurationsfiles, die nicht überschrieben werden sollen; pro Zeile ein Filename - wird z.B. im Paket "base-files" benutzt, siehe /var/lib/opkg/info/base-files.* auf der Box)
+
* <code>conffiles</code> (optional Datei mit einer Liste von Konfigurationsfiles, die nicht überschrieben werden sollen; pro Zeile ein Filename - wird z.B. im Paket "base-files" benutzt, siehe <code>/var/lib/opkg/info/base-files.*</code> auf der Box)
* preinst, prerm (optional, Shellscripten, die vor dem installieren bzw. löschen ausgeführt werden)
+
* <code>preinst</code>, <code>prerm</code> (optional, Shellscripten, die vor dem installieren bzw. löschen ausgeführt werden)
* postinst, postrm (optional, Shellscripten, die nach dem installieren bzw. löschen ausgeführt werden)
+
* <code>postinst</code>, <code>postrm</code> (optional, Shellscripten, die nach dem installieren bzw. löschen ausgeführt werden)
  
Die Datei data.tar.gz beinhaltet die eigentlichen Paket-Daten, die installiert werden sollen. Die Datei data.tar.gz wird von opkg im Root-Verzeichnis ausgepackt. opkg benutzt dafür seinen eigenen Entpacker, der - im Gegensatz zu ''tar'' pingelig ist, was fehlende Verzeichnisse im Tar-File angeht.
+
Die Datei '''data.tar.gz''' beinhaltet die eigentlichen Paket-Daten, die installiert werden sollen. Die Datei '''data.tar.gz''' wird von ''opkg'' im Root-Verzeichnis ausgepackt. ''opkg'' benutzt dafür seinen eigenen Entpacker, der - im Gegensatz zu ''tar'' pingelig ist, was fehlende Verzeichnisse im Tar-File angeht.
  
 
==== Das ''control'' File ====
 
==== Das ''control'' File ====
 
Bleibt noch das ''control''-File zu erklären. Ein ''control''-File besteht aus einer Reihe von '''Feld: Wert'''-Paaren, mit nachfolgend beschriebener Bedeutung. Dabei sind lediglich die Felder '''Package:''' und '''Architecture:''' Pflichtfelder, es ist aber sinnvoll, wenigstens noch '''Version:''' und '''Description:''' mit anzugeben.
 
Bleibt noch das ''control''-File zu erklären. Ein ''control''-File besteht aus einer Reihe von '''Feld: Wert'''-Paaren, mit nachfolgend beschriebener Bedeutung. Dabei sind lediglich die Felder '''Package:''' und '''Architecture:''' Pflichtfelder, es ist aber sinnvoll, wenigstens noch '''Version:''' und '''Description:''' mit anzugeben.
  
* '''Package:''' ist der Paket-Name ohne die Versions-Nummer
+
* '''Package:''' (Pflichtfeld) ist der Paket-Name ohne die Versions-Nummer
* '''Architecture:''' bestimmt, unter welcher Architektur das Paket sinnvollerweise installiert werden kann. Hier nimmt man "all", wenn es unabhängig vom Prozessor ist, also z.B. ein Python-Script. Ansonsten z.B. armv7ahf-vfp-neon wenn es spezifisch für eine unserer 4k-Boxen ist, weil z.B. ein kompiliertes Binary enthalten ist. Gültige Werte für "Architecture" für deine Box stehen in der Datei /etc/opkg/arch.conf.
+
* '''Architecture:''' (Pflichtfeld) bestimmt, unter welcher Architektur das Paket sinnvollerweise installiert werden kann. Hier nimmt man "all", wenn es unabhängig vom Prozessor ist, also z.B. ein Python-Script. Ansonsten z.B. armv7ahf-vfp-neon wenn es spezifisch für eine unserer 4k-Boxen ist, weil z.B. ein kompiliertes Binary enthalten ist. Gültige Werte für "Architecture" für deine Box stehen in der Datei /etc/opkg/arch.conf.
* '''Version:''' ist die Versionsnummer des Paketes. Hier fährt man sehr gut mit einer numerischen Versionsnummer (z.B. 1.2-r0), da opkg anhand der Versionsnummer alphanumerisch sortiert und entscheidet, ob ein Paket neuer als ein bereits installiertes ist. Versionsnummern a la "gitXXX" sind eher ungeeignet.
+
* '''Version:''' (empfohlenes Feld) ist die Versionsnummer des Paketes. Hier fährt man sehr gut mit einer numerischen Versionsnummer (z.B. 1.2-r0), da opkg anhand der Versionsnummer alphanumerisch sortiert und entscheidet, ob ein Paket neuer als ein bereits installiertes ist. Versionsnummern a la "gitXXX" sind eher ungeeignet.
 +
* '''Description:''' (empfohlenes Feld) ausführliche Beschreibung des Pakets. Dieses Feld kann aus mehreren Zeilen bestehen, wobei nachfolgende Zeilen immer mit einem Leerzeichen beginnnen müssen, Absätze mit " .".
 
* '''Depends:''' beschreibt die Abhängigkeiten zu anderen Paketen. Diese Zeile kann eine Liste von Paketen enthalten, die installiert sein müssen bzw. installiert werden sollen, wenn das Paket installiert wird. Für jedes Paket kann weiter noch angeben werden, welche Version benötigt wird. Das kann man durch (>> Version), (>= Version), (= Version), (<= Version), (<< Version) hinter dem Paketnamen angeben. >>: neuer als, >=: mindestens, =: genau gleich, <=: höchstens, <<: älter als.
 
* '''Depends:''' beschreibt die Abhängigkeiten zu anderen Paketen. Diese Zeile kann eine Liste von Paketen enthalten, die installiert sein müssen bzw. installiert werden sollen, wenn das Paket installiert wird. Für jedes Paket kann weiter noch angeben werden, welche Version benötigt wird. Das kann man durch (>> Version), (>= Version), (= Version), (<= Version), (<< Version) hinter dem Paketnamen angeben. >>: neuer als, >=: mindestens, =: genau gleich, <=: höchstens, <<: älter als.
* '''Description:''' ausführliche Beschreibung des Pakets. Dieses Feld kann aus mehreren Zeilen bestehen, wobei nachfolgende Zeilen immer mit einem Leerzeichen beginnnen müssen, Absätze mit " .".
 
 
* '''Conflicts:''' wenn die Installation dieses Paketes sich mit einem anderen Paket beisst (z.B. wenn beide Pakete gleiche Files installieren), werden die Pakete durch Komma getrennt hier aufgeführt.
 
* '''Conflicts:''' wenn die Installation dieses Paketes sich mit einem anderen Paket beisst (z.B. wenn beide Pakete gleiche Files installieren), werden die Pakete durch Komma getrennt hier aufgeführt.
 
* '''Installed-Size:''' hier kann der vom installierten Paket in Anspruch genommene Speicherplatz in KB angegeben werden
 
* '''Installed-Size:''' hier kann der vom installierten Paket in Anspruch genommene Speicherplatz in KB angegeben werden
Zeile 131: Zeile 131:
 
* '''Suggests:''' Liste von Paketen, für die es vielleicht Sinn macht, zusätzlich zu diesem Paket installiert zu werden - eine noch weichere Depends: Klausel.
 
* '''Suggests:''' Liste von Paketen, für die es vielleicht Sinn macht, zusätzlich zu diesem Paket installiert zu werden - eine noch weichere Depends: Klausel.
  
Als Beispiele kann man sich die tausenden von *.control im Verzeichnis /var/lib/opkg/info/ anschauen. Pro installiertes Paket steht dort die control-Datei, die mit dem Paket ausgeliefert wurde.
+
Als Beispiele kann man sich die tausenden von <code>*.control</code> im Verzeichnis <code>/var/lib/opkg/info/</code> anschauen. Pro installiertes Paket steht dort die ''control''-Datei, die mit dem Paket ausgeliefert wurde.
  
 
==== Ein Script um Pakete zu erstellen ====
 
==== Ein Script um Pakete zu erstellen ====
Mit folgendem Script kann aus einem Installations-Verzeichnis heraus ein fertiges Paket gebaut werden. Dafür ist es nur nötig, eine fertige ''control''-Datei und das fertige data.tar.gz im Verzeichnis abzulegen. Wenn man ein Programm fertig kompiliert hat, lässt es sich üblicherweise mit dem Kommando <code>make install</code> installieren. Man kann aber bei den meisten Programmen heute <code>make install DESTDIR=/media/hdd/install</code> angeben, um das Programm unter einem anderen Root-Verzeichnis, z.B. /media/hdd/install, zu installieren. Von hier kann man noch einmal schauen, was alles installiert würde, und von hier das data.tar.gz-File erstellen.
+
Mit folgendem Script kann aus einem Installations-Verzeichnis heraus ein fertiges Paket gebaut werden. Dafür ist es nur nötig, eine fertige ''control''-Datei und das fertige ''data.tar.gz'' im Verzeichnis abzulegen. Wenn man ein Programm fertig kompiliert hat, lässt es sich üblicherweise mit dem Kommando <code>make install</code> installieren. Man kann aber bei den meisten Programmen heute <code>make install DESTDIR=/media/hdd/install</code> angeben, um das Programm unter einem anderen Root-Verzeichnis, z.B. <code>/media/hdd/install/</code>, zu installieren. Von hier kann man noch einmal schauen, was alles installiert würde, und von hier das ''data.tar.gz''-File erstellen.
  
Das folgende Script wird im Installations-Root ausgeführt:
+
Das folgende Script wird im Installations-Root (z.B. <code>/media/hdd/install/</code>) ausgeführt:
  
 
     #!/bin/bash
 
     #!/bin/bash
Zeile 156: Zeile 156:
 
     ar r $ipk debian-binary control.tar.gz data.tar.gz
 
     ar r $ipk debian-binary control.tar.gz data.tar.gz
  
Für dieses Script wird das '''ar''' aus den Binutils benötigt, hier funktioniert das Busybox-ar nicht. Ein Binutils-Paket für die ARM-Architektur findet sich bei uns im Downloads-Bereich, für MIPSEL wird man fündig, wenn man im Netz nach Debian-Paketen sucht.
+
Wichtig: für dieses Script wird das ''ar'' aus den Binutils benötigt, hier funktioniert das ''ar'' aus Busybox nicht. Ein Binutils-Paket für die ARM-Architektur findet sich bei uns im Downloads-Bereich, für MIPSEL wird man fündig, wenn man im Netz nach Debian-Paketen sucht.

Version vom 14. Juli 2020, 13:13 Uhr

opkg ist ein Paketmanager, zugeschnitten auf die Bedürfnisse von Embedded Systemen. Die Aufgabe eines Paketmanagers ist, die auf einem System (z.B. unseren VU+ Boxen) installierte Software zu verwalten. Die Software wird dazu in Pakete gebündelt. Mit dem Paketmanager können solche Pakete installiert, deinstalliert und gelöscht werden. Der Paketmanager ermöglicht es, Software-Pakete zentral zusammenzustellen und auch zentral zu verteilen. Dafür greift der Paketmanager auf den Feed zu - das ist das zentrale Repository, in dem alle Pakete zum Download für den Paketmanager bereitgestellt werden.

Benutzung

Für die komplette Liste der Befehle, die opkg kennt, gibt man einfach opkg in der Shell ein.

Die wichtigsten Befehle hier auf einen Blick:

opkg update Akualisiert die Liste der am Feed verfügbaren Pakete
okpg list-upgradable Zeigt eine Liste aller Pakete an, für die es am Feed eine Aktualisierung gibt
opkg upgrade Aktualisiert alle Pakete, für die es eine neuere Version am Feed gibt
opkg list Zeigt eine Liste mit allen verfügbaren Paketen an
opkg list-installed Zeigt eine Liste mit allen installierten Paketen an
opkg install <paketliste> Installiert ein oder mehrere Pakete
opkg remove <paketliste> Deinstalliert ein oder mehrere Pakete

Weiterführende Informationen

Für die Benutzung des Paketmanagers sind die folgenden Informationen nicht wichtig. Das wird sich vermutlich ändern, wenn man selber Pakete bauen möchte.

opkg benutzt drei Verzeichnisse für den Betrieb:

/etc/opkg/ Konfiguration für opkg; hier wird die Liste aller Feeds abgelegt und die Liste der benutzten Architekturen definiert.
/var/lib/opkg/ Hier wird der Gesamt-Status der installierten Pakete gespeichert. Dies beinhaltet eine Liste aller Pakete, die am Feed verfügbar sind, als auch Listen mit allen Dateien, die von allen Paketen installiert wurden.
/usr/lib/opkg/ Im Verzeichnis /usr/lib/opkg/alternatives/ werden Informationen zu allen Programmen verwaltet, für die es mehrere Installations-Kandidaten gibt. Ein gutes Beispiel ist busybox, welches für eine Vielzahl von Standard-Unix-Programmen eine abgespeckte Variante zur Verfügung stellt. Wenn das Original-Programm ebenfalls installiert wird, soll natürlich nicht weiter die Busybox-Variante benutzt werden.

Paket-Informationen

Informationen zu allen installierten Paketen legt opkg im Verzeichnis /var/lib/opkg/info/ ab. In diesem Verzeichnis befinden sich zu jedem installierten Paket mehrere Dateien:

paketname.control Datei mit allen Meta-Informationen zum Paket paketname
paketname.list Liste aller vom Paket installierten Dateien
paketname.preinst (optional) Script, welches vor Installation von paketname ausgeführt wurde
paketname.postinst (optional) Script, welches nach Installation von paketname ausgeführt wurde
paketname.prerm (optional) Script, welches vor Deinstallation von paketname ausgeführt wird
paketname.postrm (optional) Script, welches nach Deinstallation von paketname ausgeführt wird
paketname.conffiles (optional) Liste aller vom Paket installierten Konfigurationsfiles, die beim Update nicht überschrieben werden sollen

Mit diesen Informationen ist es ziemlich einfach, zu einem installierten Paket wieder eine ipk-Datei mit einem installierbaren Paket zu bauen. Dafür kann folgendes Script benutzt werden:

   #!/bin/bash
   
   name=$1
   if [ ! -f "/var/lib/opkg/info/$name.control" ]; then
       echo "Paket " $name " ist nicht installiert"
   exit
   fi
   
   builddir=/media/hdd/build.$$
   mkdir $builddir || exit 1
   
   # control-, list- und p-Dateien ins Build-Dir kopieren
   pushd /var/lib/opkg/info > /dev/null
   for file in $name.*; do
       cp $file $builddir/${file#"$name."}
   done
   
   cd $builddir
   
   # tar-Datei mit allen gelisteten Dateien erstellen
   tar -czf data.tar.gz --no-recursion -T list 2>/dev/null
   
   # opkg benötigt für jedes Verzeichnis einen eigenen Eintrag,
   # deswegen das tar-File noch einmal aus- und wieder einpacken.
   mkdir clean
   cd clean
   tar -xf ../data.tar.gz
   tar -czf ../data.tar.gz .
   cd ..
   
   tar -czf control.tar.gz $(ls control conffiles pre* post* 2> /dev/null)
   echo "2.0" > debian-binary
   
   version=$(grep Version: control | sed -e 's/.*: *//')
   package=$(grep Package: control | sed -e 's/.*: *//')
   arch=$(grep Architecture: control | sed -e 's/.*: *//')
   
   ipk=${package}_${version}_${arch}.ipk
   
   ar r $ipk debian-binary control.tar.gz data.tar.gz 2> /dev/null
   popd > /dev/null
   
   mv -i $builddir/$ipk .
   rm -fr $builddir

Pakete selber bauen

Ein Paket ist eine Sammlung von zu installierenden Dateien, Metainformationen sowie vor und nach Installation auszuführenden Scripten. Als Paket-Container-Format wird dafür das unter Unix seit Ewigkeiten benutzte ar-Format verwendet, mit dem auch Bibliotheken für statische Libraries (.a-Files) erstellt werden.

In einer .ipk-Datei befinden sich immer drei Dateien: control.tar.gz, data.tar.gz, debian-binary. In der Datei control.tar.gz befinden sich alle Meta-Daten zum Programm:

  • control (diese Datei muss enthalten sein),
  • conffiles (optional Datei mit einer Liste von Konfigurationsfiles, die nicht überschrieben werden sollen; pro Zeile ein Filename - wird z.B. im Paket "base-files" benutzt, siehe /var/lib/opkg/info/base-files.* auf der Box)
  • preinst, prerm (optional, Shellscripten, die vor dem installieren bzw. löschen ausgeführt werden)
  • postinst, postrm (optional, Shellscripten, die nach dem installieren bzw. löschen ausgeführt werden)

Die Datei data.tar.gz beinhaltet die eigentlichen Paket-Daten, die installiert werden sollen. Die Datei data.tar.gz wird von opkg im Root-Verzeichnis ausgepackt. opkg benutzt dafür seinen eigenen Entpacker, der - im Gegensatz zu tar pingelig ist, was fehlende Verzeichnisse im Tar-File angeht.

Das control File

Bleibt noch das control-File zu erklären. Ein control-File besteht aus einer Reihe von Feld: Wert-Paaren, mit nachfolgend beschriebener Bedeutung. Dabei sind lediglich die Felder Package: und Architecture: Pflichtfelder, es ist aber sinnvoll, wenigstens noch Version: und Description: mit anzugeben.

  • Package: (Pflichtfeld) ist der Paket-Name ohne die Versions-Nummer
  • Architecture: (Pflichtfeld) bestimmt, unter welcher Architektur das Paket sinnvollerweise installiert werden kann. Hier nimmt man "all", wenn es unabhängig vom Prozessor ist, also z.B. ein Python-Script. Ansonsten z.B. armv7ahf-vfp-neon wenn es spezifisch für eine unserer 4k-Boxen ist, weil z.B. ein kompiliertes Binary enthalten ist. Gültige Werte für "Architecture" für deine Box stehen in der Datei /etc/opkg/arch.conf.
  • Version: (empfohlenes Feld) ist die Versionsnummer des Paketes. Hier fährt man sehr gut mit einer numerischen Versionsnummer (z.B. 1.2-r0), da opkg anhand der Versionsnummer alphanumerisch sortiert und entscheidet, ob ein Paket neuer als ein bereits installiertes ist. Versionsnummern a la "gitXXX" sind eher ungeeignet.
  • Description: (empfohlenes Feld) ausführliche Beschreibung des Pakets. Dieses Feld kann aus mehreren Zeilen bestehen, wobei nachfolgende Zeilen immer mit einem Leerzeichen beginnnen müssen, Absätze mit " .".
  • Depends: beschreibt die Abhängigkeiten zu anderen Paketen. Diese Zeile kann eine Liste von Paketen enthalten, die installiert sein müssen bzw. installiert werden sollen, wenn das Paket installiert wird. Für jedes Paket kann weiter noch angeben werden, welche Version benötigt wird. Das kann man durch (>> Version), (>= Version), (= Version), (<= Version), (<< Version) hinter dem Paketnamen angeben. >>: neuer als, >=: mindestens, =: genau gleich, <=: höchstens, <<: älter als.
  • Conflicts: wenn die Installation dieses Paketes sich mit einem anderen Paket beisst (z.B. wenn beide Pakete gleiche Files installieren), werden die Pakete durch Komma getrennt hier aufgeführt.
  • Installed-Size: hier kann der vom installierten Paket in Anspruch genommene Speicherplatz in KB angegeben werden
  • Maintainer: Wer betreut dieses Paket?
  • Priority: extra, optional, required, standard
  • Provides: Für kompliziertere Abhängigkeiten von Paketen mit virtuellen Paketen definiert "Provides:", für welches virtuelle Paket das Paket eine Installation erfüllt. Dafür kann ein Paket z.B. "Depends: vpaket" voraussetzen, und unser Paket "Package: paket" sowie "Provides: vpaket" definieren. Das macht man gerne, wenn man Pakete für spezifische Hardware schnürt, z.B. eine bestimmte Box.
  • Section: Welcher Sektion das Paket zugeordnet werden soll.
  • Replaces: Manchmal gibt es für ein altes Paket ein neues, welches das alte ersetzt. Um Konflikte mit gleichen Files zu verhindern, kann man hier angeben, welches alte Paket unser Paket ersetzt.
  • Source: Quelle des Pakets.
  • Recommends: Liste von Paketen, für die es Sinn macht, zusätzlich zu diesem Paket installiert zu werden. Quasi eine sehr weiche Depends: Klausel.
  • Suggests: Liste von Paketen, für die es vielleicht Sinn macht, zusätzlich zu diesem Paket installiert zu werden - eine noch weichere Depends: Klausel.

Als Beispiele kann man sich die tausenden von *.control im Verzeichnis /var/lib/opkg/info/ anschauen. Pro installiertes Paket steht dort die control-Datei, die mit dem Paket ausgeliefert wurde.

Ein Script um Pakete zu erstellen

Mit folgendem Script kann aus einem Installations-Verzeichnis heraus ein fertiges Paket gebaut werden. Dafür ist es nur nötig, eine fertige control-Datei und das fertige data.tar.gz im Verzeichnis abzulegen. Wenn man ein Programm fertig kompiliert hat, lässt es sich üblicherweise mit dem Kommando make install installieren. Man kann aber bei den meisten Programmen heute make install DESTDIR=/media/hdd/install angeben, um das Programm unter einem anderen Root-Verzeichnis, z.B. /media/hdd/install/, zu installieren. Von hier kann man noch einmal schauen, was alles installiert würde, und von hier das data.tar.gz-File erstellen.

Das folgende Script wird im Installations-Root (z.B. /media/hdd/install/) ausgeführt:

   #!/bin/bash
   
   if [ ! -f "control" -o ! -f "data.tar.gz" ]; then
       echo "Verzeichnis enthält keine Paketdaten"
       exit
   fi
   
   tar -czf control.tar.gz $(ls control conffiles pre* post* 2> /dev/null)
   echo "2.0" > debian-binary
   
   version=$(grep Version: control | sed -e 's/.*: *//')
   package=$(grep Package: control | sed -e 's/.*: *//')
   arch=$(grep Architecture: control | sed -e 's/.*: *//')
   
   ipk=${package}_${version}_${arch}.ipk
   
   ar r $ipk debian-binary control.tar.gz data.tar.gz

Wichtig: für dieses Script wird das ar aus den Binutils benötigt, hier funktioniert das ar aus Busybox nicht. Ein Binutils-Paket für die ARM-Architektur findet sich bei uns im Downloads-Bereich, für MIPSEL wird man fündig, wenn man im Netz nach Debian-Paketen sucht.