Dispositif de système de traitement par lots OpenWrt

Le système d'exploitation OpenWrt est couramment utilisé comme micrologiciel pour les routeurs. L'application typique est de définir et d'oublier. Mais si tout à coup quelque chose ne vous suffit pas, vous devrez alors comprendre le kit de distribution.











OpenWrt utilise opkg comme gestionnaire de paquets, ou plutôt comme son propre fork . Les ingénieurs Debian le trouveront familier à bien des égards: commandes similaires, format similaire du référentiel et des paquets.



Je voulais patcher LUCI (cela ne sera pas dans l'article), mais je n'ai pas trouvé d'introduction rapide adéquate, j'ai dû collecter indépendamment des fragments d'informations à partir de documentation dispersée, d'articles et d'exemples, en regardant le code et les résultats du travail. En prime, j'ai collecté un package primitif (mais inutile en pratique) qui n'est pas encore dans le référentiel. Je partage le programme éducatif collecté ci-dessous.



Dispositif de référentiel



Il existe un fichier dans le système de fichiers OpenWrt /etc/opkg/distfeeds.conf



qui spécifie la liste système (fournie par les développeurs OpenWrt et opkg) des référentiels. Les référentiels propres et tiers peuvent être spécifiés dans /etc/opkg/customfeeds.conf



. Le format est une ligne, se compose de trois mots:



  1. src



    ou src/gz



    , cela dépend Packages



    si le fichier sera téléchargé ou Packages.gz



    . A en juger par le code, il existe d'autres options pour le premier mot, mais je n'ai trouvé aucun référentiel pour lequel cela serait pertinent. Malgré le src



    nom, c'est un référentiel pour les paquets binaires. L'opkg n'a pas de format de référentiel spécial pour les paquets source similaire à celui utilisé dans Debian / APT.
  2. Le nom du référentiel ou "feed" dans la terminologie opkg / OpenWrt.
  3. L'URL qui contient le Packages



    / Packages.gz



    .


Lorsqu'il est exécuté ou ajouté opkg update



à l'URL , la liste des packages et des signatures est enregistrée , le fichier est nommé en fonction du deuxième mot de la liste des référentiels. Il en résulte deux conclusions importantes:/



Packages



Packages.gz



/tmp/opkg-lists







  1. Au redémarrage, le cache sera effacé. Sur les systèmes embarqués tels que les routeurs, cela est parfaitement logique.
  2. Vous /etc/opkg/customfeeds.conf



    pouvez remplacer les flux système par les vôtres, en leur donnant le même nom. opkg jurera, mais avalera le remplacement, ajoutant le fichier désiré au lieu de celui chargé précédemment.


En même temps, il sera chargé Packages.sig



, ce qui devrait contenir le hachage de la liste des paquets décompressés. La liste elle-même répertorie simplement les packages, il y a plusieurs valeurs pour chaque package, les valeurs des différents packages sont séparées par une ligne vide. Voici les champs les plus importants pour chaque package:



  • Package



    , nom du paquet;
  • Version



    , version, s'il existe plusieurs packages avec le même nom, vous pouvez sélectionner la version, la dernière sera installée par défaut;
  • Depends



    , en fonction des autres packages, le gestionnaire de packages installera les packages listés s'ils ne sont pas présents dans le système;
  • Filename



    , le chemin d'accès au fichier est relatif à l'URL de base du référentiel, généralement le référentiel est plat et tout est au même endroit que `Packages.gz`;
  • SHA256sum



    le hachage du package déclaré par le référentiel.


Si vous voulez plus de détails, vous pouvez simplement lire l'une de ces listes directement dans votre navigateur .



Paquets binaires



Les paquets binaires sont presque identiques aux paquets Debian. La différence est la suivante:



  1. Extension .ipk



    au lieu de .deb



    .
  2. `tar` gzip



    , . Debian ar



    , .tar.xz



    , .


Si vous changez l'extension de package pour OpenWrt .tar.gz



et la décompressez, vous trouverez à l'intérieur deux archives et un fichier texte. Le fichier est nommé debian-version



, il contient la version du format de fichier binaire et n'est pas très intéressant pour nous, dans les systèmes modernes cette version est toujours égale à 2.0



.



L'archive data.tar.gz



contient des fichiers exécutables, des fichiers de configuration et tout ce pour quoi le package est installé. Si vous le décompressez à la racine du FS, vous obtiendrez tous les fichiers attendus aux bons endroits, dans /usr/bin/



, /etc/



et ainsi de suite.



Et il control.tar.gz



y a des fichiers auxiliaires pour le gestionnaire de paquets. Ce script qui doit être exécuté avant ou après l'installation et l' enlèvement ( preinst



, postinst



, prerm



,postrm



), des informations sur les fichiers qui sont des fichiers de configuration et des méta-informations sur le package, qui sont en grande partie les mêmes que celles contenues dans Packages



.



Système de création de paquet



Le système d'assemblage (aka SDK) est réalisé sous la forme d'un Make-framework. Le framework n'implique pas que vous construirez des packages séparément, sa tâche principale est de construire des référentiels entiers.



Le SDK x86_64



est dans git . Il existe une archive (le lien sera bientôt obsolète, mais il n'est pas difficile d'en trouver une nouvelle) qui vous fera gagner du temps lors de la compilation de la chaîne d'outils pour l'assemblage. A l'intérieur, le dossier présente un intérêt particulier feeds.conf.default



. Le format est simple, séparé par un espace:



  1. Mot-clé src-git



    . Non seulement git est pris en charge , mais il n'y a plus de référentiels dans les autres VCS.
  2. Nom du flux.
  3. Une URL de référentiel git où vous pouvez spécifier un commit ou une balise. Si vous connaissez le nom d'une telle spécification, veuillez me le dire.


Le référentiel avec les packages lui-même est conçu aussi simplement que possible: à la racine du référentiel il y a une catégorie de package, au deuxième niveau il y a un répertoire avec le nom du package, et à l'intérieur se trouve Makefile



, facultativement, `Config.in` pour des options supplémentaires lors de l'exécution make menuconfig



et un sous-répertoire patches



avec le contenu correspondant. Pour le package le plus simple, uniquement Makefile



. Par exemple, vous pouvez regarder le miroir du référentiel principal .



Tester la construction



J'ai essayé de créer GNU Hello pour tester le fonctionnement du SDK. C'est un Hello World relativement monstrueux, écrit en stricte conformité avec les directives du projet GNU, son seul but est d'illustrer ces directives. Je n'ai pas créé de référentiel séparé pour cela, mais je l'ai plutôt "glissé" dans les packages SDK de base, d'où je l'ai compilé.



Pour le fonctionnement du SDK Entouré par les paquets Debian nécessaires libncurses-dev



(pour l'assemblage du menu), build-essential



(de GCC et d' autres programmes standards, en fonction du C), gawk



, unzip



, file



, rsync



et python3



. De plus, pour créer un référentiel à partir des packages collectés, vous aurez besoin d'un utilitaire de génération de clés usign



. Il n'est pas dans le référentiel, vous aurez donc en plus besoin de `cmake` pour la construction. Cet outil peut être remplacé par GPG etsignify-openbsd



mais il est recommandé et développé par le projet OpenWrt et est beaucoup plus agréable à utiliser.



Compilez et installez usign



:



git clone https://git.openwrt.org/project/usign.git
cd usign
cmake .
make
sudo make install 
      
      





Au lieu de définir ( sudo make install



), vous pouvez simplement vous rappeler où se trouve le binar afin de le tirer davantage avec vos mains.



Maintenant, la configuration de base du SDK:



git clone https://git.openwrt.org/openwrt/openwrt.git
cd openwrt
./scripts/feeds update -a
./scripts/feeds install -a
      
      





Permettez-moi de vous rappeler qu'au lieu de cloner depuis git, vous pouvez télécharger et décompresser l'archive avec la chaîne d'outils précompilée. N'oubliez pas de télécharger la dernière version!



Lors de l'exécution, ./scripts/feeds update -a



nous clonons / mettons à jour tous les référentiels à partir de feeds.conf (.default), vérifions les dépendances et préparons un répertoire staging_dir/host/bin



avec des fichiers exécutables (ce sont principalement des liens symboliques vers des utilitaires système). La commande suivante ./scripts/feeds install -a



,, pousse les liens symboliques dans package/feeds



, d'où ils seront extraits pour la compilation. Ces deux commandes ne sont pas nécessaires pour créer mon package personnalisé.



Le suivant est exécutémake menuconfig



... Vous pouvez l'ignorer, mais lors de la compilation du package, il affichera toujours la fenêtre appropriée. Dans celui-ci, il suffit de changer la cible et le sous-objectif pour que tout soit compilé sous x86_64 et quitter, en acceptant de sauvegarder la configuration. Vous devrez également collecter des outils d'assemblage auxiliaires ( make tools/install



) et une chaîne d'outils ( make toolchain/install



). Si vous avez téléchargé le SDK à partir de l'archive, les make menuconfig



options de choix d'une cible ne s'afficheront pas et l'assemblage de la boîte à outils et de la chaîne d'outils n'est pas nécessaire - tout est déjà en place.



Maintenant, je crée un répertoire package/devel/hello



dans lequel je place le Makefile



contenu suivant:



Makefile
include $(TOPDIR)/rules.mk

PKG_NAME:=hello
PKG_VERSION:=2.9
PKG_RELEASE:=1
PKG_LICENSE:=GPL-3.0-or-later

PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/hello/
PKG_HASH:=ecbb7a2214196c57ff9340aa71458e1559abd38f6d8d169666846935df191ea7

include $(INCLUDE_DIR)/package.mk

define Package/hello
        SECTION:=devel
        CATEGORY:=Development
        TITLE:=GNU Hello
        URL:=https://www.gnu.org/software/hello/
endef

define Package/hello/description
        The GNU Hello program produces a familiar, friendly greeting. Yes,
        this is another implementation of the classic program that prints
        “Hello, world!” when you run it. However, unlike the minimal version
        often seen, GNU Hello processes its argument list to modify its
        behavior, supports greetings in many languages, and so on. The primary
        purpose of GNU Hello is to demonstrate how to write other programs that
        do these things; it serves as a model for GNU coding standards and GNU
        maintainer practices.
endef

define Package/hello/install
        $(INSTALL_DIR) $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/src/hello $(1)/usr/bin/
endef

$(eval $(call BuildPackage,hello))
      
      





Fondamentalement, tout doit être clair sans explication. Les fichiers du framework sont connectés, les principaux paramètres du package sont décrits, @GNU



remplacés par les miroirs du projet GNU (définis dans le framework), et le chemin se compose de deux parties: PKG_SOURCE_URL



qui spécifie l'URL de base pour toutes les versions et est développé par concaténation avec le nom de fichier d' PKG_SOURCE



une barre oblique. Il Package/hello/install



contient des instructions pour assembler des binaires dans une archive data.tar.gz



. Des options de construction supplémentaires, si nécessaire, sont disponibles dans la documentation . Au fait, n'oubliez pas que make est très pointilleux sur l'indentation, j'avais des onglets simples au lieu d'espaces de début.



Appelle encore une foismake menuconfig



, vérifiez que le paquet hello est marqué dans la section indiquée (Développement dans mon cas) et quittez en sauvegardant la configuration. Enfin, nous assemblons le package en trois étapes; télécharger, décompresser et compiler:



make package/hello/download
make package/hello/prepare
make package/hello/compile
      
      





En conséquence, j'ai reçu un colis bin/packages/x86_64/base/hello_2.9-1_x86_64.ipk



. Vous pouvez créer un référentiel. Nous générons une paire de clés ( usign -G -c 'openwrt test repo' -s key-build -p key-build.pub



la clé privée doit être appelée `clé build`) et recueillez le dépôt: make package/index



. A ce stade, l'assemblée peut jurer de l'absence usign



dans le répertoire avec des outils auxiliaires, j'ai décidé de problème symlink: ln -s `which usign` staging_dir/host/bin/usign



. Maintenant, à côté du package se trouve l'ensemble complet requis pour le référentiel.



Vérification du référentiel avec le package



Vous pouvez tout vérifier sur un vrai routeur (n'oubliez pas de choisir la bonne cible), mais j'ai utilisé Docker. En Dokerhabe ont l' image OpenWrt pour x86_84, qui peut être exécuté, cerise dans le répertoire conteneur avec le SDK: sudo docker run -it --name openwrt_test -v $PWD:/opt openwrtorg/rootfs



. Appuyez sur le bouton Entrée jusqu'à ce que l'invite Bash apparaisse.



Je copie la clé du répertoire transmis (le cp /opt/key-build.pub /etc/opkg/keys/usign -F -p /opt/key-build.pub



nom de la clé doit nécessairement correspondre à l'identifiant), ajoute mon référentiel local ( echo src/gz local file:///opt/bin/packages/x86_64/base >> /etc/opkg/customfeeds.conf



), mets à jour le référentiel ( opkg update



). La conclusion commence par un texte encourageant, tout est signé correctement:



# opkg update
Downloading file:///opt/bin/packages/x86_64/base/Packages.gz
Updated list of available packages in /var/opkg-lists/local
Downloading file:///opt/bin/packages/x86_64/base/Packages.sig
Signature check passed.
      
      





Il ne reste plus qu'à installer et vérifier:



root@34af2f6e849b:/# opkg install hello
Installing hello (2.9-1) to root...
Downloading file:///opt/bin/packages/x86_64/base/hello_2.9-1_x86_64.ipk
Configuring hello.
root@34af2f6e849b:/# hello
Hello, world!
      
      





Hourra, c'est fait! Malgré la documentation dispersée dans les articles, le processus de création de packages est assez simple.










All Articles