Recommandations pour le parrainage de paquets Debian

Parrainer un paquet signifie l’uploader pour le compte d’une autre personne (qui se trouve être, la plupart du temps, un nouveau contributeur voulant devenir mainteneur de paquet). Le parrainage est réservé aux développeurs Debian, car ils sont réputés connaître les tenants et aboutissants de l’empaquetage. Cet article essaye ici de documenter ce processus, afin de s’assurer que le parrain effectue un travail satisfaisant, au regard des standards Debian.

Parrainer un paquet dans l’archive Debian n’est pas une tâche triviale. Cela suppose que vous ayez vérifié son empaquetage et jugé qu’il était du niveau de qualité attendu par Debian. Voyons voir ce que vous pouvez et devriez faire dans un tel cas :

Parrainer l’envoi initial

Parrainer un tout nouveau paquet requiert une analyse méthodique de son empaquetage : compiler le paquet et tester le logiciel proprement dit n’est absolument pas suffisant ! Vous devez ouvrir chaque fichier dans le répertoire debian à la recherche de problèmes potentiels. Voici une liste que vous pouvez utiliser pour réaliser cet audit :

  • Vérifier que l’archive TAR amont fournie est identique à celle distribuée par l’auteur amont (dans le cas où les sources ont été ré-empaquetées pour Debian, il vous faudra générer l’archive par vous-même) ;
  • Lancer lintian. Ce dernier remontera beaucoup de problèmes « habituels ». Vérifier que les overrides employés pour masquer des erreurs sont pleinement justifiés ;
  • Lancer licensecheck et vérifier que debian/copyright est correct et exhaustif. Rechercher les problèmes de licences (comme les fichiers dont l’en-tête comporte « All rights reserved », ou une licence non compatible avec les principes du logiciel libre selon Debian) ;
  • Compiler le paquet avec pbuilder (ou équivalent), afin de s’assurer que les dépendances de compilation soient complètes ;
  • Rechercher les erreurs dans debian/control : est-ce qu’il suit les bonnes pratiques ? Est-ce que la liste des dépendances est complète ?
  • Rechercher les erreurs dans debian/rules : est-ce qu’il suit les bonnes pratiques ? Est-il améliorable ?
  • Rechercher les erreurs dans les scripts de configuration (preinst, postinst, prerm, postrm, config) : est-ce que les scripts preinst et postrm fonctionneront si les dépendances ne sont pas installées ? Est-ce que tous les scripts sont bien idempotents (c’est à dire qu’ils peuvent être lancés un nombre arbitraire de fois sans conséquences fâcheuses) ?
  • Passer en revue toutes les modifications faites aux fichiers amont (soit dans les fichiers .diff.gz, soit dans debian/patches/ ou directement embarquées dans le tarball debian en ce qui concerne les fichiers binaires). Est-ce que ces modifications sont justifiées ? Sont-elles proprement documentées (en utilisant DEP-3 dans le cas des patchs) ?
  • Pour chaque fichier, il vous faut vous demander pourquoi il est là et s’il constitue la meilleure manière d’atteindre le but recherché. Est-ce que le mainteneur suit bien les bonnes pratiques de l’empaquetage décrites dans la Référence du Développeur Debian ?
  • Compiler, installer les paquets, et essayer les logiciels. Assurez-vous de pouvoir supprimer et purger les paquets. Vous pouvez aussi tester les paquets grâce à piuparts.

Si cet audit n’a révélé aucun problème, vous pouvez alors uploader le paquet. Mais souvenez-vous que même si vous n’en êtes pas le mainteneur, le parrain reste responsable de ce qu’il a envoyé dans l’archive Debian. C’est pourquoi vous êtes encouragé à suivre le paquet grâce au PTS (Package Tracking System – Système de Suivi des Paquets).

Parrainer la mise à jour d’un paquet déjà existant

Vous supposerez généralement que le paquet a déjà été l’objet d’un examen minutieux. Donc plutôt que de recommencer, vous analyserez avec beaucoup d’attention les différences entre l’ancienne et la nouvelle version préparée par le mainteneur. Si vous n’avez pas vous-même effectué la revue initiale, vous souhaiterez peut-être jeter un coup d’oeil un peu plus approfondi au paquet en lui-même, juste au cas où le premier « relecteur » ait été un peu négligeant.

Pour comparer, il vous faut les deux versions. Télécharger la version source actuelle (grâce à apt-get source) et recompiler-là (ou télécharger le fichier binaire correspondant : aptitude download). Télécharger ensuite le paquet source à parrainer (la plupart du temps via dget).

Lisez les nouvelles entrées du fichier de suivi des modifications (changelog) : il devrait vous dire à quoi vous attendre. L’outil principal que vous allez utiliser est debdiff, que vous pouvez lancer avec deux paquets sources (fichiers .dsc) ou deux fichiers binaires, ou encore deux fichiers .changes (il comparera alors tous les fichiers binaires listés dans les fichiers .changes).

Si vous comparez les paquets sources (en excluant les fichiers upstream dans le cas d’une nouvelle version upstream, par exemple en filtrant la sortie de debdiff grâce à filterdiff -i '*/debian/*'), vous devez comprendre toutes les modifications qui s’affichent, et elles doivent être proprement documentées dans le suivi des modifications Debian.

S’il n’y a rien à relever, compiler le paquet et comparer les fichiers binaires, afin de vérifier que les modifications vues dans les sources n’ont aucun effet de bord (comme des fichiers supprimés par erreurs, des dépendances manquantes, …).

Il peut également être utile de contrôler l’état du paquet sur le PTS, histoire de vérifier que le mainteneur n’a rien manqué d’important : peut-être que des traductions en attente auraient pu être intégrées, ou bien le paquet a fait l’objet d’une mise à jour indépendante (NMU – Non-Maintener Upload) mais le mainteneur a oublié d’en reprendre les modifications dans sa nouvelle version. Il se peut également qu’un bogue critique pour la publication ait été laissé de côté et bloque la migration vers testing… bref : quelle qu’en soit la nature, si vous trouvez quelque chose qui aurait pu être (mieux) fait, il est temps de le dire au mainteneur de sorte à ce qu’il puisse s’améliorer la prochaine fois, et qu’il ait plus justement conscience de ses responsabilités.

