Provided by:
debconf-doc_1.5.32ubuntu3_all 
NOM
debconf - guide du developpeur
DESCRIPTION
C'est un guide pour creer des paquets qui utilisent debconf.
Ce manuel suppose que vous connaissez bien debconf en tant
qu'utilisateur et que vous etes familier avec les bases de la
construction des paquets Debian.
Ce manuel commence par expliquer les deux nouveaux fichiers ajoutes aux
paquets Debian qui utilisent debconf. Puis il explique comment le
protocole debconf fonctionne et vous indique les bibliotheques qui
permettent de communiquer avec le protocole. Il traite les autres
scripts d'administration ou debconf est typiquement utilise : les
scripts postinst et postrm. Ensuite, il passe a des sujets plus pointus
comme le partage des questionnaires debconf, le debogage, d'autres
techniques courantes et les pieges de la programmation avec debconf. Il
se termine par une discussion sur les defauts actuels de debconf.
LE SCRIPT DE CONFIGURATION
Debconf ajoute un script d'administration, le script config, au jeu de
scripts pouvant etre presents dans un paquet Debian (les scripts
postinst, preinst, postrm, prerm). Le script config doit poser toutes
les questions necessaires a la configuration du paquet.
Remarque : il est un peu ennuyeux que dpkg considere le script postinst
du paquet comme un script de << configuration >> du paquet ; en effet,
un paquet utilisant debconf est souvent pre-configure, par son script
config, avant que le script postinst soit lance. Mais, bon !
Lorsque le script config est lance, deux parametres lui sont passes ;
il en va de meme pour le script postinst. Le premier est l'action a
effectuer et le second est la version du paquet actuellement installe.
Donc, comme pour un script postinst, vous pouvez utiliser
dpkg --compare-versions sur $2 pour effectuer une action seulement en
cas de mise a niveau d'une version particuliere du paquet ou d'autres
actions de ce type.
Le script config peut etre lance de l'une de ces trois facons :
1 Si un paquet est pre-configure, avec dpkg-preconfigure, son
script config est lance avec les parametres << configure >> et
<< installed-version >>.
2 Lorsque le script postinst d'un paquet est lance, debconf
essaiera aussi de lancer le script config, avec les memes
parametres que ceux qui sont passes lorsqu'il est pre-configure.
C'est necessaire car le paquet n'a peut-etre pas ete
pre-configure, et donc le script config doit alors etre lance.
Veuillez consulter la section BIDOUILLES pour plus de
precisions.
3 Si un paquet est reconfigure, avec dpkg-reconfigure, son script
config est lance et les parametres << reconfigure >> et le
numero de la version installee lui sont passes.
Notez que puisqu'une installation ou une mise a niveau typique
utilisant apt execute les etapes 1 et 2, le script config sera lance
deux fois. La seconde fois, il ne devrait rien faire (poser les
questions deux fois de suite est ennuyeux) et il devrait etre nettement
idempotent. Par chance, debconf evite par defaut de repeter les
questions, donc c'est relativement facile a effectuer.
Notez que le script config est lance avant que le paquet ne soit
depaquete. Il ne devrait utiliser que des commandes disponibles dans
les paquets essentiels. La seule dependance qui est sure d'etre
satisfaite lorsque son script config est lance est une dependance
(eventuellement sur une version specifique) sur debconf lui-meme.
Le script config ne devrait pas avoir besoin de modifier le systeme de
fichiers. Il verifie seulement l'etat du systeme et pose des questions.
Debconf conserve alors les reponses, qui pourront etre utilisees par le
script postinst. Et inversement, le script postinst ne devrait presque
jamais utiliser debconf pour poser des questions, mais devrait a la
place utiliser les reponses aux questions posees par le script config.
LE FICHIER TEMPLATES
Un paquet qui utilise debconf voudra probablement poser quelques
questions. Ces questions sont conservees sous une forme standard dans
le fichier templates.
Comme le script config, le fichier templates est inclus dans la section
control.tar.gz d'un paquet. Son format est semblable a celui du fichier
control Debian ; un ensemble de paragraphes separes par des lignes
vides, ou chaque paragraphe possede une forme du type RFC 822 :
Template: toto/tata
Type: string
Default: toto
Description: Il s'agit d'un exemple de question
Ceci est la description longue
.
Veuillez noter que :
- comme dans une description de paquet Debian, un point seul
definit un
nouveau paragraphe ;
- la plupart du texte est reformate, mais le texte avec une
indentation
double est garde tel quel, ainsi vous pouvez l'utiliser pour des
listes,
comme celle-ci. Soyez prudent, comme il n'est pas reformate, s'il
est
trop large, il s'affichera mal. Il vaut mieux l'utiliser pour des
elements courts (donc ceci est un mauvais exemple).
Template: toto/titi
Type: boolean
Description: C'est clair n'est-ce pas ?
Ceci est une autre question, de type booleenne.
Pour des exemples concrets de fichiers templates, regardez
/var/lib/dpkg/info/debconf.templates, ainsi que les autres fichiers
.templates de ce repertoire.
Examinons chaque champ successivement :
Template
Le nom du message, dans le champ << Template >>, est
generalement prefixe avec le nom du paquet. Ensuite, l'espace de
nommage est tres libre ; vous pouvez utiliser une simple
disposition plane, ou definir des << sous-repertoires >>
contenant ces questions.
Type Le type du message determine le type d'objet devant etre
presente a l'utilisateur. Les types actuellement reconnus sont :
string C'est un champ libre ou l'utilisateur peut taper
n'importe quelle chaine de caracteres.
password
Demande a l'utilisateur un mot de passe. Utilisez-le avec
precaution ; soyez conscient que le mot de passe que
l'utilisateur indique sera ecrit dans la base de donnees
de debconf. Vous devriez probablement effacer cette
valeur de la base de donnees des que possible.
boolean
Un choix du type << vrai ou faux >>.
select Un choix entre des valeurs. Les choix doivent etre
specifies dans un champ nomme << Choices >>. Les valeurs
sont separees par des virgules et des espaces, comme
ceci :
Choices: oui, non, peut-etre
multiselect
Comme le type de donnees select, excepte que
l'utilisateur peut choisir plusieurs elements de la liste
(ou n'en choisir aucun).
note A la place d'une question, ce type de donnees indique une
note qui peut etre affichee a l'utilisateur. Elle ne
devrait etre utilisee que pour des notes importantes que
l'utilisateur doit absolument lire, car debconf va
deployer les grands moyens pour s'assurer que
l'utilisateur la lira ; en arretant l'installation et en
attendant qu'il presse une touche. Il est preferable de
n'utiliser ceci que pour signaler des problemes tres
serieux et le type de donnees << error >> est souvent
plus approprie.
error Ce type de donnees est utilise pour les messages
d'erreur, comme des erreurs d'entree invalide. Debconf
posera une question de ce genre meme si la priorite est
trop haute, ou si l'utilisateur l'a deja vue.
title Ce type de donnees est utilise pour les titres, afin
qu'ils soient positionnes avec la commande SETTITLE.
text Ce type de donnees peut etre utilise pour des portions de
texte, comme des etiquettes, qui peuvent etre utilisees
pour des raisons cosmetiques dans l'affichage de
certaines interfaces. D'autres interfaces ne
l'utiliseront pas. Il n'y a pas de raison de l'utiliser
pour l'instant, puisqu'aucune interface ne le gere
correctement. Il risque meme d'etre supprime dans le
futur.
Default
Le champ << Default >> indique a debconf la valeur par defaut.
Pour multiselect, elle peut etre une liste de choix separes par
des virgules semblable au champ << Choices >>. Pour select, elle
devrait etre l'un des choix possibles. Pour Boolean, c'est
<< true >> ou << false >>, alors que cela peut etre n'importe
quoi pour une chaine de caracteres et est ignore pour les mots
de passe.
Ne faites pas l'erreur de penser que le champ default contient
la << valeur >> de la question, ou qu'il puisse etre utilise
pour changer la valeur de la question. Il ne le fait pas, et ne
le peut pas, il fournit seulement une valeur par defaut
lorsqu'une question est affichee pour la premiere fois. Pour
fournir une valeur par defaut qui change a la volee, vous
devriez utiliser la commande SET pour changer la valeur de la
question.
Description
Le champ << Description >>, comme la description d'un paquet
Debian, est constitue de deux parties : une description courte
et une description longue. Notez que certaines interfaces
debconf n'affichent pas la description longue, ou ne l'affichent
que si l'utilisateur demande de l'aide. La description courte
doit donc suffire a la comprehension du message.
Si vous n'arrivez pas a trouver une description longue,
premierement, reflechissez-y plus longuement. Postez sur
debian-devel. Demandez de l'aide. Prenez votre plus belle
plume ! Car la description longue est importante. Si apres tout
ca vous n'arrivez toujours pas a proposer quelque chose,
laissez-la vide. Cela n'apporte rien de recopier la description
courte.
Le texte dans la description longue sera reformate, a moins
qu'il ne soit prefixe avec une espace supplementaire (apres
l'espace requise). Vous pouvez le decouper en plusieurs
paragraphes en les separant par " ." sur une ligne.
QUESTIONS
Une question est une instance d'un message. En demandant a debconf
d'afficher une question, votre script config peut interagir avec
l'utilisateur. Quand debconf charge un questionnaire (cela arrive a
chaque fois qu'un script postinst ou config est lance), il cree
automatiquement la question a partir du message. Il est possible de
creer plusieurs questions independantes a partir d'un meme message (en
utilisant la commande REGISTER), mais c'est rarement necessaire. Les
messages sont des donnees statiques qui proviennent du fichier
templates, alors que les questions sont utilisees pour conserver des
donnees dynamiques, comme la valeur actuelle d'une question, ou si un
utilisateur a deja vu une question, etc. Gardez bien a l'esprit la
difference entre un message et une question, mais ne vous inquietez pas
trop.
MESSAGES PARTAG'ES
Il est tout a fait possible que des paquets partagent un message et une
question. Tous les paquets doivent fournir une copie identique du
message dans leur fichier templates. Cela peut etre utile si un groupe
de paquets a besoin de poser les memes questions et que vous avez envie
de ne deranger les utilisateurs qu'une seule fois. Les messages
partages sont generalement places dans le pseudo-repertoire shared/
dans l'espace de nommage des questionnaires debconf.
LE PROTOCOLE DEBCONF
Les scripts config communiquent avec debconf en utilisant le protocole
debconf. C'est un protocole simple oriente ligne, semblable aux
protocoles internet courants comme SMTP. Le script config envoie a
debconf une commande en l'ecrivant sur la sortie standard. Il peut
alors lire la reponse de debconf depuis l'entree standard.
Les reponses de debconf peuvent etre scindees en deux parties : un code
de retour numerique (le premier mot de la reponse) et un code de retour
etendu facultatif (le reste de la reponse). Le code numerique utilise 0
pour indiquer un succes et d'autres nombres pour indiquer divers types
d'erreur. Pour plus de precisions, veuillez consulter le tableau dans
les specifications debconf de la charte Debian.
Le code de retour etendu n'a generalement aucune forme particuliere,
vous pourrez donc, dans la plupart des cas, l'ignorer et vous ne
devriez pas essayer de l'analyser dans un programme pour savoir ce que
debconf est en train de faire. Les commandes comme GET sont des
exceptions car elles retournent une valeur dans le code de retour
etendu.
Vous voudrez generalement utiliser une bibliotheque specifique a un
langage qui gere l'aspect pratique des connexions et des communications
avec debconf.
Maintenant, voici les commandes de ce protocole. Ce n'est pas une
definition complete, veuillez consulter les specifications debconf de
la charte Debian pour plus d'informations.
VERSION nombre
Vous n'aurez, en general, pas besoin d'utiliser cette commande.
Elle echange avec le protocole debconf le numero de la version
utilisee. La version actuelle du protocole est 2.0 et les
versions de la serie 2.x assureront la compatibilite ascendante.
Vous pouvez specifier le numero de version du protocole que vous
parlez et debconf retournera la version du protocole qu'il parle
dans le code de retour etendu. Si la version que vous specifiez
est trop faible, debconf renverra un code de retour numerique
egal a 30.
CAPB fonctionnalit'es
Vous n'aurez, en general, pas besoin d'utiliser cette commande.
Elle echange avec debconf une liste des fonctionnalites
reconnues. Des fonctionnalites supportees par vous et debconf
seront utilisees et debconf repondra avec toutes les
fonctionnalites qu'il accepte.
Si << escape >> ne fait pas partie de vos fonctionnalites,
debconf va attendre que les commandes que vous lui passez
comportent des antislashes et des caracteres de retour a la
ligne echappes (comme \\ et \n respectivement) et va faire de
meme pour ses reponses. Ceci peut etre utilise par exemple pour
changer des chaines de caracteres multilignes en modeles, ou
pour recuperer des descriptions etendues multilignes de maniere
fiable en utilisant METAGET.
SETTITLE question
Utilisez la description courte du message comme titre de l'ecran
debconf pour la question indiquee. Le message devrait etre de
type titre. Vous n'aurez que rarement besoin de cette commande
puisque debconf peut automatiquement generer un titre base sur
le nom de votre paquet.
Definir le titre depuis un message signifie que les titres
seront stockes a la meme place que les autres questions posees
par debconf. Elle permet aussi de traduire ces titres.
TITLE cha^ine de caract`eres
Utiliser la chaine de caracteres comme titre de l'ecran debconf.
L'utilisation de la commande SETTITLE est preferable car elle
permet de traduire les titres affiches par debconf.
INPUT priorit'e question
Demande a debconf de preparer l'affichage d'une question a
l'utilisateur. La question n'est pas affichee jusqu'a ce que la
commande GO soit lancee ; cela permet de lancer plusieurs
commandes INPUT en serie, pour construire un jeu de questions
qui pourraient toutes etre posees sur un seul ecran.
Le champ priorite indique a debconf s'il est important que la
question soit posee a l'utilisateur ou non. Les priorites sont :
low Elements peu importants dont la valeur par defaut
convient dans la majorite des cas ; seuls ceux qui
veulent tout controler les voient ;
medium Elements normaux qui ont une valeur par defaut
raisonnable ;
high Elements qui n'ont pas de valeur par defaut raisonnable ;
critical
Elements qui peuvent probablement casser le systeme sans
l'intervention de l'utilisateur.
Pour decider si la question doit etre affichee ou non, debconf
se base sur sa priorite, si l'utilisateur l'a deja vue et
l'interface qui va etre utilisee. Si la question n'est pas a
afficher, debconf retournera un code de retour egal a 30.
GO
Cette commande demande a debconf d'afficher les questions
accumulees (depuis les commandes INPUT).
Si la fonctionnalite de sauvegarde est supportee et si
l'utilisateur indique qu'il veut revenir a une etape precedente,
debconf repondra avec un code de retour egal a 30.
CLEAR Elimine les questions accumulees (avec les commandes INPUT) sans
les afficher.
BEGINBLOCK
ENDBLOCK
Certaines interfaces peuvent afficher plusieurs questions a
l'utilisateur en meme temps. Peut-etre qu'a l'avenir une
interface pourra regrouper ces questions en blocs sur l'ecran.
BEGINBLOCK et ENDBLOCK peuvent etre placees autour de plusieurs
commandes INPUT pour indiquer des blocs de questions (les blocs
peuvent meme etre emboites). Etant donne qu'aucune interface
n'est encore aussi sophistiquee, ces commandes sont pour
l'instant ignorees.
STOP Cette commande dit a debconf que vous avez fini de communiquer
avec lui. En general, debconf peut detecter la fin de votre
programme, cette commande n'est donc pas necessaire.
GET question
Apres avoir utilise INPUT et GO pour afficher une question, vous
pouvez utiliser cette commande pour recuperer la valeur indiquee
par l'utilisateur. Cette valeur est renvoyee dans le code de
retour etendu.
SET question valeur
Cette commande positionne la valeur d'une question et peut etre
utilisee pour remplacer la valeur par defaut avec une valeur que
votre programme calcule a la volee.
RESET question
Cela remet la question a sa valeur par defaut (comme il est
specifie dans le champ << Default >> de son message).
SUBST question cl'e valeur
Des questions peuvent avoir des substitutions incluses dans
leurs champs << Description >> et << Choices >> (l'utilisation
de substitutions dans les champs << Choices >> fait un peu
bidouillage, un meilleur mecanisme sera developpe). Ces
substitutions ressemblent a << ${key} >>. Quand les questions
sont affichees, les substitutions sont remplacees par leurs
valeurs. Cette commande peut etre utilisee pour fixer la valeur
d'une substitution. Cela peut etre utile si vous avez besoin
d'afficher a l'utilisateur des messages que vous ne pouvez pas
mettre dans le fichier templates.
N'essayez pas d'utiliser SUBST pour changer la valeur par defaut
d'une question ; cela ne fonctionnera pas puisqu'il y a la
commande SET prevue a cet effet.
FGET question marque
Une marque peut etre associee a une question. Les marques
peuvent avoir une valeur << true >> ou << false >>. Cette
commande renvoie la valeur de la marque.
FSET question marque valeur
Cela fixe la valeur de la marque d'une question. La valeur est
soit << true >> soit << false >>.
La marque << seen >> est courante. Elle n'est normalement
positionnee que si un utilisateur a deja vu la question.
Habituellement, debconf affiche a l'utilisateur seulement les
questions dont la marque << seen >> est positionnee a
<< false >> (ou si vous reconfigurez un paquet). Quelquefois
vous voulez que l'utilisateur revoie une question -- dans ce cas
vous pouvez positionner la marque << seen >> a false pour forcer
debconf a l'afficher a nouveau.
METAGET question champ
Cela renvoie la valeur d'un champ d'une question associee a un
message (le champ Description, par exemple).
REGISTER message question
Cela cree une nouvelle question qui est liee a un message. Par
defaut, chaque message possede une question du meme nom qui lui
est associee. Toutefois, on peut associer autant de questions
que l'on veut a un message et cela permet de creer beaucoup de
questions.
UNREGISTER question
Cela retire une question de la base de donnees.
PURGE Appelez cette commande dans votre script postrm lorsque votre
paquet est purge. Il retire toutes les questions concernant
votre paquet de la base de donnees de debconf.
X_LOADTEMPLATEFILE /path/to/templates [owner]
Cette extensions charge le fichier de modele specifie dans la
base de donnees de debconf. Le proprietaire assume que le paquet
est en cours de configuration avec debconf.
Voici un exemple simple du protocole debconf en action.
INPUT medium debconf/frontend
30 question skipped
FSET debconf/frontend seen false
0 false
INPUT high debconf/frontend
0 question will be asked
GO
[ debconf affiche ici une question a l'utilisateur. ]
0 ok
GET no/such/question
10 no/such/question doesn't exist
GET debconf/frontend
0 Dialog
BIBLIOTH`EQUES
Comme parler directement a debconf via son protocole represente trop de
travail, il existe quelques bibliotheques pour vous epargner cette
tache ingrate.
Pour la programmation shell, il y a la bibliotheque
/usr/share/debconf/confmodule que vous pouvez inclure en debut d'un
script shell ; vous pourrez communiquer avec debconf de facon presque
naturelle en utilisant la version en minuscules des commandes du
protocole debconf qui sont prefixees de << db_ >> (par ex.
<< db_input >> et << db_go >>). Pour plus de precisions veuillez
consulter confmodule(3).
Les programmeurs Perl peuvent utiliser le module perl
Debconf::Client::ConfModule(3) et les programmeurs Python peuvent
utiliser le module python debconf.
Le reste de ce manuel utilisera la bibliotheque
/usr/share/debconf/confmodule dans des scripts shell a titre d'exemple.
Voici un exemple de script config utilisant cette bibliotheque, il pose
seulement une question :
#!/bin/sh
set -e
. /usr/share/debconf/confmodule
db_set mypackage/reboot-now false
db_input high mypackage/reboot-now || true
db_go || true
Remarquez l'utilisation de << || true >> pour eviter que le script ne
meurt si debconf decide qu'il ne peut pas afficher une question, ou si
l'utilisateur essaie de revenir en arriere. Dans ces situations,
debconf renvoie un code de retour non nul et puisque set -e est
positionne dans ce script shell, un code de retour non intercepte le
fera abandonner.
Et voici le script postinst correspondant, qui utilise la reponse a la
question de l'utilisateur pour voir si le systeme doit etre redemarre
(un exemple plutot stupide) :
#!/bin/sh
set -e
. /usr/share/debconf/confmodule
db_get mypackage/reboot-now
if [ "$RET" = true ]; then
shutdown -r now
fi
Remarquez l'utilisation de la variable $RET pour recuperer le code de
retour etendu de la commande GET, qui contient la reponse de
l'utilisateur a la question.
LE SCRIPT POSTINST
La derniere section avait un exemple de script postinst qui utilise
debconf pour recuperer la valeur d'une question et agir selon elle.
Voici quelques remarques a garder a l'esprit lors de l'ecriture des
scripts postinst qui utilisent debconf :
* evitez de poser des questions dans le script postinst. Le script
config devrait poser ces questions a sa place en utilisant
debconf, pour que la pre-configuration fonctionne par la suite ;
* incluez toujours /usr/share/debconf/confmodule au debut de votre
script postinst, meme si vous ne lancez aucune des commandes
db_*. C'est necessaire pour s'assurer que le script config sera
bien lance (veuillez consulter la section BIDOUILLES pour plus
de details) ;
* evitez d'afficher quelque chose sur la sortie standard dans
votre script postinst, puisque cela peut perturber debconf ; le
script postinst ne devrait de toute facon pas etre bavard.
L'affichage sur la sortie d'erreur est autorise, si vous le
devez ;
* si votre script postinst lance un demon, soyez sur de dire a
debconf de STOPper a la fin, car debconf peut avoir du mal a
detecter la fin du script postinst ;
* faites accepter a votre script postinst un premier parametre
<< reconfigure >>. Il peut le traiter comme << configure >>.
Cela sera utilise dans une version ulterieure de debconf pour
permettre aux scripts postinst de savoir quand ils sont
reconfigures.
AUTRES SCRIPTS
En plus des scripts config et postinst, vous pouvez utiliser debconf
dans tout autre script d'administration. En general, vous utiliserez
debconf dans votre script postrm, pour appeler la commande PURGE quand
votre paquet est supprime, pour vider ses entrees dans la base de
donnees de debconf. En fait, cela est automatiquement configure pour
vous par dh_installdebconf(1).
Un emploi plus sophistique de debconf serait de l'utiliser dans le
script postrm lors de la purge de votre paquet, pour poser une question
concernant la suppression de quelque chose. Ou peut-etre avez-vous
besoin de l'utiliser dans les scripts preinst ou prerm pour quelque
raison que ce soit. Toutes ces utilisations fonctionneront, bien
qu'elles impliqueront probablement de poser une question et d'agir en
fonction de la reponse dans le meme programme, plutot que de separer
les deux actions comme dans les scripts config et postinst.
Notez que si votre paquet n'utilise debconf que dans le script postrm,
vous devriez faire en sorte que le script postinst de votre paquet
inclue /usr/share/debconf/confmodule, pour que debconf puisse charger
votre fichier templates dans sa base de donnees. Le questionnaire sera
alors disponible lorsque votre paquet sera purge.
Vous pouvez aussi utiliser debconf dans d'autres programmes
independants. Le seul probleme est que debconf n'est pas concu pour
etre un systeme d'enregistrement et ne peut pas etre utilise comme tel.
La philosophie d'Unix est preservee, les programmes sont configures a
l'aide de fichiers dans /etc, et non pas par une sombre base de donnees
debconf (ce n'est qu'un cache et il peut se volatiliser). Reflechissez
donc longuement avant d'utiliser debconf dans un programme independant.
Cela peut prendre un sens dans certains cas, comme dans le programme
apt-setup qui utilise debconf pour interroger l'utilisateur de maniere
coherente avec le reste de la procedure d'installation de Debian et qui
agit immediatement avec les reponses pour configurer le fichier
sources.list.
LOCALISATION
Debconf accepte la localisation des fichiers templates. Cela est
accompli en ajoutant d'autres champs contenant les traductions. Tous
les champs peuvent etre traduits. Par exemple, vous pourriez avoir
envie de traduire la description en espagnol. Creez simplement un champ
nomme << Description-es >> contenant la traduction. Si un champ traduit
n'est pas disponible, debconf utilise le champ anglais.
En plus du champ << Description >>, vous devriez traduire le champ
<< Choices >> d'un message de type select ou multiselect. Il faut
lister les choix traduits dans l'ordre dans lequel ils apparaissent
dans le champ << Choices >> principal. Vous ne devriez pas avoir besoin
de traduire le champ << Default >> d'une question de type select ou
multiselect et la valeur de la question sera automatiquement retournee
en anglais.
Vous trouverez surement plus facile de gerer les traductions si vous
les conservez dans des fichiers separes ; un fichier par traduction.
Par le passe, les programmes debconf-getlang(1) et
debconf-mergetemplate(1) etaient utilises pour gerer les fichiers
debian/templates.ll. Cela a ete rendu obsolete par le paquet
po-debconf(7), qui permet de traiter les traductions des questionnaires
debconf avec des fichiers .po comme les autres traductions. Vos
traducteurs vous remercieront pour l'utilisation de ce nouveau
mecanisme performant.
Pour plus de precisions sur po-debconf, consultez sa page de manuel. Si
vous utilisez debhelper, la conversion vers po-debconf est aussi simple
que de lancer la commande debconf-gettextize(1) une fois et d'ajouter
une dependance de construction (<< Build-Depends >>) sur po-debconf et
sur debhelper (>= 4.1.13).
R'ECAPITULATION
Donc vous avez un script config, un fichier templates, un script
postinst qui utilisent debconf, etc. Reunir tous ces scripts dans un
paquet Debian n'est pas difficile. Vous pouvez le faire a la main ou
utiliser dh_installdebconf(1) qui fusionne vos questions-modeles
traduites, copie les fichiers a la bonne place pour vous et peut meme
generer l'appel a PURGE qui devrait etre place dans votre script
postrm. Assurez-vous que votre paquet depende de debconf (>= 0.5),
puisque les anciennes versions n'etaient pas compatibles avec tout ce
qui est decrit dans ce manuel. Et c'est termine !
Mais vous ne pouvez pas encore tester, deboguer et utiliser debconf
pour des choses plus interessantes que de poser de simples questions.
Pour cela, veuillez continuer a lire.
D'EBOGAGE
Vous avez donc un paquet qui est suppose utiliser debconf, mais il ne
fonctionne pas tres bien. Peut-etre que debconf ne pose pas la question
que vous avez configuree. Ou peut-etre que quelque chose d'etrange
arrive ; il entre dans une boucle infinie, ou pire encore.
Heureusement, debconf possede beaucoup de possibilites de debogage.
DEBCONF_DEBUG
La premiere chose a portee de main est la variable
d'environnement DEBCONF_DEBUG. Si vous positionnez et exportez
DEBCONF_DEBUG=developer, debconf affichera sur la sortie
d'erreur standard (<< stderr >>) une copie du protocole debconf
lorsque votre programme s'execute. Elle ressemblera a quelque
chose comme ceci -- la faute est flagrante :
debconf (developer): <-- input high debconf/frontand
debconf (developer): --> 10 "debconf/frontand" doesn't exist
debconf (developer): <-- go
debconf (developer): --> 0 ok
Lors d'un debogage, l'interface readline de debconf est tres
utile (d'apres l'auteur), car les questions ne masquent pas cet
affichage, toute la sortie du debogage est facilement preservee
et enregistree.
DEBCONF_C_VALUES
Si cette variable d'environnement est definie a << true >>,
l'interface graphique affichera les valeurs dans le champ
<< Choices-C >> (s'il est present) des modeles select et
multi-select au lieu des valeurs comprehensibles.
debconf-communicate
debconf-communicate(1) est un autre programme utile. Lancez-le
et vous pourrez parler le protocole debconf brut a debconf.
C'est une bonne maniere d'essayer des choses a la volee.
debconf-show
Si un utilisateur rapporte un probleme, debconf-show(1) peut
etre utilise pour lister les questions de votre paquet, en
affichant leurs valeurs et en indiquant si l'utilisateur les a
deja vues.
.debconfrc
Pour eviter le cycle ennuyeux
construction/installation/debogage, il peut etre utile de
charger vos questionnaires avec debconf-loadtemplate(1) et de
lancer votre script config a la main avec la commande
debconf(1). Neanmoins, vous devez toujours le faire en tant que
superutilisateur, d'accord ? Pas terrible ! Et idealement vous
souhaiteriez etre en mesure de voir a quoi ressemble une
installation toute fraiche de votre paquet avec une base de
donnees debconf propre.
Il s'avere que si vous configurez un fichier ~/.debconfrc pour
un utilisateur normal, pointant vers un config.dat et un
template.dat propres a l'utilisateur, vous pouvez charger les
questionnaires et lancer tous les scripts config que vous
voulez, sans avoir besoin d'un acces super-utilisateur. Si vous
voulez commencer avec une base de donnees propre, supprimez
simplement les fichiers *.dat.
Pour plus de details pour mettre cela en place, voyez
debconf.conf(5), et remarquez que /etc/debconf.conf fait un bon
modele pour un fichier ~/.debconfrc personnel.
PROGRAMMATION AVANC'EE AVEC DEBCONF
Manipulation du fichier de configuration
Beaucoup d'entre vous ont l'air de vouloir utiliser debconf pour aider
a la gestion des fichiers de configuration contenus dans vos paquets.
Peut-etre qu'il n'y a pas de bonne valeur par defaut a inclure dans
votre paquet, vous voulez donc utiliser debconf pour interroger
l'utilisateur et ecrire un fichier de configuration base sur ses
reponses. Cela semble assez facile a faire, mais lorsque vous
considerez les mises a niveau, que faire lorsque quelqu'un modifie le
fichier de configuration que vous generez, et dpkg-reconfigure, et...
Il y a beaucoup de manieres de le faire, la plupart d'entre-elles ne
sont pas correctes et vous serez souvent ennuye par des rapports de
bogue. Voici une maniere correcte de le faire. Cela suppose que votre
fichier config n'est compose que d'une serie de variables de shell
positionnees, avec des commentaires entre elles, vous pouvez simplement
inclure le fichier pour le << charger >>. Si vous avez un format plus
complique, sa lecture (et son ecriture) devient un peu plus delicate.
Votre script config ressemblera a quelque chose comme ca :
#!/bin/sh
CONFIGFILE=/etc/foo.conf
set -e
. /usr/share/debconf/confmodule
# charge le fichier de configuration, s'il existe.
if [ -e $CONFIGFILE ]; then
. $CONFIGFILE || true
# Enregistrer les valeurs du fichier de configuration
# dans la base de donnees de debconf
db_set mypackage/toto "$FOO"
db_set mypackage/titi "$BAR"
fi
# Poser les questions.
db_input medium mypackage/toto || true
db_input medium mypackage/titi || true
db_go || true
Et le script postinst ressemblera a quelque chose comme ceci :
#!/bin/sh
CONFIGFILE=/etc/foo.conf
set -e
. /usr/share/debconf/confmodule
# Generer un fichier de configuration, s'il n'en existe pas.
# Une alternative est d'effectuer une copie dans un fichier
# modele depuis un autre endroit.
if [ ! -e $CONFIGFILE ]; then
echo "# Fichier de configuration pour mon paquet" > $CONFIGFILE
echo "TOTO=" >> $CONFIGFILE
echo "TITI=" >> $CONFIGFILE
fi
# Substituer les valeurs par celles de la base
# de donnees de debconf. Des optimisations
# evidentes sont possibles ici. Le cp avant
# le sed permet de s'assurer que l'on ne detruit
# pas le systeme des droits du fichier config.
db_get mypackage/foo
TOTO="$RET"
db_get mypackage/bar
TITI="$RET"
cp -a -f $CONFIGFILE $CONFIGFILE.tmp
# Si l'administrateur a supprime ou commente des variables mais
# les a ensuite definies via debconf, ajouter (a nouveau) au
# fichier de configuration (conffile).
test -z "$TOTO" || grep -Eq '^ *TOTO=' $CONFIGFILE || \
echo "TOTO=" >> $CONFIGFILE
test -z "$TITI" || grep -Eq '^ *TITI=' $CONFIGFILE || \
echo "TITI=" >> $CONFIGFILE
sed -e "s/^ *TOTO=.*/TOTO=\"$TOTO\"/" \
-e "s/^ *TITI=.*/TITI=\"$TITI\"/" \
< $CONFIGFILE > $CONFIGFILE.tmp
mv -f $CONFIGFILE.tmp $CONFIGFILE
Examinez comment ces deux scripts gerent tous les cas. Sur une nouvelle
installation, les questions sont posees par le script config et un
nouveau fichier de configuration est genere par le script postinst.
Pendant les mises a niveau et les reconfigurations, le fichier config
est lu, et ses valeurs sont utilisees pour modifier les valeurs dans la
base de donnees de debconf : les modifications manuelles de
l'administrateur ne sont donc pas perdues. Les questions sont posees a
nouveau (et peuvent etre affichees ou non). Puis le script postinst
remplace les valeurs dans le fichier config, en laissant le reste du
fichier inchange.
Permettre `a l'utilisateur de revenir en arri`ere
Peu de choses sont plus frustrantes, quand vous utilisez un systeme
comme debconf, que de repondre a une question posee, puis de passer a
un autre ecran avec une nouvelle question, de realiser alors que vous
avez fait une erreur dans la derniere question et que vous voulez y
retourner mais vous decouvrez que vous ne le pouvez pas.
Puisque debconf est conduit par votre script config, il ne peut revenir
seul a une question precedente, mais avec un petit coup de pouce de
votre part, il peut le faire. La premiere etape est que votre script
config fasse savoir a debconf qu'il est capable de gerer le fait que
l'utilisateur presse un bouton de retour en arriere. Vous utiliserez la
commande CAPB pour le faire en passant backup en parametre.
Puis, apres chaque commande GO, vous devez essayer de voir si
l'utilisateur a demande a revenir en arriere (debconf renvoie un code
de retour 30) et si c'est le cas, revenir a la question precedente.
Il existe plusieurs manieres d'ecrire des structures de controle pour
que votre programme puisse revenir aux questions anterieures lorsque
c'est necessaire. Vous pouvez ecrire du code spaghetti plein de goto.
Ou vous pouvez creer plusieurs fonctions et les utiliser de maniere
recursive. Mais peut-etre que la facon la plus correcte et la plus
simple est de construire une machine a etats. Voici le squelette d'une
machine a etats que vous pouvez remplir et ameliorer.
#!/bin/sh
set -e
. /usr/share/debconf/confmodule
db_capb backup
STATE=1
while true; do
case "$STATE" in
1)
# Deux questions sans rapport.
db_input medium ma/question || true
db_input medium mon/autre_question || true
;;
2)
# Ne poser cette question que si la
# reponse a la premiere question etait oui.
db_get ma/question
if [ "$RET" = "true" ]; then
db_input medium ma/question_dependante || true
fi
;;
*)
# Le cas par defaut est atteint quand $STATE est plus
# grand que le dernier etat implemente, et provoque la
# sortie de la boucle. Ceci requiert que les etat soient
# numerotes a partir de 1, successivement, et sans trou,
# puisque l'on entrera dans le cas par defaut s'il y a un
# trou dans la numerotation
break # quitte la boucle "while"
;;
esac
if db_go; then
STATE=$(($STATE + 1))
else
STATE=$(($STATE - 1))
fi
done
if [ $STATE -eq 0 ]; then
# L'utilisateur a demande a revenir a la premiere
# question. Ce cas est problematique. L'installation
# normale des paquets avec dpkg et apt n'est pas
# capable de revenir en arriere vers les questions
# d'autres paquets, a l'heure ou ceci est ecrit, donc
# cela va provoquer la sortie, laissant les paquets non
# configures - ce qui est probablement la meilleure
# facon de gerer la situation.
exit 10
fi
Notez que si tout ce que fait votre script config est de poser quelques
questions sans rapport les unes avec les autres, il n'y a pas besoin
d'une machine a etats. Posez simplement toutes les questions et GO ;
debconf fera de son mieux pour les presenter toutes sur un ecran et
l'utilisateur n'aura pas besoin de revenir en arriere.
'Eviter les boucles infinies
Une chose tres agacante peut arriver avec debconf si vous avez une
boucle dans votre script. Supposez que vous demandiez une entree et que
vous la validiez, ou que vous effectuiez une boucle si elle n'est pas
valable :
ok=''
do while [ ! "$ok" ];
db_input low toto/titi || true
db_go || true
db_get toto/titi
if [ "$RET" ]; then
ok=1
fi
done
Cela parait correct au premier coup d'oeil. Mais pensez a ce qui va
arriver si la valeur de toto/titi est "" lorsque l'on entre dans cette
boucle et que l'utilisateur a fixe la priorite a high, ou s'il utilise
une interface non interactive et qu'on ne lui demande donc aucune
entree. La valeur de toto/titi n'est pas changee par db_input et donc
le test echoue et boucle. Et boucle...
Une solution a ce probleme est de s'assurer qu'avant l'entree dans la
boucle, la valeur de toto/titi est positionnee a quelque chose qui
permettra de passer le test de la boucle. Donc par exemple si la valeur
par defaut de toto/titi est << 1 >>, vous pourrez passer la commande
RESET toto/titi juste avant d'entrer dans la boucle.
Une autre solution serait de verifier la valeur du code de retour de la
commande INPUT. Si c'est 30, l'utilisateur ne verra alors pas la
question qui lui est posee et vous devriez sortir de la boucle.
Choisir parmi plusieurs paquets li'es
Parfois, un ensemble de paquets lies peuvent etre installes et vous
voulez demander a l'utilisateur lequel doit etre utilise par defaut.
Les dictionnaires, ispell ou les gestionnaires de fenetres sont des
exemples de tels jeux de paquets.
Bien qu'il pourrait etre possible de simplement demander << Ce paquet
doit-il etre celui par defaut ? >> pour chaque paquet de l'ensemble,
cela aboutit a un grand nombre de questions repetitives si plusieurs de
ces paquets sont installes. Avec debconf, il est possible d'afficher
une liste de tous les paquets de l'ensemble et d'autoriser
l'utilisateur a choisir l'un d'entre eux. Et voici comment.
Utilisez un message partage par tous les paquets de cet ensemble.
Quelque chose comme ceci :
Template: shared/window-manager
Type: select
Choices: ${choices}
Description: Choisissez une gestionnaire de fenetres par defaut
Veuillez choisir le gestionnaire de fenetres qui sera demarre par
defaut
lors du lancement de X.
Description: Select the default window manager.
Select the window manager that will be started by
default when X starts.
Chaque paquet devrait inclure une copie de ce message. Puis il devrait
inclure du code comme ceci dans son script config :
db_metaget shared/window-manager owners
OWNERS=$RET
db_metaget shared/window-manager choices
CHOICES=$RET
if [ "$OWNERS" != "$CHOICES" ]; then
db_subst shared/window-manager choices $OWNERS
db_fset shared/window-manager seen false
fi
db_input medium shared/window-manager || true
db_go || true
Une petite explication est necessaire. Pour l'instant votre script est
lance, debconf a deja lu tous les questionnaires des paquets qui vont
etre installes. Puisque tous ces paquets ont une question en commun,
debconf enregistre ce fait dans le champ owners. Par une etrange
coincidence, le format du champ owners est le meme que celui du champ
choices (une liste de valeurs separees par virgule et espace).
La commande METAGET peut etre utilisee pour recuperer la liste des
proprietaires (<< owners >>) et la liste des choix. S'ils sont
differents, un nouveau paquet est alors installe. Utilisez alors la
commande SUBST pour modifier la liste des choix afin qu'elle soit
identique a celle des proprietaires et posez la question.
Lorsqu'un paquet est supprime, vous voudrez probablement voir si ce
paquet est le choix actuellement selectionne et s'il l'est, demander a
l'utilisateur de selectionner un autre paquet pour le remplacer.
Cela peut etre accompli en ajoutant quelque chose comme ceci dans le
script prerm de tous les paquets lies (en remplacant <paquet> par le
nom du paquet) :
if [ -e /usr/share/debconf/confmodule ]; then
. /usr/share/debconf/confmodule
# Je ne veux plus de cette question.
db_unregister shared/window-manager
# Regarde si la question partagee existe toujours.
if db_get shared/window-manager; then
db_metaget shared/window-manager owners
db_subst shared/window-manager choices $RET
db_metaget shared/window-manager value
if [ "<paquet>" = "$RET" ] ; then
db_fset shared/window-manage seen false
db_input high shared/window-manager || true
db_go || true
fi
# Maintenant faites ce que le script postinst faisait
# pour mettre a jour le lien symbolique du gestionnaire de
# fenetre.
fi
fi
BIDOUILLES
Debconf n'est pas encore entierement integre a dpkg (mais je veux
changer ca), cela demande donc actuellement quelques bidouilles peu
propres.
Le pire de ces bidouillages est le lancement du script config. Le
fonctionnement actuel est de lancer le script config lorsque le paquet
est pre-configure. Puis, lorsque le script postinst s'execute, il lance
debconf. Debconf remarque qu'il va etre utilise par le script postinst,
il s'arrete et lance le script config. Cela ne fonctionne que si votre
script postinst charge l'une des bibliotheques debconf, les scripts
postinst doivent toujours prendre soin de les charger. Nous esperons
nous attaquer a cela plus tard en ajoutant un support explicite de
debconf dans dpkg. Le programme debconf(1) est une etape dans ce sens.
Une bidouille similaire est de lancer debconf lorsqu'un script config,
postinst, ou d'autres programmes qui l'utilisent commence. Apres tout,
ils esperent avoir la possibilite de communiquer avec debconf d'une
facon correcte. Pour l'instant, la maniere dont cela est accompli est
que lorsqu'un tel script charge une bibliotheque debconf (comme
/usr/share/debconf/confmodule) et que debconf n'est pas deja lance, il
est demarre et une nouvelle copie du script est re-executee. Le seul
resultat perceptible est que vous avez besoin de mettre la ligne qui
charge une bibliotheque debconf au tout debut du script, ou des choses
etranges arriveront. Nous esperons examiner ca plus tard en changeant
l'invocation de debconf et le changer en un demon provisoire.
La facon dont debconf trouve quels fichiers templates charger et quand
les charger ressemble vraiment a une bidouille. Lorsque les scripts
config, preinst et postinst invoquent debconf, il trouvera
automatiquement l'emplacement du fichier templates et le chargera. Les
programmes independants qui utilisent debconf forceront debconf a
rechercher les fichiers templates dans
/usr/share/debconf/templates/nomduprog.templates. Et si un le script
postrm veut utiliser debconf au moment de la purge, les questionnaires
ne seront pas disponibles a moins que debconf ait une opportunite de
les charger dans son script postinst. Cela n'est pas tres propre mais
presque inevitable. Dans le futur, certains de ces programmes
pourraient malgre tout avoir la possibilite d'utiliser
debconf-loadtemplate a la main.
Le comportement historique de /usr/share/debconf/confmodule de jouer
avec les descripteurs de fichier et de configurer un descripteur de
fichier special (<< fd #3 >>) qui communique avec debconf, peut causer
toutes sortes de trouble lorsqu'un demon est lance par un script
postinst, puisque le demon cesse de communiquer avec debconf et que
debconf ne peut pas savoir quand le script se termine. La commande STOP
peut etre utilisee pour ceci. Nous envisagerons plus tard de faire
passer la communication avec debconf a travers une socket ou un autre
mecanisme que les entrees et sorties standard.
Debconf positionne DEBCONF_RECONFIGURE=1 avant de lancer les scripts
postinst, donc un script postinst voulant eviter des operations
couteuses lorsqu'il est reconfigure peut regarder cette variable. C'est
une bidouille car la meilleure chose a faire serait de lui passer $1 =
"reconfigure", mais le faire sans casser tous les scripts postinsts qui
utilisent debconf est difficile. Le projet de migration pour cette
bidouille est d'encourager les gens a ecrire des scripts postinst qui
acceptent "reconfigure" et, une fois qu'ils le feront tous, commencer a
passer cette variable.
VOIR AUSSI
debconf(7) est le guide de l'utilisateur de debconf.
La specification debconf dans la charte Debian est une definition
canonique du protocole debconf.
/usr/share/doc/debian-policy/debconf_specification.txt.gz
debconf.conf(5) contient beaucoup d'informations, y compris des
informations sur les pilotes de la base de donnees.
AUTEUR
Joey Hess <joeyh@debian.org>
TRADUCTION
Julien Louis <ptitlouis@sysif.net>, 2005
Cyril Brulebois <kibi@debian.org>, 2006
Veuillez signaler toute erreur de traduction en ecrivant a
<debian-l10n-french@lists.debian.org> ou par un rapport de bogue sur le
paquet debconf.
DEBCONF-DEVEL(7)