Ręczne składanie pakietów
Ostatnia zmiana: 2025-07-06 12:47
W systemie OpenWrt do wydania 24.10 włącznie używany był program
opkg do zarządzana pakietami. Jest on
forkiem starszego programu ipkg i wykorzystuje pliki z rozszerzeniem *.ipk. Technicznie rzecz biorąc, plik ipk jest prostym archiwum plików i innych archiwów. Pakiety ipk tworzone są przez SDK OpenWrt z odpowiednich plików Makefile, ale nic nie stoi na przeszkodzie żeby taki pakiet stworzyć ręcznie, nawet w samym systemie OpenWrt.
Nie jest to polecany sposób tworzenia pakietów dla OpenWrt. Należy używać normalnie SDK OpenWrt.
Na pakiet ipk składają się trzy rzeczy:
- plik o nazwie
debian-binary zawierający informację o wersji formatu (jest to ciąg znaków "2.0" zakończony znakiem nowej linii)
- plik będący archiwum w formacie
tar.gz o nazwie
data.tar.gz zawierający spakowane pliki stanowiące zawartość pakietu
- plik będący archiwum w formacie
tar.gz o nazwie
control.tar.gz zawierający pliki opisujące czym jest zawartość pakietu
Zróbmy więc swój własny pakiet ipk wykorzystując do tego OpenWrt (choć oczywiście można to też zrobić w normalnym linuksie).
Przygotowania
Tworzymy katalog gdzie będziemy wszystko składać. Logujemy się do jakiegoś urządzenia z OpenWrt i robimy:
# mkdir -p /tmp/pakiet
# cd /tmp/pakiet
Wszystko będzie umieszczone w tym katalogu, więc przechodzimy do niego; wszystkie poniższe polecenia wykonujemy już w tym katalogu. Tam też powstanie wynikowy plik *.ipk
debian-binary
To zwykły plik tekstowy, więc jego stworzenie jest proste:
# echo "2.0" > debian-binary
data.tar.gz
To archiwum z plikami które chcemy spakietować. Pliki muszą być już skompilowane, przygotowane w formie nadającej się do bezpośredniego uruchomienia w OpenWrt, z odpowiednimi bibliotekami oraz z odpowiednimi uprawieniami. Wszystkie pliki będą instalowane względem katalogu głównego (root - /).
Do katalogu
files należy skopiować pliki które mają znaleźć się w pakiecie, umieszczone już we właściwych podkatalogach.
Dla testów zróbmy jeden plik będący skryptem wykonywalnym, umieszczonym docelowo w katalogu /usr/bin pod nazwą
witaj-swiecie.sh. Plik będzie miał taką zawartość:
#!/bin/sh
echo "Witaj swiecie!"
exit 0
Jeżeli mamy plik przygotowany w edytorze tekstowym to należy zrobić katalogi w
files i go tam skopiować. Na potrzeby tego poradnika zróbmy go po prostu ręcznie:
# mkdir -p files/usr/bin
# echo '#!/bin/sh' > files/usr/bin/witaj-swiecie.sh
# echo 'echo "Witaj swiecie!"' >> files/usr/bin/witaj-swiecie.sh
# echo 'exit 0' >> files/usr/bin/witaj-swiecie.sh
Nie wolno zapominać o uprawnieniach tego pliku
# chmod 755 files/usr/bin/witaj-swiecie.sh
Tak przygotowaną strukturę katalogową z plikami pakujemy do pliku o nazwie
data.tar.gz
# cd files
# tar -zcvf ../data.tar.gz .
# cd ..
W katalogu /tmp/pakiet powinien powstać plik
data.tar.gz.
control.tar.gz
To archiwum z kolei zawiera trzy pliki:
- postinst, który zawiera standardowe skrypty wykonujące się po zainstalowaniu pakietu
- prerm, który zawiera standardowe skrypty wykonujące się przed odinstalowaniem pakietu
- control, opisujący sam pakiet
Robimy katalog gdzie w/w pliki będą utworzone:
Dwa pierwsze pliki muszą mieć określoną zawartość więc wystarczy je zrobić:
# echo '#!/bin/sh' > control/postinst
# echo '[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0' >> control/postinst
# echo '[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0' >> control/postinst
# echo '. ${IPKG_INSTROOT}/lib/functions.sh' >> control/postinst
# echo 'default_postinst $0 $@' >> control/postinst
# chmod 755 control/postinst
# echo '#!/bin/sh' > control/prerm
# echo '[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0' >> control/prerm
# echo '. ${IPKG_INSTROOT}/lib/functions.sh' >> control/prerm
# echo 'default_prerm $0 $@' >> control/prerm
# chmod 755 control/prerm
Te pliki to zawartość domyślna z OpenWrt, które nie zawierają skryptów specyficznych dla pakietu uruchamianych po instalacji i przed usunięciem.
Zostaje do utworzenia sam plik
control. Jego dość prosta zawartość wygląda następująco:
Package: <nazwa pakietu>
Version: <pełna wersja z ew numerem rewizji>
Depends: libc <i inne zależności>
Source: <źródło pakietu>
SourceName: <źródło pakietu>
Section: <sekcja do której należy pakiet>
SourceDateEpoch: <znacznik czasowy utworzenia pakietu>
Maintainer: <opiekun pakietu>
Architecture: all <all - dla wszystkich architektur albo określona nazwa jeżeli w pakiecie mają znaleźć się binarki>
Installed-Size: <rozmiar po instalacji>
Description: <opis pakietu>
Taki plik znów można przygotować w edytorze tekstowym lub zrobić go przy pomocy echo. Posłużymy się tą drugą metodą:
# echo 'Package: helloworld' > control/control
# echo 'Version: 20250705-r1' >> control/control
# echo 'Depends: libc' >> control/control
# echo 'Source: helloworld' >> control/control
# echo 'SourceName: helloworld' >> control/control
# echo 'Section: utils' >> control/control
# echo 'SourceDateEpoch: '$(date +%s) >> control/control
# echo 'Maintainer: Jan Kowalski <user@foo.org>' >> control/control
# echo 'Architecture: all' >> control/control
# echo 'Installed-Size: '$(du -kcs files | awk '/total/{print $1*1024}') >> control/control
# echo 'Description: Witaj swiecie' >> control/control
Polecenie
du -kcs files wyświetla zajętość katalogu files, czyli mniej-więcej ile pakiet zajmuje po instalacji, awk służy to przeliczenia tego na bajty. Można teraz wykonać polecenie
aby sprawdzić czy mamy wszystkie pliki. Wynik powinien wyglądać podobnie do tego:
drwxr-xr-x 2 root root 100 Jul 5 08:32 .
drwxr-xr-x 4 root root 120 Jul 5 08:20 ..
-rw-r--r-- 1 root root 241 Jul 5 08:33 control
-rwxr-xr-x 1 root root 160 Jul 5 08:20 postinst
-rwxr-xr-x 1 root root 117 Jul 5 08:20 prerm
Pakujemy to:
# cd control
# tar -zcvf ../control.tar.gz .
# cd ..
Tworzenie pakietu
W rezultacie w katalogu
/tmp/pakiet powinny znajdować się teraz wszystkie niezbędne pliki:
# ls -la
drwxr-xr-x 4 root root 140 Jul 5 08:36 .
drwxrwxrwt 18 root root 520 Jul 5 08:33 ..
drwxr-xr-x 2 root root 100 Jul 5 08:32 control
-rw-r--r-- 1 root root 467 Jul 5 08:36 control.tar.gz
-rw-r--r-- 1 root root 208 Jul 5 08:12 data.tar.gz
-rw-r--r-- 1 root root 4 Jul 5 08:01 debian-binary
drwxr-xr-x 4 root root 80 Jul 5 08:16 files
Jeżeli tak jest to robimy pakiet:
# tar -zcvf helloworld_20250705-r1.ipk control.tar.gz data.tar.gz debian-binary
Gdzie nazwa pliku powinna być w formacie "nazwa pakietu" podkreślenie "numer wersji" ipk. Choć to sprawa umowna bo plik może nazywać się też "alamakota.ipk" i też powinno być dobrze.
Sprawdźmy czy plik jest
# ls -la *.ipk
-rw-r--r-- 1 root root 882 Jul 5 08:38 helloworld_20250705-r1.ipk
Sprawdźmy czy da się go zainstalować i czy działa:
# opkg install ./helloworld_20250705-r1.ipk
Installing helloworld (2025-07-05-r1) to root...
Configuring helloworld.
# opkg list-installed | grep helloworld
helloworld - 2025-07-05-r1
# opkg files helloworld
Package helloworld (2025-07-05-r1) is installed on root and has the following files:
/usr/bin/witaj-swiecie.sh
# opkg info helloworld
Package: helloworld
Version: 2025-07-05-r1
Depends: libc
Status: install user installed
Architecture: all
Installed-Time: 1751697614
# ls /usr/bin/witaj-swiecie.sh
/usr/bin/witaj-swiecie.sh
# witaj-swiecie.sh
Witaj swiecie!
W praktyce w/w polecenia można łatwo oskryptować i robić pakiety prawie że automatycznie.
Zakończenie
Należy jeszcze wspomnieć do dwóch oczywistych rzeczach:
- gotowy pakiet ipk można rozpakować - ponieważ jest to archiwum
- zainstalowany pakiet ipk w systemie OpenWrt można wydobyć i zgromadzić wszystkie pliki. Przy odrobinie wytrwałości można z tych plików znów złożyć gotowy pakiet przeznaczony do ponownej instalacji