Package Debian


 ericc    jeu. 13 oct. : 11:38
 Aucun    Tutoriels

Introduction à la création de package pour Debian et Ubuntu

Introduction à la création de package pour Debian et Ubuntu

1° Introduction Le système de package est la base de toute distribution. Celui-ci permet à un utilisateur (généralement "root") d'installer proprement un logiciel sur sa machine, en respectant les conventions de sa distribution (positionnement des fichiers) et surtout de le désinstaller tout aussi proprement. Il permet aussi la gestion des versions et de mettre à jour l'ensemble des logiciels installés. Important: le gestionnaire de package gère (dans la majorité des cas) les dépendances. A savoir, si vous désirez installer le programme "A" mais que celui-ci à besoin de "B" pour fonctionner, alors "B" sera automatiquement installé. Dans le même ordre d'idée, il gère aussi les conflits (connu !!) Debian et toutes les distributions dérivées (Ubuntu, Linux Mint) utilisent "dpkg" et le format de fichier .deb. (vient de Debra, qui était le prénom de la petite amie du créateur de Debian) D'autres gestionnaires de packages connus : emerge utilisé par Gentoo rpm utilisé par Red Hat et beaucoup d'autres pacman utilisé par Arch Linux En règle générale, un package contient des binaires, le logiciel déjà compilé pour votre type de machine. Exception notoire: emerge fournis le source code des logiciels avec les instructions pour la compilation et l'installation des différents fichiers, associé à des paramètres qui sont propre à votre machine (par exemple: type de CPU, nombre de CPU/core, ...) Avantage: chaque logiciel est compilé spécifiquement pour votre machine. Inconvénient : chaque mise à jour demande une recompilation et c'est parfois très long. sleep 2° Package Debian Quelques précisions, clarifications sur le système de package de Debian: Le gestionnaire de packages est "dpkg" et toutes les commandes associés (dpkg-*). Apt, Dselect, Aptitude et Synaptic ne sont que des "front-end" qui apporte des fonctionnalités additionelles à dpkg comme la connexion réseau (la possibilité de downloader un package à partir d'un repository) ou une interface graphique. Mais dans tout les cas c'est dpkg qui fait le travail en arrière plan. Quand j'ai voulu faire un package pour mon usage personnel, j'ai, bien sur, fait une recherche sur Google .... j'ai trouvé des dizaines de tutoriaux qui tous expliquaient une méthode différente, avec l'utilisation d'outils différents. wall Au final, c'est assez confus pour un débutant !! En fait, après réflexion, j'en ai déduit que finalement c'est assez logique. Tout le monde n'a pas les même besoins quand il s'agit de créer un package. A un bout, on a celui qui souhaite distribuer des fichiers simples comme des wallpapers ou des icônes, et/ou qui ne font qu' 1 ou 2 packages dans l'année. Et à l'autre bout, on a des équipes de développeurs qui génèrent des dizaines de packages par semaines (ou par jour) comme LibreOffice ou Gnome par exemple et qui ont besoin d'un système plus ou moins automatique et robuste. Il faut aussi considérer l'usage qu'il en sera fait ! Si vous faites un package pour votre usage personnel, il évident qu'il n'est pas nécessaire de suivre à la lettre toutes les exigence d'un package destiné à être uploader sur un repo officiel Debian et utilisé par des milliers de personnes. 3° Info techniques Un package Debian (*.deb) n'est en fait qu'une archive compilée avec "ar" (un ancêtre de "tar", c'est pour dire comment c'est vieux smile ) Prenons un exemple: Tout d'abord nous allons downloader le package "Hello" qui est destiné justement à ce genre de chose (montrer comment est constitué un package). Commencons par le downloader (mais pas l'installer !) dans un répertoire temporaire
~/Temp$ aptitude download hello
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Reading extended state information
Initializing package states... Done
Get:1 http: //be.archive.ubuntu.com/ubuntu/ lucid/main hello 2.4-3 [34.3kB]
Fetched 34.3kB in 0s (707kB/s)
(cette commande fonctionne avec aptitude mais pas apt-get !!) après moins d'1 seconde vous devriez avoir recu le package
~/Temp$ ls -l
total 36    
-rw-r--r-- 1 34266 2009-11-05 12:06 hello_2.4-3_amd64.deb
Visualisons les info de ce package :
~/Temp$ dpkg -I hello_2.4-3_amd64.deb 
 new debian package, version 2.0.
 size 34266 bytes: control archive= 585 bytes.
     713 bytes,    17 lines      control              
 Package: hello
 Version: 2.4-3
 Architecture: amd64
 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
 Original-Maintainer: Santiago Vila <sanvila@debian.org>
 Installed-Size: 648
 Depends: libc6 (>= 2.3.4), dpkg (>= 1.15.4) | install-info
 Section: devel
 Priority: optional
 Description: The classic greeting, and a good example
  The GNU hello program produces a familiar, friendly greeting.  It
  allows non-programmers to use a classic computer science tool which
  would otherwise be unavailable to them.
  .
  Seriously, though: this is an example of how to do a Debian package.
  It is the Debian version of the GNU Project's `hello world' program
  (which is itself an example for the GNU Project).