Si vous n’avez trouvé aucun problème, alors il est temps d’uploader la nouvelle version. Dans tous les autres cas, demandez au mainteneur de vous envoyer une version corrigée.


Cet article a servi de base à la rédaction de la section correspondante de la Référence du développeur Debian (cf #453313). Cliquez ici pour soutenir mon travail sur la documentation Debian.

Ceci est une traduction de mon article Best practices when sponsoring Debian packages contribuée par Weierstrass01.

4 astuces pour maintenir un paquet Debian « 3.0 (quilt) » dans un système de suivi de versions (VCS)

La plupart des paquets Debian sont gérés grâce à un logiciel de gestion de versions (VCS – Version Control System) tel que git, subversion, bazaar ou mercurial. Les particularités du format « 3.0 (quilt) » ne sont pas sans conséquences sur la gestion des paquets dans un VCS, et cet article va vous présenter quelques astuces afin d’en rendre l’usage plus agréable.

(Tous les exemples présentés ci-dessous s’appuient sur l’utilisation de git comme VCS).

1. Exclusion du répertoire .pc

Le répertoire .pc est utilisé par quilt afin de stocker ses données internes (liste des patchs appliqués, sauvegarde des fichiers modifiés). Il est également créé par dpkg-source de telle sorte que quilt « sache » que les patchs sont situés dans debian/patches (et non dans patches, qui est le répertoire que quilt utilise par défaut). À ce titre, le répertoire est conservé même lorsque plus aucun patch n’est actuellemement appliqué.

Vous ne tenez cependant pas à conserver ce répertoire dans votre dépôt : il doit donc être mentionné dans la liste des fichiers exclus. Avec git, il suffit d’indiquer :

$ echo ".pc" >>.gitignore
$ git add .gitignore
$ git commit -m "Ignore quilt dir"

Le fichier .gitignore n’étant pas pris en compte par dpkg-source, le paquet source généré par ce dernier ne sera pas « pollué ».

2. Retirer les patchs après la compilation

Si vous stockez vos sources « amont » avec les patchs non appliqués (ce que font la plupart des gens) et que vous ne compilez pas vos paquets dans un répertoire temporaire prévu à cet effet, alors vous souhaitez probablement « désappliquer » les patchs après la compilation, de sorte à retrouver un dépôt dans un état « propre ».

C’est désormais le comportement par défaut de dpkg-source. S’il a dû appliquer les patchs, il les enlèvera automatiquement également.

Mais on peut tout de même forcer ce comportement en ajoutant « unapply-patches » à debian/source/local-options :

$ echo "unapply-patches" >>debian/source/local-options
$ git add debian/source/local-options
$ git commit -m "Unapply patches after build"

svn-buildpackage compilant systématiquement dans un répertoire temporaire, le dépôt est laissé exactement dans le même état qu’avant la compilation : cette option est inutile dans ce cas. Ce comportement peut également être demandé à git-buildpackage grâce à l’option --git-export-dir=../build-area/ (../build-area/ étant le répertoire utilisé par svn-buildpackage, cette option force git-buildpackage à se comporter comme svn-buildpackage).

3. Gérer vos patchs quilt comme une branche git

Plutôt que de gérer les patchs spécifiques à Debian via quilt, il est possible d’utiliser git lui-même. Avec git-buildpackage vient l’outil gbp-pq (Git-BuildPackage Patch Queue – File des patchs de git-buildpackage). gbp-pq permet l’export d’une série quilt dans une branche git, que vous pouvez alors manipuler comme vous le souhaitez. Chaque commit représentant un patch, vous devez « rebaser » cette branche afin d’éditer les commits intermédiaires. Jetez un oeil à la documentation de gbp-pq pour appronfondir le sujet.

Alternative à gbp-pq, l’utilisation de git-dpm est plus compliquée, mais présente l’avantage de conserver l’historique de toutes les branches utilisées pour générer les séries quilt de toutes les publications Debian. Son principe de fonctionnement est très bien expliqué sur son site, et vous pouvez également souhaiter lire la revue qu’en a fait Sam Hartman, qui en présente les limites.

4. Documenter la manière de passer en revue les modifications

L’un des principaux bénéfices liés à l’utilisation du nouveau format source tient au fait qu’il est dorénavant simple de passer en revue les modifications amont : celles-ci sont conservées en autant de patchs distincts proprement documentés (et, idéalement, en utilisant le format DEP-3). En utilisant les outils décrits précédemment, le message de commit devient l’en-tête du patch. Il devient donc important de saisir des messages de commit explicites.

Cette méthode fonctionne bien tant que votre méthode de travail prend appui sur les patchs Debian, regroupés dans une branche que vous rebasez sur les sources amont à chaque publication. Certains mainteneurs n’aiment pas cette méthode de travail et préfèrent voir appliquer les modifications propres à Debian directement sur la branche d’empaquetage. Ils sautent alors vers une nouvelle version amont en la fusionnant dans cette dernière. Il est difficile dans ce cas de générer une série quilt à partir du système de suivi de versions. Il faut à la place indiquer à dpkg-source de stocker toutes les modifications dans un seul patch (qui devient alors équivalent au bon vieux .diff.gz), et documenter dans son en-tête comment mieux passer en revue les modifications, par exemple dans l’interface Web du VCS.

Le premier comportement est obtenu en passant l’option --single-debian-patch, et le second en écrivant l’en-tête dans debian/source/patch-header :

$ echo "single-debian-patch" >> debian/source/local-options
$ cat >debian/source/patch-header <<END
This patch contains all the Debian-specific
changes mixed together. To review them
separately, please inspect the VCS history
at http://git.debian.org/?=collab-maint/foo.git
<Put more details here>
END

Ceci est une traduction de mon article 4 tips to maintain a “3.0 (quilt)” Debian source package in a VCS contribuée par Weierstrass01. Vous voulez d’autres tutoriels comme celui-ci ? Cliquez ici pour vous abonner à ma newsletter et recevoir les nouveaux articles par email.

Ne créez pas votre paquet Debian avec dpkg -b

J’ai pu observer de nombreuses personnes, ces dernières années, essayant d’utiliser dpkg --build pour créer des paquets Debian. Et, de fait, si vous lisez les pages de manuel de dpkg et de dpkg-deb, l’option semble bien appropriée à cet usage :

-b, --build répertoire [archive|répertoire]

Crée une archive Debian avec l’arborescence contenue dans répertoire. répertoire doit posséder un sous-répertoire DEBIAN qui contient les fichiers de contrôle tel que le fichier « control » lui-même. Ce répertoire n’apparaît pas dans l’archive de l’arborescence du paquet binaire ; mais les fichiers qu’il contient sont mis dans la zone de contrôle du paquet binaire.

On peut en conclure que oui, effectivement, dpkg-deb est l’outil créant en dernière étape les fichiers .deb (aussi connus sous le nom de paquets binaires). Ce qui ne veut pas dire que vous êtes censé appeler un tel outil « bas-niveau » vous-même. En effet, si vous souhaitez empaqueter proprement un logiciel, vous devez plutôt créer un paquet source Debian, qui partira du code source amont pour créer des paquets binaires respectant la charte technique Debian.

Créer un tel paquet source implique également de préparer une arborescence de répertoires (mais avec un sous-répertoire « debian »), ce qui est probablement plus compliqué que d’appliquer dpkg -b à un répertoire ciselé « à la main ». Mais le résultat en est d’autant plus versatile : les outils utilisés apportent une valeur ajoutée en analysant/modifiant dynamiquement les fichiers à l’intérieur de votre paquet (par exemple, les dépendances envers les bibliothèques C requises par votre paquet sont insérées automatiquement).

Si cette méthodologie vous était inconnue, vous souhaiterez peut-être approfondir le sujet grâce au manuel du Nouveau Mainteneur ou à la Charte Debian.

Ceci est une traduction de mon article Avoid a newbie packager mistake: don’t build your Debian packages with dpkg -b contribuée par Weierstrass01.

Abonnez-vous à ce blog par RSS ou par email pour recevoir tous les prochains articles et améliorer votre maîtrise de Debian/Ubuntu.

Gérer des patchs spécifiques à chaque distribution avec un paquet source commun

Un patch peut-il n’être appliqué au paquet cible que pour certaines distributions ? Cette question m’a été posée en commentaire d’un précédent article présentant la gestion différentielle des dépendances entre Ubuntu et Debian, à partir d’un même paquet source. Et la réponse est … oui. C’est possible !

Le format de paquets source 3.0 (quilt) offre à cette fin une possibilité intéressante : plutôt que d’utiliser uniquement le fichier debian/patches/series pour rechercher des patches, dpkg-source essaye en premier lieu d’utiliser debian/patches/distrib.series, où « distrib » vaut « ubuntu », « debian », … Il est important de noter que dpkg-source n’applique pas les patches de tous les fichiers series trouvés : seuls les patches du premier fichier trouvé sont considérés.

Bien, mais comment tirer le meilleur parti de tout cela ? Debian est supposée toujours fournir le fichier debian/patches/series, ce dernier devant indiquer l’ensemble des patches « de base » à appliquer. N’importe quel tiers travaillant avec Debian peut maintenir son propre fichier series dans le dépôt CVS commun de maintenance des paquets. Il peut ainsi laisser de côté certains patches propres à Debian (les patches relatifs à la marque, par exemple), et intégrer les siens en plus des patches restants.

Il est intéressant de noter que c’est au mainteneur de s’assurer, en cas de besoin, de la cohérence des deux fichiers. dpkg-source n’offre ni la possibilité d’agréger plusieurs fichiers series, ni d’établir une quelconque dépendance entre eux.

Pour éditer un fichier series alternatif grâce à quilt, il suffit de positionner temporairement la variable d’environnement QUILT_SERIES à « distrib.series ». Faites simplement attention à bien partir d’un état vierge (i.e. aucun patch appliqué). Si tel n’est pas le cas, quilt sera confronté à une incohérence entre les données du fichier series et ses propres données (stockées dans le dossier .pc).

Ceci est une traduction de mon article Managing distribution-specific patches with a common source package contribuée par Weierstrass01. Si vous avez apprécié cet article, cliquez ici pour découvrir comment m’encourager à en rédiger d’autres.

Correctement renommer un fichier de configuration dans un paquet Debian

Après avoir traité de la suppression de conffiles obsolètes, je vais maintenant aborder la question du renommage des fichiers de configuration gérés par dpkg.

La problématique

Prenons pour hypothèse que la version 1.2 d’une quelconque application ne fournisse plus le fichier /etc/foo.conf. En lieu et place, elle fournit /etc/bar.conf, car le fichier de configuration a été renommé. Si vous ne faîtes rien de particulier, le nouveau conffile sera installé et contiendra la configuration par défaut, tandis que l’ancien restera. Toutes les modifications éventuellement réalisées par l’administrateur seront perdues (inutilisées, pour être exact : elles seront toujours consignées dans le fichier foo.conf, qui ne sera plus pris en compte).

Bien entendu, il vous est toujours possible de procéder à un mv /etc/foo.conf /etc/bar.conf dans le script de pré-installation. Mais ce n’est pas satisfaisant : une questions sera posée à l’utilisateur final lors de la mise à jour, dont il ne comprendra pas la raison.

La solution

Vous devez vérifier, dans le script de pré-installation, si l’ancien conffile a été modifié par l’administrateur. Si tel est le cas, vous souhaitez le garder de côté. Dans le cas contraire, vous pourrez le supprimer une fois la mise à jour réalisée, et, pour bien s’en rappeler, vous le renommez en /etc/foo.conf.dpkg-remove dans ce cas.

Vous supprimez ensuite /etc/foo.conf.dpkg-remove dans le script de post-installation. Si l’ancien conffile (/etc/foo.conf) existe toujours, c’est qu’il a été modifié par l’administrateur. Il ne reste plus alors qu’à faire une copie de sauvegarde du nouveau conffile vers /etc/bar.conf.dpkg-dist, et renommer l’ancien en /etc/bar.conf.

Dans le script postrm, dans le cas d’un appel pour annuler la mise à jour, le fichier /etc/foo.conf.dpkg-remove doit retrouver son nom originel.

En pratique, utilisez dpkg-maintscript-helper

dpkg-maintscript-helper permet d’automatiser toutes ces tâches. Vous n’avez qu’à ajouter l’extrait de code suivant dans chaque script (postinst, postrm, preinst) :

if dpkg-maintscript-helper supports mv_conffile 2>/dev/null; then
    dpkg-maintscript-helper mv_conffile /etc/foo.conf /etc/bar.conf 1.1-3 -- "$@"
fi

J’ai considéré dans cet exemple que la dernière version du paquet contenant /etc/foo.conf (i.e. la dernière version avant la parution de la 1.2-1) était la 1.1-3.

Vous pouvez faire l’économie des tests préliminaires en imposant une pré-dépendance à « dpkg (>= 1.15.7.2) », ou si suffisamment de temps s’est écoulé pour considérer comme probable que tout le monde dispose d’une version plus récente. Vous trouverez tous les détails sur ce point dans la page de manuel de dpkg-maintscript-helper.

Cet article est une traduction de Correctly renaming a conffile in Debian package maintainer scripts contribuée par Weierstrass01. Suivez moi sur Identi.ca, Twitter et Facebook. Ou abonnez-vous à ce blog par RSS ou par email.

Comment recompiler un paquet Debian

Savoir recompiler un paquet Debian existant est particulièrement utile. En effet, il s’agit là d’un prérequis indispensable à certaines tâches qu’un administrateur peut vouloir effectuer : activer une fonctionnalité désactivée dans le paquet Debian officiel, recompiler les sources pour un autre environnement (récupérer la version correspondant à Debian testing pour faire fonctionner le paquet sous Debian stable par exemple — ce qui, d’ailleurs, est le principe même des applications disponibles dans les backports), inclure une correction que les développeurs upstream ont mise à disposition, … Cet article vous propose de découvrir les 4 étapes nécessaires à cette recompilation :

1. Télécharger les sources

La « meilleure » manière de télécharger les sources reste l’utilisation d’APT. Il permet de les télécharger depuis les dépôts source paramétrés dans le fichier /etc/apt/sources.list, comme par exemple :

deb-src http://ftp.debian.org/debian unstable main contrib non-free
deb-src http://ftp.debian.org/debian testing main contrib non-free
deb-src http://ftp.debian.org/debian stable main contrib non-free

Comme on le voit, le premier mot-clé indique clairement à APT que l’on s’intéresse aux sources, et non pas aux binaires.

Si les dépôts source n’étaient pas présents dans le fichier auparavant, un petit apt-get update permettra de mettre à jour la base et vous pourrez récupérer par exemple la dernière version des sources du paquet publican, via la commande apt-get source publican. Il est également possible d’indiquer la distribution au sein de laquelle il faut récupérer les sources, avec la syntaxe « package/distribution« . Dans notre cas, apt-get source publican/testing récupérera les sources de publican à partir du dépôt testing et les extraira dans le répertoire courant (via la commande dpkg-source -x, avec comme prérequis le paquet dpkg-dev installé).

$ apt-get source publican/testing
Lecture des listes de paquets... Fait
Construction de l'arbre des dépendances       
Lecture des informations d'état... Fait
Note : la maintenance du paquet de « publican » est réalisée dans le système de suivi de versions « Git » à l'adresse :
git://git.debian.org/collab-maint/publican.git
Nécessité de prendre 888 ko dans les sources.
Réception de : 1 http://ftp.fr.debian.org/debian/ testing/main publican 2.5-2 (dsc) [2 292 B]
Réception de : 2 http://ftp.fr.debian.org/debian/ testing/main publican 2.5-2 (tar) [879 kB]
Réception de : 3 http://ftp.fr.debian.org/debian/ testing/main publican 2.5-2 (diff) [6907 B]
888 ko réceptionnés en 8s (104 ko/s)
dpkg-source: info: extraction de publican dans publican-2.5
dpkg-source: info: extraction de publican_2.5.orig.tar.gz
dpkg-source: info: extraction de publican_2.5-2.debian.tar.gz
dpkg-source: info: mise en place de perl-critic-fixes-svn1732
$ ls -dF publican*
publican-2.5/
publican_2.5-2.debian.tar.gz
publican_2.5-2.dsc
publican_2.5.orig.tar.gz

Si vous ne souhaitez pas utiliser APT, ou si le paquet source n’est pas hébergé par un dépôt APT, il est toujours possible de télécharger le paquet source complet via dget -u dsc-url, où dsc-url représente l’URL du fichier .dsc, image des sources du paquet. L’utilitaire dget est fourni par le paquet devscripts. L’option -u mérite d’être retenue : elle signifie que l’origine des sources ne sera pas vérifiée avant extraction.

2. Installer les dépendances de compilation

Là-aussi, APT peut faire le boulot ingrat à votre place. Tout ce que vous avez à faire est de lancer apt-get build-dep mon-paquet afin que les dépendances nécessaires à la compilation de mon-paquet soient installées. La syntaxe restant la même que pour apt-get source, il est possible de lancer apt-get build-dep publican/testing, ce qui aura pour effet d’installer les dépendances pour la compilation de la version testing de publican.

Si vous ne pouvez pas utiliser APT pour faire cela, placez-vous directement dans le répertoire contenant l’extraction du paquet source et lancez dpkg-checkbuilddeps. En sortie, vous aurez une liste de dépendances de compilation non satisfaites (dans le cas contraire, la commande restera muette, et vous pourrez continuer tranquillement). Dans ce cas, un enchaînement de copier/coller et d’apt-get install permettra de remédier au problème en quelques secondes.

3. Faites les modifications requises

Je ne détaillerai pas cette étape, dans la mesure où elle dépend totalement des objectifs particuliers qui vous poussent à recompiler. Vous serez peut-être amené à modifier le fichier debian/rules, ou à appliquer un patch.

Dans tous les cas, une chose est sûre : si vous avez changé quoi que ce soit, ou recompilé le paquet dans un environnement différent, vous devriez vraiment changer son numéro de version. dch --local perso (toujours du paquet devscripts) vous permet de le faire simplement : remplacer simplement perso par un nom court vous identifiant comme le pourvoyeur de cette version. debian/changelog sera modifié en conséquence et vous serez invité à documenter brièvement les changements opérés.

4. Compiler le paquet

La dernière étape est également la plus simple, maintenant que tout est en place. Vous devez vous placer à la racine du répertoire où sont extraites les sources, et lancer debuild -us -uc (procédure recommandée, nécessite le paquet devscripts), ou directement dpkg-buildpackage -us -uc. Les options « -us -uc » évitent l’étape de la signature qui provoquerait une erreur (bénigne) à la fin si vous ne disposez pas de clé GPG correspondant au nom entré au début du fichier des modifications Debian (debian/changelog).

$ cd publican-2.5
$ debuild -us -uc
dpkg-buildpackage: export de CFLAGS depuis dpkg-buildflags (origine : vendor): -g -O2
dpkg-buildpackage: export de CPPFLAGS depuis dpkg-buildflags (origine : vendor): 
dpkg-buildpackage: export de CXXFLAGS depuis dpkg-buildflags (origine : vendor): -g -O2
dpkg-buildpackage: export de FFLAGS depuis dpkg-buildflags (origine : vendor): -g -O2
dpkg-buildpackage: export de LDFLAGS depuis dpkg-buildflags (origine : vendor): 
dpkg-buildpackage: paquet source publican
dpkg-buildpackage: version source 2.5-2
dpkg-buildpackage: source changé par Raphaël Hertzog 
dpkg-buildpackage: architecture hôte amd64
[...]
dpkg-deb: compilation du paquet `publican' en `../publican_2.5-2rh1_all.deb'.
 dpkg-genchanges  >../publican_2.5-2rh1_amd64.changes
dpkg-genchanges: sources originales non incluses en version amont
 dpkg-source --after-build publican-2.5
dpkg-buildpackage: binary and diff upload (sources originales NON incluses)
Lancement de lintian...
lintian : terminé.

La compilation est terminée. Les sources mises à jour ainsi que les paquets binaires ont été générés dans le dossier parent.

$ cd ..
$ ls -dF publican*
publican-2.5/                    publican_2.5-2rh1.dsc
publican_2.5-2.debian.tar.gz     publican_2.5-2rh1_amd64.changes
publican_2.5-2.dsc               publican_2.5-2rh1_source.changes
publican_2.5-2rh1_all.deb        publican_2.5.orig.tar.gz
publican_2.5-2rh1.debian.tar.gz

Cet article est une traduction de Howto to rebuild Debian packages contribuée par Weierstrass01. Abonnez-vous à ce blog par RSS ou par email pour recevoir tous les prochains articles et améliorer votre maîtrise de Debian/Ubuntu.

La bonne manière de supprimer un fichier de configuration obsolète dans un paquet Debian

Un conffile est un fichier de configuration géré par dpkg, mais je suis certain que vous vous souvenez de cet article introductif à propos des conffiles. Lorsque votre paquet cesse de fournir un conffile, celui-ci reste simplement sur le disque et est considéré comme « obsolète » par le gestionnaire de paquets. Il n’est retiré que dans le cas de la purge (et non de la simple suppression) du paquet. Si vous souhaitez que ce fichier soit retiré avant ce terme, il ne vous reste plus qu’à coder vous-même en ce sens les scripts de configuration de vos paquets. Voyons donc comment.

Quand est-ce nécessaire ?

dpkg privilégie la sécurité en ne supprimant pas ce fichier sauf en cas de purge. Pourtant, il est généralement plus avisé de le faire plus tôt pour ne pas induire l’utilisateur en erreur. C’est même obligatoire dans certains cas, puisque garder le conffile pourrait provoquer des erreurs logicielles (par exemple dans le cas où il se trouve dans un dossier « .d », et qu’il contient des entrées plus supportées ou contradictoires avec celles de nouveaux conffiles).

Qu’est-ce que « rm » a donc de compliqué ?

Vous souhaitez donc supprimer le conffile. Ajouter une commande « rm » dans debian/postinst semble plutôt facile. Certes, mais ce n’est pas du tout la bonne manière de procéder ! Il se pourrait que le conffile contienne certaines adaptations faites par l’administrateur, que vous ne souhaitez pas perdre. Plutôt que de supprimer, vous souhaitez plutôt garder le fichier dans un coin, afin que l’administrateur puisse récupérer ce qu’il avait fait et s’en servir comme bon lui semble.

La bonne action à prendre est donc de demander le déplacement de ce fichier dans le script prerm, afin d’éviter toute interférence avec la nouvelle version. Simultanément, vous devez vérifier si le conffile a été modifié par l’utilisateur, et, si c’est le cas, le retenir pour plus tard. Puis, dans le script postinst, le supprimer s’il n’y aucun changement entre la nouvelle et l’ancienne version, ou le garder sous un autre nom, si différence il y a. Ajouter un suffixe type .dpkg-bak est généralement suffisant, dans la mesure où de nombreuses applications sont configurées pour ne prendre en compte que les fichiers d’une certaine extension (*.conf, au hasard). run-parts, par exemple, ignore tous les fichiers contenant un point dans leurs noms. Dans le script postrm enfin, il est nécessaire de supprimer les conffiles conservés jusque-là en raison de changements locaux et, au cas où l’installation rendant obsolète le conffile est annulée, restaurer l’ancienne version.

Automatisons tout cela grâce à dpkg-maintscript-helper

Fioouuuu… c’est une longue liste de tâches à réaliser pour une action apparemment simple ! Heureusement, tout cela peut être automatisé grâce à dpkg-maintscript-helper. Partons du principe que vous souhaitez supprimer /etc/foo/conf.d/bar, du fait qu’il est maintenant dépassé et que vous préparez une nouvelle version 1.2-1 qui le supprimera lors de la mise à jour. Il vous suffit de copier-coller l’extrait de code suivant dans les 3 scripts (preinst, postinst, postrm) :

if dpkg-maintscript-helper supports rm_conffile 2>/dev/null; then
    dpkg-maintscript-helper rm_conffile /etc/foo/conf.d/bar 1.2-1 -- "$@"
fi

Le if peut être évité en posant une dépendance à « dpkg (>= 1.15.7.2) », ou s’il s’est écoulé suffisamment de temps pour supposer que tout le monde dispose d’une version assez récente. La page de manuel de dpkg-maintscript-helper vous apportera tous les détails nécessaires.

Cet article est une traduction de The right way to remove an obsolete conffile in a Debian package contribuée par Weierstrass01. Abonnez-vous à ce blog par RSS ou par email pour recevoir tous les prochains articles et améliorer votre maîtrise de Debian/Ubuntu.

Le plan secret derrière le format de paquet source Debian « 3.0 (quilt) »

New source package formats do wondersBien qu’ayant passé un nombre incalculable d’heures au développement du nouveau format source connu sous le nom de « 3.0 (quilt) », je n’ai réalisé que récemment que je n’avais encore rien écrit quant aux motivations qui m’ont conduit à le faire. Oubli auquel cet article va remédier.

Le bon vieux format « 1.0″

Jusqu’en 2008, dpkg-source n’était capable de gérer qu’un seul format source, maintenant connu comme le « 1.0″. Il s’agissait du format utilisé depuis le commencement du projet et, bien que fonctionnant sans problème dans la majorité des cas, il souffrait d’un certain nombre de limitations. Ceci principalement parce qu’il gérait l’empaquetage Debian comme un patch devant être appliqué par dessus le tarball source originel.

Ce patch pouvait avoir deux fonctions : créer les fichiers requis dans le sous-répertoire Debian et appliquer les modifications aux sources upstream. Mais au fil du temps, si le mainteneur du paquet procédait à plusieurs modifications du code source d’origine, ces dernières atterrissaient pêle-mêle — et sans documentation — dans ce seul patch. Des systèmes de gestion des patchs (dpatch, quilt, simple-patchsys, dbs, …) furent créés pour remédier à ce problème, et de nombreux mainteneurs commencèrent à les utiliser. L’implémentation diffère légèrement d’un système à l’autre, mais le principe de base reste le même : conserver les modifications des sources originales comme autant de patchs dans le dossier debian/patches/ et les appliquer à la compilation (et les enlever dans la règle clean en charge du nettoyage de l’arborescence).

Objectifs des nouveaux formats

Lorsque j’ai commencé à travailler sur le nouveau format source, j’avais comme objectif de m’affranchir des limitations connues et d’intégrer un système de gestion des patchs à dpkg-source. Je tenais à clarifier la situation de telle sorte que le fait d’apprendre à empaqueter ne nécessitait la connaissance que d’un seul système de patchs, et ne passait plus par la modification des debian/rules pour utiliser ce dernier. Je choisis quilt dans la mesure où il était populaire, disposait d’un large panel de fonctionnalités, et ne souffrait pas du syndrome du NIH. Tout cela conduisit au format source « 3.0 (quilt) ».

Dans le même temps naquit « 3.0 (native) » en tant que format distinct. Le format « 1.0″ était capable de générer deux types de paquet sources (natif et non-natif), mais je ne tenais pas à faire perdurer ce mélange des genres au sein d’un même format. Le principe du KISS édicte que l’utilisateur doit sélectionner le format de son choix, le mettre dans debian/source/format et c’est tout. Point final. Maintenant la compilation peut légitimement échouer lorsque les pré-requis ne sont pas satisfaits, plutôt que de basculer vers un « plan B » consistant en comportements inattendus.

Fonctionnalités du format « 3.0 (quilt) »

Il s’agit du format remplaçant le format 1.0 (non-natif). Les fonctionnalités ci-dessous sont spécifiques au nouveau format et le différencient de son ancêtre :

  • Support des formats de compression autres que gzip: bzip2, lzma, xz;
  • Utilisation de plusieurs tarball amont possible;
  • Inclusion de fichiers binaires dans l’empaquetage Debian possible;
  • Remplacement automatique du dossier « debian » dans le tarball amont (aucun ré-empaquetage nécessaire);
  • Création d’un patch (au standard quilt) dans debian/patches/ lorsque des changements par rapport aux fichiers upstream sont rencontrés.

Fonctionnalités du format « 3.0 (native) »

Ce format est très similaire à la variante « native » du format « 1.0″, excepté sur deux points :

  • Support des formats de compression autres que gzip: bzip2, lzma, xz;
  • Exclusion automatique des fichiers ne devant normalement pas faire partie du paquet (fichiers spécifiques aux VCS, fichiers de sauvegarde vim, …).

Chronologie

Un petit retour sur l’histoire de ce projet est intéressant. Celui-ci a déjà quelques années d’activité et ne pourra être considéré comme terminé uniquement lorsqu’une majorité de paquets auront migré vers les nouveaux formats.

  • Janvier 2008 : la discussion Comment gérer les patchs convenablement enflamme la liste de diffusion debian-devel@lists.debian.org. Le résultat de cette discussion constitue mes orientations initiales;
  • Mars 2008 : Je finis de concevoir les nouveaux formats et je lance un appel à retours d’utilisation. dpkg 1.14.17 (uploadé dans experimental) est la toute première version les supportant;
  • Avril 2008 : Demande aux ftpmasters via le ticket n°457345 de supporter les nouveaux formats de paquet source;
  • Juin 2008 : gel de Lenny. dpkg n’est plus supposé connaître de changements. Plusieurs changements concernant les nouveaux formats source sont cependant acceptés dans les mois qui suivent dans la mesure où ce code n’est, d’une part, pas encore utilisé en production, et d’autre part, car sa présence n’est requise que dans la mesure où elle doit permettre à Lenny de gérer les nouveaux formats lorsque Squeeze aura commencé à les utiliser;
  • Février 2009 : publlication de Lenny.
  • Mars 2009 : le travail sur Squeeze a débuté, mais les ftpmasters n’ont toujours rien fait concernant le support des nouveaux formats. Je soumets un patch à la suite du ticket n°457345 pour accélérer les choses. Je mets en place une page wiki pour suivre l’avancement du projet et répondre aux questions usuelles des mainteneurs de paquets;
  • Novembre 2009 : Après un sprint des ftpmasters, il est alors possible d’uploader des paquets aux nouveaux formats sources dans unstable. Cela focalise l’attention sur les nouveaux formats et certaines personnes commencent à se plaindre de certaines décisions de conception. L’implémentation du format « 3.0 (quilt) » change considérablement durant ce mois. La version de dpkg dans Lenny est même mise à jour pour la garder synchronisée avec ces changements;
  • Mars 2010 : je prévoyais jusque-là de laisser dpkg-source compiler lui-même les nouveaux paquets source dans le futur. Après plusieurs échanges, je conçois que cela ne constitue pas la meilleure manière de procéder et rend à la place obligatoire le fichier debian/source/format. Le mainteneur doit explicitement désigner le format source qu’il souhaite utiliser;
  • Octobre 2010 : Les nouveaux formats source sont relativement populaires : un tiers des paquets source ont déjà changé de format, cf. ce graphique. Le gel de Squeeze en août a clairement stoppé la dynamique;
  • Février 2011: Publication de Squeeze, les mainteneurs peuvent à nouveau faire évoluer leur paquets et le taux de conversion des paquets repart à nouveau.
  • Juin 2013 : fin du projet ?

Comme vous pouvez le constater, le projet n’est pas encore terminé, bien que la partie la plus difficile soit passée. En ce qui me concerne, le plus grand enseignement que j’en retire est que vous n’aurez jamais suffisamment de retour tant que votre travail n’est pas dans unstable. Aussi, si vous menez un projet Debian impactant un grand nombre de personnes, assurez-vous d’organiser un processus de revue officiel dès le début. Une des meilleures manières de le faire consiste probablement à décrire votre projet à travers une Proposition d’amélioration de Debian.

Si vous appréciez les efforts que j’ai consacrés à ce projet, n’hésitez pas à ouvrir un compte Flattr et à soutenir dpkg de temps en temps. Ou à visiter ma page « Soutenir mon travail« .

Cet article est une traduction de The secret plan behind the « 3.0 (quilt) » Debian source package format contribuée par Weierstrass01.

Comment générer des dépendances différentes pour Debian et Ubuntu avec un paquet source commun

Il arrive que les dépendances requises par certains paquets diffèrent entre Debian et Ubuntu. Il reste néanmoins possible de garder un seul paquet source, capable de générer plusieurs variantes distinctes. Cet article décrit comment faire, pas-à-pas.

1. Quand est-ce nécessaire ?

Bien qu’il soit possible d’avoir des dépendances différentes en fonction de la distribution pour laquelle le paquet est construit, cela doit autant que possible être évité, et ne constituer que la dernière option possible, comme par exemple lorsque :

  • Ubuntu dispose de paquets que Debian ne propose pas (et réciproquement), alors que le paquet qui nous occupe profiterait de leurs installations.
  • Le nom du paquet diffère entre les deux distributions (et ce de manière volontaire, non en raison d’un défaut de synchronisation entre Ubuntu et Debian)
  • Les paquets sont construits différemment dans les deux distributions, ce qui entraîne une différence de dépendances d’exécution. Certains patches ne peuvent être appliqués qu’à Ubuntu.

2. Variables de substitution dans debian/control

Les dépendances variant entre les distributions ne peuvent pas être écrites « en dur » dans debian/control. Il est par contre possible d’utiliser une variable de substitution (substvar) qui sera remplacée par dpkg-gencontrol au moment de la compilation. Elle peut par exemple être notée ${dist:Depends} :

[...]
Depends: bzip2, ${shlibs:Depends}, ${misc:Depends}, ${dist:Depends}
[...]

A noter qu’il est fort probable que vous ayez déjà d’autres variables de substitution telles que ${shlibs:Depends} pour dpkg-shlibdeps, ou ${misc:Depends} pour debhelper et ses scripts dh_*.

3. dpkg-gencontrol et option -V

Les valeurs de dépendance remplacées par cette nouvelle variable doivent être communiquées à dpkg-gencontrol, via l’option -V. Exemple :

dpkg-gencontrol [...] -Vdist:Depends="paquet-A (>= 2), paquet-B"

Si vous utilisez debhelper, l’option doit être passée à dh_gencontrol après deux tirets (--) :

dh_gencontrol -- -Vdist:Depends="paquet-A (>= 2), paquet-B"

Si vous utilisez CDBS, vous pouvez passer à la variable DEB_DH_GENCONTROL_ARGS_ALL la valeur souhaitée :

include /usr/share/cdbs/1/rules/debhelper.mk
DEB_DH_GENCONTROL_ARGS_ALL = -- -Vdist:Depends="paquet-A (>= 2), paquet-B"

Les valeurs passées à dpkg-gencontrol sont, dans tous les exemples précédents, statiques. Voyons maintenant comment les rendre dépendantes de la distribution visée.

4. Utiliser dpkg-vendor dans debian/rules

dpkg-vendor est un petit outil (fourni avec le paquet dpkg-dev) permettant d’interpréter le fichier /etc/dpkg/origins/default (fourni quant à lui par le paquet base-files) pour connaître la distribution actuelle ainsi que ses prédécesseurs. Il peut être utilisé dans debian/rules pour adapter le comportement en fonction de la distribution utilisée. La page de man explicite les nombreuses options supportées, nous allons quant à nous n’en utiliser qu’une ici : --derives-from <vendor>. Cette option entraîne le renvoi d’un code retour à la fin du script, égal à 0 si la distribution utilisée est — ou dérive de — celle indiquée, et vaut 1 sinon.

Si l’on assemble maintenant toutes les pièces du puzzle entre elles, on peut donc utiliser dpkg-vendor pour définir dynamiquement la valeur de la variable de substitution dans debian/rules. Supposons par exemple que votre paquet doit dépendre de « paquet-A (>= 2) » sur Ubuntu (et ses dérivés), de « paquet-B » sinon. En utilisant le fichier de règles de debhelper 7, cela donne :

ifeq ($(shell dpkg-vendor --derives-from Ubuntu && echo yes),yes)
	SUBSTVARS = -Vdist:Depends="paquet-A (>= 2)"
else
	SUBSTVARS = -Vdist:Depends="paquet-B"
endif

%:
	dh $@

override_dh_gencontrol:
	dh_gencontrol -- $(SUBSTVARS)

Si vous utilisez CDBS, cela donnerait :

include /usr/share/cdbs/1/rules/debhelper.mk
ifeq ($(shell dpkg-vendor --derives-from Ubuntu && echo yes),yes)
	DEB_DH_GENCONTROL_ARGS_ALL = -- -Vdist:Depends="paquet-A (>= 2)"
else
	DEB_DH_GENCONTROL_ARGS_ALL = -- -Vdist:Depends="paquet-B"
endif

Cet article est une traduction de How to generate different dependencies on Debian and Ubuntu with a common source package contribuée par Weierstrass01. Suivez moi sur Identi.ca, Twitter et Facebook. Ou abonnez-vous à ce blog par RSS ou par email.

Comment créer des paquets Debian avec une méthode de compression alternative

Alors que gzip vient immédiatement à l’esprit quand il s’agit de compression de fichiers, d’autres outils existent et permettent même d’atteindre un meilleur ratio de compression que celui-ci. Cet article explique comment tirer parti de ces alternatives dans votre travail d’empaquetage Debian.

Dans le paquet source

Un paquet source se compose de plusieurs fichiers. Le fichier .dsc n’est jamais compressé, ce qui ne pose aucun problème puisqu’il s’agit d’un petit fichier texte. Outre via gzip (orig.tar.gz), les archives TAR amont peuvent être compressés grâce à bzip2 (orig.tar.bz2), lzma (orig.tar.lzma) ou xz (orig.tar.xz). À vous de choisir si l’archive amont est proposée sous différents formats de compression. Placez-le au bon endroit et dpkg-source l’utilisera automatiquement. Il est à noter toutefois que dans le cas du format source 1.0 seul gzip est utilisable, tandis que l’archive principale Debian n’autorise actuellement que gzip et bzip2 (xz suivra éventuellement plus tard), même si le format source « 3.0 (quilt) » les supporte tous.

Les fichiers d’empaquetage Debian sont fournis soit sous forme de fichier .diff.gz pour le format source 1.0 (seul gzip est supporté ici aussi), soit sous forme de fichier .debian.tar pour le format source « 3.0 (quilt) ». Cette dernière archive pouvant être compressée via l’outil de votre choix, il suffit de le spécifier à dpkg-source (cf. ci-dessous. À noter que la valeur par défaut correspond à l’utilisation de gzip).

Dpkg-source doit générer l’archive principale dans le cas d’un paquet natif et il est possible de lui faire utiliser autre chose que gzip, grâce à l’option --compression. Cette option est usuellement placée dans le fichier debian/source/options:

# Utilisation de bzip2 au lieu de gzip
compression = "bzip2"
compression-level = 9

Cette option n’est généralement pas très utile dans le cas des paquets sources au format « 3.0 (quilt) », dans la mesure où l’archive Debian compressée n’est pas d’une taille importante. Ceci étant, certains mainteneurs préfèrent utiliser le même outil de compression pour l’archive amont et l’archive Debian. Vous êtes donc libre d’utiliser cette option dans un souci d’harmonisation.

C’est par contre bien plus intéressant dans le cas des paquets natifs : pour exemple la taille du paquet source dpkg a été réduite de 30% en passant à bzip2, sauvant ainsi 2Mo d’espace disque.

Dans les paquets binaires

Les fichiers .deb contiennent également des archives compressées au format tar, et utilisent également gzip par défaut :

$ ar t dpkg_1.15.8.9_i386.deb 
debian-binary
control.tar.gz
data.tar.gz

L’archive data.tar.gz contient tous les fichiers à installer, et c’est précisément celle que vous pouvez compresser via un outil alternatif à gzip. Rappelons que ce n’est vraiment intéressant que dans le cas des — très — gros paquets, dont la taille justifie l’écart par rapport au processus standard de compression. Essayez et regardez un peu combien de Mo vous parvenez à sauver ! Le fait que ces alternatives puissent nécessiter une quantité importante de mémoire (que ce soit pour la compression ou la décompression) ne doit pas être négligé : dans le cas de plate-formes embarquées ou de matériels d’entrée de gamme disposant de peu de mémoire, il peut être intéressant de conserver gzip.

Ceci étant dit, quelle est donc la manière de procéder ? Rien de plus facile, dpkg-deb met à disposition l’option -Z, à laquelle il suffit de passer « -Zbzip2 » par exemple. Il est également possible de passer « -z6 » pour changer le ratio de compression à 6 (ce qui peut être utile car un niveau de compression inférieur peut entraîner une empreinte mémoire plus faible, selon le programme utilisé). L’invocation de dpkg-deb étant habituellement masquée derrière l’appel à dh_builddeb dans le fichier /debian/rules, il faut modifier ce dernier avec « dh_builddeb -- -Zbzip2 ».

Si vous utilisez les fichiers de règles de debhelper 7, il vous faudra neutraliser le comportement standard via par exemple l’ajout de :

%:
	dh $@

override_dh_builddeb:
	dh_builddeb -- -Zbzip2

Si vous utilisez CDBS, la variable d’environnement DEB_DH_BUILDDEB_ARGS doit être initialisée à :

include /usr/share/cdbs/1/rules/debhelper.mk
[...]
DEB_DH_BUILDDEB_ARGS = -- -Zbzip2

Cet article est une traduction de How to create Debian packages with alternative compression methods contribuée par Weierstrass01. Abonnez-vous à ce blog par RSS ou par email pour recevoir tous les prochains articles et améliorer votre maîtrise de Debian/Ubuntu.