Voyons les fichiers contenu par ce package:
~/Temp$ dpkg -c hello_2.4-3_amd64.deb 
drwxr-xr-x root/root         0 2009-11-05 09:17 ./
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/doc/
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/doc/hello/
-rw-r--r-- root/root      2645 2008-12-09 19:48 ./usr/share/doc/hello/NEWS
-rw-r--r-- root/root      2246 2009-11-05 09:16 ./usr/share/doc/hello/copyright
-rw-r--r-- root/root      6420 2008-12-09 19:49 ./usr/share/doc/hello/changelog.gz
-rw-r--r-- root/root      3472 2009-11-05 09:16 ./usr/share/doc/hello/changelog.Debian.gz
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/info/
-rw-r--r-- root/root     11421 2009-11-05 09:17 ./usr/share/info/hello.info.gz
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/man/
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/man/man1/
-rw-r--r-- root/root       687 2009-11-05 09:17 ./usr/share/man/man1/hello.1.gz
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/bin/
-rwxr-xr-x root/root     18728 2009-11-05 09:17 ./usr/bin/hello
Maintenant regardons ce que contient réellement l'archive
~/Temp$ ar -tv hello_2.4-3_amd64.deb 
rw-r--r-- 0/0      4 Nov  5 09:17 2009 debian-binary
rw-r--r-- 0/0    585 Nov  5 09:17 2009 control.tar.gz
rw-r--r-- 0/0  33488 Nov  5 09:17 2009 data.tar.gz
En fait, tout les packages Debian (binary) contiennent la même chose, ces 3 fichiers ! On peux décompresser l'archive pour voir plus précisément son contenu :
~/Temp$ ar x hello_2.4-3_amd64.deb 
~/Temp$ ls -l 
total 80    
-rw-r--r-- 1 585 2011-10-12 14:18 control.tar.gz
-rw-r--r-- 1 33488 2011-10-12 14:18 data.tar.gz
-rw-r--r-- 1 4 2011-10-12 14:18 debian-binary
le fichier "debian-binary" ne contient que "2.0", qui indique la version du packaging (pas du logiciel !!) Cela correspond à la première ligne donnée par "dpkg -I"
~/Temp$ more debian-binary 
2.0
l'archive (tar) "control.tar.gz" contient le ou les fichiers utilisés par le gestionnaire de package pour installer les fichiers. On les appelle aussi "metadata" du package
~/Temp$ tar tvzf control.tar.gz 
drwxr-xr-x root/root         0 2009-11-05 09:17 ./
-rw-r--r-- root/root       713 2009-11-05 09:17 ./control
dans ce package, il n'y a que le fichier "control" mais il peux y avoir beaucoup d'autres fichiers comme "preinst", "postinst", prerm", "postrm" qui sont des scripts bash qui seront exécutés respectivement :
  • avant l'installation (preinst)
  • après l'installation (postinst)
  • avant la désinstallation (prerm)
  • après la désinstallation (postrm)
et qui permettent par exemple, de créer des utilisateurs ou des groupes, ou mettre un fichier dans le démarrage système, ou changer le owner (chown) de certain fichier ...etc. l'archive (tar) "data.tar.gz" contient les fichiers qui seront installés. On parle aussi de "payload"! C'est généralement le plus gros fichier.
~/Temp$ tar tvzf data.tar.gz 
drwxr-xr-x root/root         0 2009-11-05 09:17 ./
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/doc/
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/doc/hello/
-rw-r--r-- root/root      2645 2008-12-09 19:48 ./usr/share/doc/hello/NEWS
-rw-r--r-- root/root      2246 2009-11-05 09:16 ./usr/share/doc/hello/copyright
-rw-r--r-- root/root      6420 2008-12-09 19:49 ./usr/share/doc/hello/changelog.gz
-rw-r--r-- root/root      3472 2009-11-05 09:16 ./usr/share/doc/hello/changelog.Debian.gz
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/info/
-rw-r--r-- root/root     11421 2009-11-05 09:17 ./usr/share/info/hello.info.gz
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/man/
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/share/man/man1/
-rw-r--r-- root/root       687 2009-11-05 09:17 ./usr/share/man/man1/hello.1.gz
drwxr-xr-x root/root         0 2009-11-05 09:17 ./usr/bin/
-rwxr-xr-x root/root     18728 2009-11-05 09:17 ./usr/bin/hello
On constate que c'est exactement la liste donnée par la commande "dpkg -c" Si vous utilisez une distro basé sur Debian, vous avez peut être remarqué que le nom des packages respectent certaines règles : < nom du logiciel >_< version >-< DebianRevisionNumber >_< architecture >.deb les underscores (_) et tirets (-) sont importants le nom du logiciel peux contenir un ou plusieurs chiffres mais ils doivent être collé au nom (Gnome2) le nom du logiciel ne peux pas commencé par un un chiffre et doit toujours être en minuscules l'architecture indique sur pour quel type de machine le package à été concu et suivent une liste pré-établie (x86, amd64, i386, all pour applicable pour toutes les architectures) 4° Methode simple Bien il est temps maintenant de faire notre propre package pour comprendre comment cela fonctionne. Autant le dire tout de suite, la méthode qui suit est valide pour faire des packages simples pour vous (et vos amis) mais ne peux pas être envoyer vers un repo officiel, mais elle a l'avantage d'être simple, rapide et applicable par tout le monde Question importante : Pourquoi faire un package ? Les raisons peuvent être multiple ! Vous avez trouvé un logiciel qui vous est très utile et vous voudriez en faire profiter vos amis. Vous avez une collection de wallpaper que vous aimeriez installer entre plusieurs machines On peux imaginer aussi de faire des packages avec les mp3 d'un album Dans mon cas, c'est principalement pour installer la dernière version de Firefox qui est rarement disponible dans les dépôts officiels. De l'autre coté, j'ai une machine type amd64 (64bits) et je ne suis pas sur que le site officiel de Mozilla vous fournisse cette version (mais plutôt la x86 comme c'était le cas avec les versions 3.1x ) alors que la version 64bits existe depuis pas mal de temps (mais pas officiellement). Et en dernier ressort, je souhaitais pouvoir désinstaller rapidement et simplement les anciennes versions La version officielle de Firefox, quand j'écris ces lignes, est la 7.0.1 Commençons donc par downloader l'archive. Rendez vous à l'adresse suivante : http://ftp.mozilla.org/pub/mozilla.org/mozilla.org/firefox/releases/ sur ce serveur, vous avez TOUTES les versions de firefox. Celle avec un "b" dans le n° de version, sont des "beta" donc, sauf si vous êtes casse-cou, on évite ! On prend la version avec le n° le plus élevé mais sans "b", c'est à dire la 7.0.1 ensuite le type d'architecture ... linux-x86_64 pour moi Et enfin la langue. "en-GB" en ce qui me concerne mais rien ne vous empêche de prendre "fr" wink http://ftp.mozilla.org/pub/mozilla.org/mozilla.org/firefox/releases/7.0.1/linux-x86_64/en-GB/ dans ce répertoire, vous avez 2 fichiers: firefox-7.0.1.tar.bz2 qui est l'archive qui nous intéresse firefox-7.0.1.tar.bz2.asc qui est un fichier texte qui contient la signature GnuPG de la fondation Mozilla et vous permet de vérifier que l'archive est originale on download "firefox-7.0.1.tar.bz2" Maintenant on crée un répertoire qui va contenir nos fichiers utiliser pour construire le package:
~/Temp$ mkdir firefox7-7.0.1
Le nom du répertoire est important car cela sera aussi le nom de notre package ! J'ai utilisé "firefox7" comme nom de logiciel pour évité les conflits avec un possible package officiel qui lui s'appelle "firefox" (sous Ubuntu) Cela me permet aussi de conserver plusieurs versions de firefox sur ma machine (firefox4, firefox5, firefox6, ...) tout en conservant la possibilité de mettre à jour une même version majeure ... Il est important d'éviter au maximum d'utiliser un nom de package qui existe déjà dans le repo officiel, sauf si bien sur, vous êtes packager officiel pour ce package !!! Pour éviter tout problème, vous pouvez faire un "aptitude search " pour vérifier si celui-ci existe déjà Ensuite dans ce répertoire on crée l'arborescence suivante: 148640Selection001
~/Temp$ cd firefox7-7.0.1/
~/Temp/firefox7-7.0.1$ mkdir DEBIAN
~/Temp/firefox7-7.0.1$ mkdir opt
~/Temp/firefox7-7.0.1$ mkdir -p usr/share/applications
le répertoire "DEBIAN" doit être obligatoirement en majuscules Lors de l'installation, dpkg va copié simplement les fichiers sur votre disque à la place correspondante, à part le répertoire "DEBIAN". Vous devez considérer le répertoire "firefox7-7.0.1" comme étant la racine (root) de votre installation L'archive de Firefox se décompresse dans un répertoire et fonctionne directement comme cela. Elle réutilise directement (et met éventuellement à jour) les add-ons que vous auriez pu installé sur une version précédente J'ai décidé de mettre les fichiers dans le répertoire "/opt" (option) pour être sur de ne pas interférer avec une autre version de firefox. Par contre, je vais créer un fichier pour que cette version apparaisse directement dans le menu (facile et pratique ! évite d'avoir à le faire manuellement par la suite) Donc on copie l'archive "firefox-7.0.1.tar.bz2" dans le répertoire "opt" et on la décompresse
cp ~/Temp/firefox-7.0.1.tar.bz2 ~/Temp/firefox7-7.0.1/opt/
~/Temp/firefox7-7.0.1$ cd opt/
~/Temp/firefox7-7.0.1/opt$ tar xjf firefox-7.0.1.tar.bz2 
~/Temp/firefox7-7.0.1/opt$ rm firefox-7.0.1.tar.bz2
on supprime l'archive, histoire que notre package ne fasse pas deux fois la taille nécessaire sans raison. Et comme on l'a copié depuis le répertoire ou on l'avait downloader, on l'a toujours sous la main au cas ou en aurait besoin On renomme le répertoire créé par tar, toujours pour éviter les conflits avec d'autres versions
~/Temp/firefox7-7.0.1/opt$ mv firefox firefox7
Maintenant, on va dans le répertoire "usr/share/applications" , et dans celui-ci, on doit créer un fichier "firefox.desktop" qui sera utilisé par gnome pour insérer notre version de firefox dans le menu. Comme je n'ai pas la science infuse et que je suis légèrement feignant, j'ai repris comme modèle le fichier qui existait sur ma machine dans le répertoire "/usr/share/applications", et j'ai apporté les modifications que je trouvais nécessaires (plus d'info sur la page de la documentation de Gnome2 : Desktop Entry Files
[Desktop Entry] Version=7.0.1 Name=Firefox7 Web Browser Name[fr]=Navigateur Web Firefox Comment=Browse the World Wide Web Comment[fr]=Navigue sur Internet GenericName=Web Browser GenericName[fr]=Navigateur Web Exec=/opt/firefox7/firefox %u Terminal=false X-MultipleArgs=false Type=Application Icon=/opt/firefox7/chrome/icons/default/default48.png Categories=Network;WebBrowser; MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/vnd.mozilla.xul+xml;application/rss+xml;application/rdf+xml;image/gif;image/jpeg;image/png; StartupWMClass=Firefox StartupNotify=true
J'ai supprimé quasi toutes les traductions du nom, et des commentaires parce qu'il y a peu de chance que je passe mon package à un Arménien ou un Slovaque et en plus cela faisait trop de lignes pour copié ici ! Vous pouvez remplacer l’icône en downloadant une autre image png et en la placant dans le bon répertoire, puis changez son nom dans ce fichier. C'est ce que je fais généralement pour distinguer visuellement les différentes versions. Importantes lignes : Exec : vérifiez que le chemin est le bon ! et le nom de l’exécutable Icon : même remarques Maintenant on va dans le répertoire DEBIAN. Le contenu de ce répertoire sera dans l'archive "control.tar.gz" Comme pour le package de demo "Hello.....deb" on ne va créer que le fichier "control" qui est le seul fichier réellement obligatoire
Package: firefox7 Version: 7.0.1 Section: web Priority: optional Architecture: amd64 Essential: no Installed-Size: 16M Depends: Pre-Depends: Recommends: Suggests: Maintainer: ericc <-email-> Conflicts: Replaces: Provides: Description: Browse the World Wide Web Firefox delivers safe, easy web browsing. A familiar user interface, enhanced security features including protection from online identity theft, and integrated search let you get the most out of the web.
De la même manière, je n'ai gardé que les informations qui sont obligatoires ou me paraissaient utiles. Ainsi, il n'y a aucune dépendance (j'ai assumé que vous aviez déjà une version antérieure de Firefox, pour laquelle les dépendances ont été installé ! Dans l'absolu, j'aurai du au moins mettre X11) Attention: la description longue doit être à la fin du fichier et commence par un espace !! Voila, c'est tout cool Vous devriez avoir quelque chose qui ressemble à cela :
(j'ai supprimé pas mal de lignes pour que cela rentre dans la page biggrin )

Si vous avez remarqué précédemment dans les listes de fichiers contenu dans les packages, tout les fichiers appartenait à "root" ! Hors pour l'instant, ils sont tous sous notre possession. 
Parce que je ne suis pas sur que le packager le fasse et pour des raisons de sécurité, on va le faire aussi pour nos fichiers:
~/Temp/firefox7-7.0.1$ sudo chown -R root:root opt/
~/Temp/firefox7-7.0.1$ sudo chown -R root:root usr/
On ne modifie pas le répertoire DEBIAN !! Maintenant on remonte d'un niveau et on lance la création du package
~/Temp/firefox7-7.0.1$ cd ..
~/Temp$ dpkg-deb --build firefox7-7.0.1
dpkg-deb: building package `firefox7' in `firefox7-7.0.1.deb'.
et voilà ! C'est tout ... cela prend moins de 10s pour faire le package
~/Temp$ ls -l firefox7-7.0.1.deb 
-rw-r--r-- 1 17291306 2011-10-12 17:29 firefox7-7.0.1.deb
~/Temp$ dpkg -I firefox7-7.0.1.deb 
 new debian package, version 2.0.
 size 17291306 bytes: control archive= 476 bytes.
     491 bytes,    17 lines      control              
 Package: firefox7
 Version: 7.0.1
 Section: web
 Priority: optional
 Architecture: amd64
 Essential: no
 Installed-Size: 16M 
 Depends:
 Pre-Depends:
 Recommends:
 Suggests:
 Maintainer: ericc <ericc@ericc-dream.fr.nf> 
 Conflicts:
 Replaces:
 Provides:
 Description: Browse the World Wide Web
  Firefox delivers safe, easy web browsing. A familiar user interface, enhanced security features including protection from online identity theft, and integrated search let you get the most out of the web.
~/Temp$ dpkg -c firefox7-7.0.1.deb 
drwxr-xr-x ecrastes/ecrastes 0 2011-10-12 16:31 ./
drwxr-xr-x root/root         0 2011-10-12 16:31 ./usr/
drwxr-xr-x root/root         0 2011-10-12 16:31 ./usr/share/
drwxr-xr-x root/root         0 2011-10-12 17:09 ./usr/share/applications/
-rw-r--r-- root/root      2690 2011-10-12 17:09 ./usr/share/applications/firefox7.desktop
drwxr-xr-x root/root         0 2011-10-12 16:46 ./opt/
drwxr-xr-x root/root         0 2011-09-29 02:50 ./opt/firefox7/
-rw-r--r-- root/root       177 2011-09-29 02:50 ./opt/firefox7/README.txt
-rwxr-xr-x root/root     57176 2011-09-29 02:39 ./opt/firefox7/firefox
....
Si vous voulez, vous pouvez renommer le package en "firefox7-7.0.1_amd64.deb", histoire de vous rappelez pour quelle architecture ce package est destiné Y a plus qu'à installer avec un
sudo dpkg --install firefox7-7.0.1.deb
rock Comme dit précédemment, cette méthode est valide pour créer des packages personnels pour des fichiers type images ou son(mp3) ou des binaires déjà compiler. Il est possible de faire un package avec des binaires à partir d'un source code (c'est même la méthode par défaut) .... mais je vous expliquerais ça une autre fois, dans un autre tuto ericc me