Provided by:
debconf-doc_1.5.42ubuntu1_all 
NOMBRE
debconf - Guia del desarrollador
DESCRIPCI'ON
Esta es una guia para el desarrollo de paquetes que usan debconf.
Este manual asume que esta familiarizado con debconf como usuario, y
que conoce los conceptos basicos de la construccion de paquetes debian.
Este manual comienza explicando dos nuevos ficheros que se anaden a
paquetes debian que usan debconf. A continuacion, explica como funciona
el protocolo de debconf, y senala las bibliotecas que permitiran que
sus programas hablen tal protocolo. Se discuten otros scripts de
desarrollador que habitualmente usan debconf: los scripts postinst
(postinstalacion) y postrm (posteliminacion). Continua con temas mas
avanzados como el sistema de plantillas compartidas de debconf,
depuracion de fallos, y algunas tecnicas comunes y problemas a la hora
de programar con debconf. Finaliza con un analisis de las deficiencias
actuales de debconf.
EL SCRIPT CONFIG
Debconf anade un script de desarrollador adicional, el script
<<config>>, al conjunto de scripts de desarrollador que pueden existir
en paquetes debian (<<postinst>>, <<preinst>>, <<postrm>>, y
<<prerm>>). El script <<config>> es el responsable de plantear
cualquier pregunta necesaria para la configuracion del paquete.
Nota: Es un poco confuso que dpkg se refiere a ejecutar el script
<<postinst>> como la <<configuracion>> del paquete, ya que,
habitualmente, un paquete que usa debconf esta totalmente
preconfigurado mediante el script <<config>> antes de que se ejecute el
script de postinstalacion. Pero bueno.
Al igual que el script <<postinst>>, el script <<config>> acepta dos
parametros cuando se ejecuta. El primero dice la accion que se esta
realizando, y el segundo la version del paquete actualmente instalado.
Por lo tanto, al igual que con un script <<postinst>>, puede usar
<<dpkg --compare-versions>> con <<$2>> para hacer que un comportamiento
solo aparezca durante la actualizacion a partir de una version en
particular, y otros comportamientos parecidos.
El script <<config>> se puede ejecutar de tres formas distintas:
1 Si el paquete esta preconfigurado con <<dpkg-preconfigure>>, se
ejecuta el script <<config>> y se le introducen los parametros
<<configure>> y la version instalada (<<installed-version>>).
2 Cuando se ejecuta el script <<postinst>> de un paquete debconf
intentara ejecutar tambien el script <<config>>, al que se le
introduciran los mismos parametros que se introducen cuando se
preconfigura. Es necesario ya que puede que el paquete aun no se
haya preconfigurado, y que el script <<config>> todavia necesite
una oportunidad para ejecutarse. Para mas detalles consulte
<<ARREGLOS>>.
3 Si el paquete se reconfigura con <<dpkg-reconfigure>>, se
ejecuta el script <<config>>, y se le introducen los parametros
<<reconfigure>> y la version instalada (<<installed-version>>).
Tenga en cuenta que ya que una instalacion o actualizacion tipica de
paquetes mediante apt ejecuta los pasos 1 y 2, el script <<config>> se
ejecutara dos veces. No deberia hacer nada (plantear las mismas
preguntas dos veces seguidas es molesto), y deberia ser idempotente.
Afortunadamente, debconf evita repetir preguntas por omision, asi que
esto es generalmente facil de realizar.
Observe que el script <<config>> se ejecuta antes de desempaquetar el
paquete. Solo deberia usar ordenes que estan en los paquetes esenciales
(<<essential>>). La unica dependencia que su paquete tendra de forma
obligatoria al ejecutar el script <<config>> es el mismo debconf
(posiblemente versionada).
El script <<config>> no deberia necesitar modificar el sistema de
ficheros de ninguna forma. Simplemente, examina el estado del sistema y
plantea preguntas, y debconf guarda las respuestas para usarlas despues
a traves del script <<postinst>>. Por el contrario, el script
<<postinst>> nunca deberia usar debconf para plantear preguntas, sino
que deberia actuar en base a las respuestas a las preguntas planteadas
por el script <<config>>.
EL FICHERO DE PLANTILLAS
Probablemente, un paquete que usa debconf desea plantear algunas
preguntas. Estas preguntas se guardan, en de plantilla, en el fichero
de plantillas.
Al igual que el script <<config>>, el fichero de plantillas se ubica en
la seccion <<control.tar.gz>> de un paquete <<.deb>>. Su formato es
similar al fichero de control de debian, un conjunto de definiciones
separadas por lineas en blanco. Cada definicion tiene una forma similar
al formato RFC822:
Template: foo/bar
Type: string
Default: foo
Description: Este es un ejemplo de pregunta de tipo cadena.
Esta es su descripcion extendida.
.
Tenga en cuenta:
- Al igual que en la descripcion de un paquete debian,
un punto en una linea vacia inicia un nuevo parrafo.
- La mayoria del texto se justifica, pero el texto con
doble sangrado no se modifica, asi que puede usarlo
para listas de elementos como esta lista. Tenga
cuidado ya que no se justifica, y tendra un pobre
aspecto si es demasiado ancho. Es mejor usarlo con
elementos cortos (y por ello este es un mal ejemplo).
Template: foo/baz
Type: boolean
Description: Es obvio, cno?
Esta es otra pregunta, de tipo booleano.
Si desea ver ejemplos de uso reales de ficheros de plantillas consulte
<</var/lib/dpkg/info/debconf.templates>> y otros ficheros
<<.templates>> en ese directorio.
Ahora vamos a explicar cada uno de los campos.
Template
El nombre de la plantilla, en el campo <<Template>>, tiene
habitualmente como prefijo el nombre del paquete. A continuacion
de esto, el espacio de nombres esta abierto; puede usar un
sencillo diseno plano como el que aparece antes, o definir
<<subdirectorios>>, que contienen las preguntas relacionadas.
Type El tipo de plantilla determina el tipo de elemento que se
muestra al usuario. Los tipos aceptados actualmente son:
string Resulta en un campo de entrada con formato libre en el
que el usuario puede introducir cualquier cadena.
password
Solicita una contrasena al usuario. Uselo con precaucion;
tenga en cuenta que la contrasena que el usuario
introduzca se escribira en la base de datos de debconf.
Probablemente, deberia eliminar ese valor de la base de
datos tan pronto como sea posible.
boolean
Una eleccion <<true/false>> (verdadero/falso).
select Una eleccion de un valor entre un numero de valores. Las
posibles elecciones se deben definir en un campo llamado
<<Choices>>. Separe los valores posibles con comas y
espacios, como se ve a continuacion.
Choices: yes, no, maybe
multiselect
Similar al tipo datos <<select>>, a excepcion de que el
usuario puede seleccionar cualquier numero de elementos
de la lista de elecciones (o no seleccionar ninguno).
note Mas que una pregunta, este tipo de dato indica una nota
que se puede mostrar al usuario. Solo se deberia usar
para notas importantes que el usuario realmente deberia
ver, ya que debconf sufrira complicaciones para
asegurarse de que el usuario lo ve; interrumpira la
instalacion para que puedan pulsar una tecla. Es mejor
usar este aviso solo para problemas serios, y a menudo es
mas adecuado usar el tipo de dato <<error>> .
error Este tipo de dato se usa para mensajes de error, tales
como los errores de validacion de entradas. Debconf
mostrara una pregunta de este tipo incluso si la
prioridad es demasiado alta o si el usuario ya la ha
visto.
title Este tipo de datos se usa para titulos, que se definiran
con la orden <<SETTITLE>>.
text Este tipo de datos se puede usar para fragmentos de texto
tales como etiquetas, que se pueden usar por razones
esteticas en las ventanas de algunas interfaces. Otras
interfaces no haran uso de el. Aun no existe ninguna
razon para usar este tipo de dato ya que ninguna interfaz
lo permite de forma adecuada. Incluso puede que se
elimine en el futuro.
Default
El campo <<Default>> dice a debconf cual deberia ser el valor
predefinido. Con <<multiselect>>, puede ser una lista de
elecciones separadas por comas y espacios, de forma similar al
campo <<Choices>>. Con <<select>>, deberia ser una de las
elecciones. Con <<boolean>>, es <<true>> o <<false>>. Puede ser
cualquier cosa con <<string>>, y se ignora con <<passwords>>.
No cometa el error de pensar que el campo <<Default>> contiene
el valor de la pregunta, o que se puede usar para cambiar el
valor de la pregunta. No puede hacer esto, y no deberia.
Simplemente ofrece el valor predefinido para la primera vez que
se muestra la pregunta. Para proporcionar un valor predefinido
que se pueda modificar en el momento, tendra que usar la orden
<<SET>> para cambiar el valor de una pregunta.
Description
El campo <<Description>> tiene dos partes, al igual que la
descripcion de un paquete de Debian: una descripcion corta y una
descripcion extendida. Tenga en cuenta que algunas interfaces de
debconf no muestran la descripcion extendida, o puede que solo
la muestren si el usuario solicita ayuda. Por ello, la
descripcion corta deberia ser suficientemente completa.
Si no puede inventarse una descripcion larga, primero, piense un
poco mas. Mande un correo a debian-devel. Pida ayuda. iTome
clases de composicion de texto! La descripcion extendida es
importante. Si despues de todo esto aun no se le ha ocurrido
nada, deje el espacio en blanco. No tiene sentido duplicar la
descripcion corta.
El texto de la descripcion extendida se justificara, a menos que
este precedido por un espacio blanco adicional (ademas del
espacio requerido). Puede dividirlo en varios parrafos
insertando <<.>> en una linea vacia entre los parrafos.
PREGUNTAS
Una pregunta es una instancia de plantilla. Al pedir a debconf que
muestre una pregunta, su script <<config>> puede interactuar con el
usuario. Cuando debconf carga un fichero de plantillas (esto ocurre
cada vez que se ejecuta un script <<config>> o <<postinst>>)
automaticamente crea una instancia para cada pregunta de cada
plantilla. Es posible crear instancias de varias preguntas
independientes a partir de la misma plantilla (usando la orden
<<REGISTER>>), pero rara vez es necesario. Las plantillas son datos
estaticos que proceden del fichero de plantillas, mientras que las
preguntas se usan para almacenar datos dinamicos, tales como el valor
actual de la pregunta, si el usuario ha visto la pregunta, y asi en
adelante. Tenga en cuenta la diferencia entre una plantilla y una
pregunta, pero no se preocupe demasiado por ello.
PLANTILLAS COMPARTIDAS
Es posible tener una plantilla y una pregunta compartidas por un
conjunto de paquetes. Todos los paquetes deben proporcionar una copia
identica de la plantilla en sus ficheros de plantillas. Puede ser util
si un conjunto de paquetes necesitan plantear la misma pregunta, y solo
desea consultar al usuario una sola vez. Habitualmente, las plantillas
compartidas se ubican en el seudo directorio <<shared/>> en el espacio
de nombres (<<namespace>>) de la plantilla de debconf.
EL PROTOCOLO DE DEBCONF
Los scripts <<config>> se comunican con debconf usando el protocolo de
debconf. Este es un sencillo protocolo orientado a la linea de ordenes,
similar a protocolos comunes de Internet tales como SMTP. El script
<<config>> envia una orden a debconf enviando la orden por la salida
estandar. A continuacion, puede leer la respuesta de debconf por la
entrada estandar.
La respuesta de debconf se puede dividir en dos partes. Un codigo de
salida numerico (la primera palabra de la respuesta), y opcionalmente
un codigo de salida extendido (el resto de la respuesta). El codigo
numerico usa cero para indicar exito, y otros numeros para indicar
varios tipos de fallo. Para mas detalles, consulte la tabla en el
documento de especificaciones de debconf en las normas de Debian
(debian-policy).
El codigo de salida extendido tiene, habitualmente, una forma libre y
sin especificar, asi que generalmente deberia ignorarlo, y
definitivamente no deberia intentar analizarlo con un programa para
averiguar lo que debconf esta haciendo. La excepcion son ordenes como
<<GET>>, que hacen que un valor se devuelva en el codigo de salida
extendido.
Habitualmente, querra usar una biblioteca de lenguaje especifico que
gestiona los particularidades de creacion de estas conexiones con
debconf y la comunicacion con este.
Por ahora, aqui tiene las ordenes en el protocolo. Esta no es la
definicion completa; para ello, consulte el documento de
especificaciones de debconf en las normas de Debian (debian-policy).
VERSION n'umero
Generalmente no tendra que usar esta orden. Intercambia con
debconf el numero de version del protocolo que se esta usando.
La version del protocolo actual es 2.0, y las versiones de la
serie 2.x tendran compatibilidad hacia atras. Puede definir el
numero de version del protocolo que esta usando y debconf
devolvera la version del protocolo que esta usando en el codigo
de salida extendido. Si la version que define es demasiado baja,
debconf respondera con el codigo numerico 30.
CAPB funcionalidades
Generalmente no tendra que usar esta orden. Intercambia con
debconf una lista de funcionalidades aceptadas. Se usaran la
funcionalidades que el script y debconf aceptan, y debconf
respondera con todas las funcionalidades que permite.
Si <<escape>> esta entre sus funcionalidades, debconf esperara
que las ordenes que envie tengan escapes de barras inversas y
nuevas lineas (como <<\\>> y <<\n>> respectivamente), y
respondera con barras inversas y nuevas lineas escapadas. Esto
se puede usar, por ejemplo, para sustituir cadenas de varias
lineas en plantillas, o para obtener descripciones extendidas de
varias lineas adecuadamente usando METAGET. Si usa este modo,
tendra que escapar el texto de entrada (o puede usar
debconf-escape(1) para que le asista en esta labor si asi lo
desea), pero las bibliotecas confmodule devolveran respuestas
sin escapes.
SETTITLE pregunta
Esto define el titulo que debconf muestra al usuario, usando la
descripcion corta de la plantilla para la pregunta especificada.
La plantilla deberia de ser de tipo <<title>>. Rara vez
necesitara usar esta orden ya que debconf puede generar
automaticamente un titulo a partir del nombre del paquete.
Configurar el titulo a partir de la plantilla significa que se
guardan en la misma ubicacion que el resto de las preguntas de
debconf, permitiendo su traduccion.
TITLE cadena
Esto define el titulo que debconf muestra al usuario con la
cadena especificada. Habitualmente, se prefiere el uso de la
orden <<SETTITLE>> ya que permite la traduccion del titulo.
INPUT prioridad pregunta
Hace que debconf se prepare para mostrar una pregunta al
usuario. La pregunta no se muestra realmente hasta que no se
emita una orden <<GO>>; esto permite introducir en serie varias
ordenes <<INPUT>> para construir una serie de preguntas que se
podrian plantear en una sola pantalla.
El campo de prioridad indica a debconf la importancia de la
pregunta mostrada al usuario. Los valores de prioridad son:
low Elementos muy triviales que tienen valores predefinidos
que funcionaran en la inmensa mayoria de los casos. Solo
los obsesos del control deberian verlos.
medium Elementos normales con valores predefinidos razonables.
high Elementos que no tienen un valor predefinido razonable.
critical
Elementos que posiblemente rompan el sistema sin la
intervencion del usuario.
Debconf decide si se muestra la pregunta en base a la prioridad,
si el usuario la ha visto ya, y la interfaz que se esta usando.
Si la pregunta no se va a mostrar, debconf responde con el
codigo numerico 30.
GO
Indica a debconf que muestre al usuario el conjunto acumulado de
preguntas (de ordenes <<INPUT>>).
Si se admite la funcionalidad de copia de seguridad y el usuario
indica que desea retroceder, debconf responde con el codigo
numerico 30.
CLEAR Elimina el conjunto acumulado de preguntas (de ordenes
<<INPUT>>) sin mostrarlas.
BEGINBLOCK
ENDBLOCK
Algunas interfaces de debconf pueden mostrar varias preguntas a
la vez al usuario. Puede que en el futuro, una interfaz sea
tambien capaz de agrupar en bloque estas preguntas en la
pantalla. <<BEGINBLOCK>> y <<ENDBLOCK>> se pueden ubicar en
torno a un conjunto de ordenes <<INPUT>> para indicar bloques de
preguntas (y los bloques se pueden anidar tambien). Ya que
ninguna interfaz de debconf es aun tan sofisticada, estas
ordenes se ignoraran por ahora.
STOP Esta orden indica a debconf que ya ha terminado de comunicarse
con el. Habitualmente debconf puede detectar la finalizacion de
su programa, con lo cual esta orden no seria necesaria.
GET pregunta
Despues de usar <<INPUT>> y <<GO>> para mostrar una pregunta,
puede usar esta orden para obtener el valor que introdujo el
usuario. El valor se devuelve en el codigo de salida extendido.
SET pregunta valor
Define el valor de la pregunta, y se puede usar para reemplazar
el valor predefinido con un calculo que su programa haga durante
el proceso.
RESET pregunta
Restablece la pregunta a su valor predefinido (tal y como esta
definido en el campo <<Default>> de su plantilla).
SUBST pregunta clave valor
Las preguntas pueden integrar sustituciones en sus campos
<<Description>> y <<Choices>> (el uso de sustituciones en campos
<<Choices>> no esta demasiado bien hecho; con el tiempo se
desarrollara un mecanismo mejor). Estas sustituciones tiene la
apariencia <<${key}>>. Cuando se muestra la pregunta, las
sustituciones se reemplazan con sus valores. Esta orden se puede
usar para definir el valor de una sustitucion. Es util si
necesita mostrar algunos mensajes al usuario, las cuales no
desea integrar en el codigo (<<hardcode>>) en el fichero de
plantillas.
No intente usar <<SUBST>> para cambiar el valor predefinido de
una pregunta; no funcionara ya que existe una orden <<SET>> para
ese proposito.
FGET pregunta marca
Las preguntas pueden tener marcas asociadas a ellas. Las marcas
pueden tener un valor de <<true>> (verdadero) o <<false>>
(falso).
FSET pregunta marca valor
Esto define el valor de la marca de una pregunta. El valor debe
ser <<true>> o <<false>>.
Una marca comun es la marca <<seen>>. Habitualmente, solo se
define si el usuario ya ha viso la pregunta. Generalmente,
debconf solo muestra preguntas a los usuarios si la marca
<<seen>> esta definida con <<false>> (o si esta reconfigurando
el paquete). A veces desea que el usuario vea la pregunta otra
vez; en estos casos puede definir la marca <<seen>> con el valor
<<false>> para forzar a debconf a que la muestre otra vez.
METAGET pregunta campo
Devuelve el valor de cualquier campo de una plantilla asociada a
la pregunta (<<Description>>, por ejemplo).
REGISTER plantilla pregunta
Crea una nueva pregunta ligada a una plantilla. Por omision,
cada plantilla tiene una pregunta asociada con el mismo nombre.
Sin embargo, se pueden asociar cualquier numero de preguntas a
una plantilla, permitiendo la creacion de mas preguntas.
UNREGISTER pregunta
Elimina una pregunta de la base de datos.
PURGE Invoque esto en el script <<postrm>> al purgar el paquete.
Elimina todas las preguntas de su paquete de la base de datos de
debconf.
X_LOADTEMPLATEFILE /ruta/a/plantillas [propietario]
Esta extension carga el fichero de plantilla especificado, en la
base de datos de debconf. El propietario recibe el valor
predefinido del paquete que se esta configurando con debconf.
Aqui tiene un sencillo ejemplo del protocolo de debconf en accion.
INPUT medium debconf/frontend
30 question skipped
FSET debconf/frontend seen false
0 false
INPUT high debconf/frontend
0 question will be asked
GO
[ Aqui, debconf muestra al usuario una pregunta. ]
0 ok
GET no/such/question
10 no/such/question doesn't exist
GET debconf/frontend
0 Dialog
BIBLIOTECAS
Configurar manualmente lo necesario para poder hablar con debconf
mediante el protocolo de debconf es quiza demasiado trabajo, y por ello
existen algunas pequenas bibliotecas para aliviar este arduo trabajo.
Para la programacion en consola existe la biblioteca
<</usr/share/debconf/confmodule>>, el cual puede cargar al principio
del script de consola, y comunicarse con debconf con una relativa
naturalidad usando las versiones en minuscula de las ordenes del
protocolo de debconf, las cuales estan prefijadas con <<db_>> (por
ejemplo, <<db_input>> y <<db_go>>). Para mas detalles, consulte
confmodule(3).
Los programadores que usan Perl pueden usar el modulo de Perl
Debconf::Client::ConfModule(3pm), y los programadores que usan Python
pueden usar el modulo de Python de debconf.
El resto de este manual usara la biblioteca
<</usr/share/debconf/confmodule>> en los scripts de consola de ejemplo.
Aqui tiene un script <<config>> de ejemplo que usa esa biblioteca, y
que solo plantea una pregunta:
#!/bin/sh
set -e
. /usr/share/debconf/confmodule
db_set mi-paquete/reboot-now false
db_input high mi-paquete/reboot-now || true
db_go || true
Tenga en cuenta que el uso de <<|| true>> evita que el script finalice
si debconf decide que no puede mostrar la pregunta, o si el usuario
intenta retroceder. En estas situaciones debconf devuelve un codigo de
salida distinto de cero, y debido a que este script usa <<set -e>>, un
codigo de salida sin variable de error (<<untrapped>>) haria que se
cancelase.
Y aqui tiene un script <<postinst>> correspondiente, que usa la
respuesta del usuario a la pregunta para ver si se deberia reiniciar el
sistema (un ejemplo algo absurdo...):
#!/bin/sh
set -e
. /usr/share/debconf/confmodule
db_get mi-paquete/reboot-now
if [ "$RET" = true ]; then
shutdown -r now
fi
Tenga en cuenta el uso de la variable <<$RET>> para obtener un codigo
de salida extendido de la orden <<GET>>, que contiene la respuesta del
usuario a la pregunta.
EL SCRIPT POSTINST
La ultima seccion tenia un ejemplo de un script <<postinst>> que usa
debconf para obtener el valor de una pregunta, y actuar en
consecuencia. Existen algunas cosas que debe tener en cuenta al
escribir scripts <<postinst>> que usan debconf:
* Evite hacer preguntas en el <<postinst>>. Por el contrario, el
script <<config>> deberia hacer preguntas mediante debconf, para
que funcione la preconfiguracion.
* Cargue siempre <</usr/share/debconf/confmodule>> al inicio de su
<<postinst>>, incluso si no va a ejecutar ninguna orden <<db_*>>
desde el script. Es necesario para asegurar que el script
<<config>> tenga la oportunidad de ejecutarse (para mas detalles
consulte <<ARREGLOS>>).
* Evite enviar cualquier informacion del <<postinst>> a traves de
la salida estandar ya que puede confundir a debconf, y de todas
formas, <<postinst>> no deberia ser informativo. Enviar
informacion a la salida de error es aceptable, de ser necesario.
* Si su <<postinst>> inicia un demonio asegurese de informar a
debconf de que ejecute <<STOP>> al final, ya que de otra forma
puede que debconf confunda el momento en que finaliza el script
<<postinst>>.
* Haga que el script <<postinst>> acepte <<reconfigure>> como
primer parametro. Puede tratarlo al igual que <<configure>>. Se
usara en futuras versiones de debconf para informar a los script
<<postinst>> de cuando se reconfiguran.
OTROS SCRIPTS
Aparte del script <<config>> y <<postinst>>, puede usar debconf en
cualquier otro script de encargado de paquetes. Habitualmente, usara
debconf en su <<postrm>> para invocar la orden <<PURGE>> cuando purga
su paquete y asi eliminar sus entradas de la base de datos debconf.
(Por cierto, esta configurado automaticamente mediante
dh_installdebconf(1).)
Un uso mas complejo de debconf seria si desea usarlo en el script
<<postrm>> al purgar el paquete para realizar una pregunta acerca de la
eliminacion de algo. O puede que se vea en la necesidad de usarlo en
los script <<preinst>> o <<prerm>>. Todos estos usos funcionaran,
aunque probablemente incluyan plantear preguntas y actuar segun la
respuesta en el mismo programa, en lugar de separar las dos actividades
como se hace con los scripts <<config>> y <<postint>>.
Tenga en cuenta que si el unico uso que su paquete hace de debconf esta
en el script <<postrm>>, deberia comprobar que el script <<postinst>>
del paquete carga <</usr/share/debconf/confmodule>> para dar a debconf
la oportunidad de cargar su fichero de plantillas en la base de datos.
Asi, las plantillas estaran disponibles al purgar su paquete.
Tambien puede usar debconf con otros programas independientes. La
cuestion que debe cuidar es que debconf no pretende ser, y no se
deberia usar, como un registro. Al fin y al cabo, esto es Unix, y los
programas se configuran mediante ficheros en <</etc>>, y no mediante
alguna difusa base de datos de debconf (que es solo un almacen
susceptible de desaparecer). Asi que reflexione antes de usar debconf
con un programa independiente.
Hay situaciones en las que tiene sentido, por ejemplo con el programa
apt-setup, que usa debconf para realizar preguntas al usuario de una
forma consistente con el resto del proceso de instalacion de Debian, y
asi actuar segun las respuestas para configurar el fichero
<<sources.list>> de apt.
LOCALIZACI'ON
Debconf permite la localizacion de ficheros de plantilla. Esto se
consigue anadiendo mas campos que contienen el texto traducido. Se
pueden traducir cualquiera de los campos. Por ejemplo, puede que desee
traducir la descripcion al espanol. Simplemente, cree un campo llamado
<<Description-es>> para contener la traduccion. Si no se dispone de la
traduccion de un campo, debconf usa el campo en ingles de forma
predefinida.
Ademas del campo <<Description>> tambien deberia traducir el campo
<<Choices>> de una plantilla <<select>> o <<multiselect>>. Asegurese de
listar las opciones traducidas en el mismo orden en el que aparecen en
el campo <<Choices>>. No necesita traducir el campo <<Default>> de una
pregunta <<select>> o <<multiselect>>, y el valor del campo aparecera
automaticamente en ingles.
Le resultara mas facil administrar las traducciones si las gestiona en
ficheros separados; un fichero por traduccion. En el pasado se usaban
los programas debconf-getlang(1) y debconf-mergetemplate(1) para
administrar los ficheros <<debian/template.ll>>. Han quedado obsoletos
por el paquete po-debconf(7), que permite administrar traducciones de
debconf en ficheros <<.po>>, al igual que cualquier otra traduccion.
Sus traductores le estaran agradecidos por usar este nuevo y mejorado
mecanismo.
Para mas detalles acerca de po-debconf, consulte su pagina de manual.
Si usa debhelper, pasar a po-debconf es tan facil como ejecutar la
orden debconf-gettextize(1) una sola vez, y anadir una dependencia de
construccion sobre po-debconf y debhelper (>= 4.1.13).
INTEGRAR LAS DIFERENTES PARTES
Asi que tiene un script <<config>>, un fichero de plantillas, un script
<<postinst>> que usa debconf y asi en adelante. Integrar todos estos
elementos en un paquete debian no es muy dificil. Puede hacerlo a mano,
o puede usar dh_installdebconf(1), el cual fusionara sus plantillas
traducidas, copiara los ficheros a las ubicaciones apropiadas, y puede
incluso crear la invocacion a <<PURGE>> que deberia estar en su script
<<postrm>>. Compruebe que el paquete dependa de debconf (>= 0.5) ya que
las versiones anteriores no son compatibles con todo lo descrito en
este manual. Y esto es todo.
Bueno, a excepcion de probar, la depuracion y en realidad usar debconf
para cosas mas interesantes que plantear unas pocas preguntas basicas.
Para ello, siga leyendo...
DEPURACI'ON
Asi que tiene un paquete que deberia usar debconf, pero que no llega a
funcionar. Puede que debconf no plantee la pregunta que configuro. O
puede que este ocurriendo algo mas raro; esta atrapado en un especie de
bucle, o peor. Afortunadamente, debconf ofrece muchas facilidades para
su depuracion.
DEBCONF_DEBUG
La primera cosa que tiene que hacer es configurar la variable de
entorno <<DEBCONF_DEBUG>>. Si ejecuta un <<set>> y <<export>> de
<<DEBCONF_DEBUG=developer>>, debconf enviara por la salida
estandar un volcado del protocolo de debconf a medida que el
programa se ejecuta. Es similar a esto, la errata es evidente
(--):
debconf (developer): <-- input high debconf/frontand
debconf (developer): --> 10 "debconf/frontand" doesn't exist
debconf (developer): <-- go
debconf (developer): --> 0 ok
Es bastante util usar la interfaz readline de debconf cuando
realice la depuracion (segun la opinion del autor), ya que las
preguntas no entorpecen la labor, y la salida de depuracion se
puede registrar y preservar con facilidad.
DEBCONF_C_VALUES
Si define esta variable de entorno como <<true>>, la interfaz
mostrara los valores en los campos <<Choices-C>> (de existir) de
plantillas <<select>> y <<multiselect>> en lugar de los valores
descriptivos.
debconf-communicate
Otra herramienta util es el programa debconf-communicate(1).
Inicielo y podra comunicarse con debconf mediante el protocolo
de debconf de forma interactiva. Es una buena forma de probar
cosas inmediatamente.
debconf-show
Si un usuario informa de un problema puede usar debconf-show(1)
para mostrar todas las preguntas del que su paquete es
propietario, mostrando sus valores y si el usuario las ha visto.
.debconfrc
Para evitar el ciclo, a menudo tedioso, de construir, instalar y
depurar, puede ser util cargar sus plantillas con
debconf-loadtemplate(1) y ejecutar su script <<config>>
directamente con la orden debconf(1). Sin embargo, tiene que
hacer esto como el usuario <<root>>, cno?. No es muy bueno. Y lo
ideal es que pueda ver el comportamiento de una instalacion
nueva de su paquete, con una base de datos de debconf limpia.
Resulta que si configura un fichero <<~/.debconfrc>> para un
usuario normal que apunta a unos ficheros <<config.dat>> y
<<template.dat>> para el usuario, puede cargar plantillas y
ejecutar scripts <<config>> cuanto desee sin permisos del
usuario <<root>>. Si desea iniciar todo con una base de datos
limpia, simplemente borre los ficheros <<*.dat>>.
Para detalles acerca de la configuracion, consulte
debconf.conf(5), y tenga en cuenta que <</etc/debconf.conf>> es
una buena plantilla para un fichero <<~/.debconfrc>> personal.
PROGRAMACI'ON AVANZADA CON DEBCONF
Manipulaci'on de ficheros de configuraci'on
Parece que muchos de vosotros quereis usar debconf para ayudar en la
manipulacion de los ficheros de configuracion que son parte de su
paquete. Puede que no exista un buen valor predefinido a incluir en un
fichero de configuracion, y por ello puede desear usar debconf para
plantear preguntas al usuario y escribir un fichero de configuracion en
base a las respuestas. Puede parecer facil, pero considere las
actualizaciones, y que hacer cuando alguien modifica el fichero de
configuracion que su paquete genera, cuando se usa dpkg-reconfigure, y
mas...
Existen varias formas de hacer esto, y la mayoria estan equivocadas,
generando a menudo molestos informes de fallo. Aqui tiene una de las
formas correctas de hacerlo. Asume que su fichero de configuracion es
realmente solo una serie de variables de entorno a definir (<<set>>),
con comentarios entre ellos, para que asi pueda solo leer el fichero
para cargarlo. Si tiene un formato mas complicado, leer y editar el
fichero es mas complicado.
Su script <<config>> puede tener un aspecto similar a este:
#!/bin/sh
CONFIGFILE=/etc/foo.conf
set -e
. /usr/share/debconf/confmodule
# Carga el fichero de configuracion, si existe.
if [ -e $CONFIGFILE ]; then
. $CONFIGFILE || true
# Guarda los valores del fichero de
# configuracion en la base de datos de debconf.
db_set mypackage/foo "$FOO"
db_set mypackage/bar "$BAR"
fi
# Plantea preguntas.
db_input medium mypackage/foo || true
db_input medium mypackage/bar || true
db_go || true
Y el script <<postinst>> tendra un aspecto similar al siguiente:
#!/bin/sh
CONFIGFILE=/etc/foo.conf
set -e
. /usr/share/debconf/confmodule
# Genera el fichero de configuracion, si no existe.
# Una alternativa es copiar un fichero
# de plantillas en otra ubicacion. i if [ ! -e $CONFIGFILE ]; then
echo "# Fichero de configuracion para mi paquete " > $CONFIGFILE
echo "FOO=" >> $CONFIGFILE
echo "BAR=" >> $CONFIGFILE
fi
# Sustituye los valores de la base de datos de debconf
# Aqui hay muchas optimizaciones posibles.
# <<cp>> antes de <<sed>> asegura que no nos equivocamos
# con el propietario y permisos del fichero de configuracion.
db_get mypackage/foo
FOO="$RET"
db_get mypackage/bar
BAR="$RET"
cp -a -f $CONFIGFILE $CONFIGFILE.tmp
# Si el administrador elimino algunas variables pero despues las
# define (<<set>>) mediante debconf, las (re)anade al fichero de
# configuracion.
test -z "$FOO" || grep -Eq '^ *FOO=' $CONFIGFILE || \
echo "FOO=" >> $CONFIGFILE
test -z "$BAR" || grep -Eq '^ *BAR=' $CONFIGFILE || \
echo "BAR=" >> $CONFIGFILE
sed -e "s/^ *FOO=.*/FOO=\"$FOO\"/" \
-e "s/^ *BAR=.*/BAR=\"$BAR\"/" \
< $CONFIGFILE > $CONFIGFILE.tmp
mv -f $CONFIGFILE.tmp $CONFIGFILE
Considere como estos dos scripts gestionan todas las situaciones. Las
preguntas se realizan por el script <<config>> durante una instalacion
nueva, y <<postinst>> genera un nuevo fichero de configuracion. Este
fichero se lee durante una actualizacion y reconfiguracion, y los
valores contenidos en el se usan para modificar los valores en la base
de datos de debconf, de forma que no se pierden los cambios manuales
del administrador. Las preguntas se plantean otra vez (y puede o no que
se muestren). Por ultimo, el script <<postinst>> sustituye los valores
en el fichero de configuracion, sin modificar el resto del contenido.
Permitir retroceder al usuario
Pocas cosas son tan frustrantes al usar un sistema como debconf que
responder a una pregunta, continuar a la siguiente pantalla con una
pregunta nueva, descubrir que hizo una mala eleccion en la pregunta
anterior, querer retroceder y descubrir que no puede.
Ya que el script <<config>> regula el comportamiento de debconf, este
no puede saltar a una pregunta anterior por si mismo, aunque puede
realizar este paso con un poco de su ayuda. El primer paso es permitir
que el script <<config>> sepa que debconf permite que el usuario pulse
un boton para retroceder. Para ello, use la orden <<CAPB>>,
introduciendo <<backup>> como parametro.
A continuacion, despues de cada orden <<GO>>, debe comprobar si el
usuario pidio retroceder (debconf devuelve un codigo de 30), y si es
asi, debe saltar a la pregunta anterior.
Existen varias formas de escribir las estructuras de control de su
programa para que pueda retroceder a preguntas anteriores cuando sea
necesario. Puede escribir un codigo complicado y confuso. O puede crear
varias funciones y usar recursion. Pero quizas la forma mas sencilla y
limpia es crear una maquina de estado. Aqui tiene un boceto de una
maquina de estado, que puede rellenar y expandir.
#!/bin/sh
set -e
. /usr/share/debconf/confmodule
db_capb backup
STATE=1
while true; do
case "$STATE" in
1)
# Dos preguntas no relacionadas.
db_input medium my/question || true
db_input medium my/other_question || true
;;
2)
# Realiza esta pregunta solo si
# se respondio afirmativamente
# a la primera.
db_get my/question
if [ "$RET" = "true" ]; then
db_input medium my/dep_question || true
fi
;;
*)
# El caso (<<case>>) predefinido se inicia cuando $STATE es
# mayor que el ultimo <<state>> implementado, abandonando el
bucle.
# Es necesario numerar los <<states>> consecutivamente desde
el 1
# sin espacios, ya que el <<case>> predefinido tambien se
introducira
# si hay un espacio en la numeracion.
break # exits the enclosing "while" loop
;;
esac
if db_go; then
STATE=$(($STATE + 1))
else
STATE=$(($STATE - 1))
fi
done
if [ $STATE -eq 0 ]; then
# El usuario pidio volver atras a la primera
# pregunta. Este caso es problematico. La
# instalacion regular de dpkg y apt no es capaz de
# retroceder a preguntas entre paquetes tal y como
# esto se escribe, asi que esto cerraria dejando el
# paquete sin configurar - probablemente la mejor
# forma de tratar esta situacion.
exit 10
fi
Tenga en cuenta que si todo lo que hace su script <<config>> es
plantear unas pocas preguntas sin relacion, no hay necesidad de una
maquina de estado. Solo plantee las preguntas, y <<GO>>; debconf lo
hara lo mejor que pueda para mostrar todas en la misma pantalla, y asi
el usuario no tendra que retroceder.
Evitar bucles infinitos
Debconf puede encontrar problemas si su script <<config>> contiene un
bucle. Suponga que su consulta requiere la entrada de datos y su
validacion, y su repeticion en caso de que no sea valida:
ok="
do while [ ! "$ok" ];
db_input low foo/bar || true
db_go || true
db_get foo/bar
if [ "$RET" ]; then
ok=1
fi
done
Superficialmente, esto es correcto. Pero considere que ocurre si el
valor de <<foo/bar>> es <<"">> al entrar en este bucle, y si el usuario
ha definido la prioridad de las preguntas a mostrar como alta, o si usa
una interfaz no interactiva, de forma que en realidad no se pide
ninguna entrada. El valor de <<foo/bar>> no se modifica mediante
<<db_input>>, fallando la prueba de validacion y realizando el bucle
una y otra vez...
Una forma de evitar esto es que antes de entrar en el bucle, el valor
de <<foo/bar>> este definido como algo que superaria la prueba en el
bucle. Por ejemplo, si el valor predefinido de <<foo/bar>> es "1",
entonces puede reiniciar (<<RESET>>) <<foo/bar>> antes de entrar en el
bucle.
Otra forma es comprobar el codigo de retorno de la orden <<INPUT>>. Si
es 30, el usuario no ve la pregunta que se les plantea, y deberia salir
del bucle.
Escoger entre paquetes relacionados
A veces se pueden instalar un conjunto de paquetes relacionados, y
desea consultar al usuario que conjunto se deberia usar por omision.
Ejemplos de tales conjuntos son gestores de ventanas o ficheros de
diccionario ispell.
Aunque sea posible que cada paquete en el conjunto podria simplemente
consultar <<cDeberia ser este paquete el predefinido?>>, conllevaria a
muchas preguntas repetitivas si se van a instalar varios paquetes.
Debconf permite la presentacion de una lista de todos los paquetes del
conjunto, permitiendo al usuario seleccionar cuales desea. Aqui tiene
como hacerlo.
Haga que todos los paquetes en el conjunto usen una plantilla
compartida (tipo <<shared>>). Algo como esto:
Template: shared/window-manager
Type: select
Choices: ${choices}
Description: Select the default window manager.
Select the window manager that will be started by
default when X starts.
Cada paquete deberia incluir una copia de esta plantilla. Tambien
deberia incluir codigo parecido al siguiente en su 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
Esto requiere una explicacion. Llegado el momento de ejecutar su script
<<config>>, debconf ya ha analizado todas las plantillas de los
paquetes que se van a instalar. Ya que el conjunto de paquetes
comparten una pregunta, debconf registra este hecho en el campo
<<owners>> (propietarios). Por una extrana coincidencia, el formato del
campo <<owners>> es el mismo que el del campo <<choices>> (elecciones),
una lista de valores separados por comas y espacios.
La orden <<METAGET>> se puede usar para obtener una lista de los
propietarios y de las elecciones. Si son diferentes, se ha instalado un
paquete nuevo. Use la orden <<SUBST>> para cambiar la lista de
elecciones para que sea igual a la lista de propietarios, y plantee la
pregunta.
Cuando se elimine un paquete probablemente querra ver si ese paquete es
la eleccion actualmente seleccionada, y si es asi, querra consultar al
usuario para que seleccione un paquete diferente para reemplazarlo.
Esto se puede lograr anadiendo algo similar a lo siguiente en los
scripts <<prerm>> de todos los paquetes relacionados (reemplazando
<paquete> con el nombre del paquete).
if [ -e /usr/share/debconf/confmodule ]; then
. /usr/share/debconf/confmodule
# No declara propiedad sobre esta pregunta.
db_unregister shared/window-manager
# Comprueba que la pregunta compartida aun existe.
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 [ "<paquete>" = "$RET" ] ; then
db_fset shared/window-manager seen false
db_input high shared/window-manager || true
db_go || true
fi
# Ahora haga lo que el script <<postinst>> hizo
# para actualizar el enlace simbolico del gestor
# de ventanas.
fi
fi
ARREGLOS
A dia de hoy debconf no esta completamente integrado en dpkg (pero
quiero cambiar esto en el futuro), y por ello actualmente se usan unos
arreglos poco elegantes.
El peor de estos arreglos implica ejecutar el script <<config>>. La
forma en la que funciona ahora es ejecutar el script <<config>> al
preconfigurar el paquete. Entonces, al ejecutar el script <<postinst>>,
inicia debconf otra vez. Debconf detecta que esta en uso mediante el
script <<postinst>>, y por ello se desactiva y ejecuta el script
<<config>>. Solo funciona si su script <<postinst>> carga una de las
bibliotecas debconf por lo que todos los scripts <<postinst>> deben
encargarse de ello. Esperamos cambiar esto en el futuro anadiendo la
compatibilidad explicita para debconf a dpkg. El programa debconf(1) es
un paso en esta direccion.
Otro arreglo relacionado es ejecutar debconf cuando un script
<<config>>, <<postinst>> u otro programa que lo usa se inicia. Despues
de todo, esperan poder comunicarse con debconf inmediatamente. La forma
de lograr esto actualmente es que cuando un script carga una biblioteca
de debconf (como <</usr/share/debconf/confmodule>>), y debconf no esta
en ejecucion, este se inicia, y se ejecuta una nueva copia del script.
La unica diferencia notable es que necesita ubicar la linea que carga
la biblioteca de debconf al principio del script o pueden ocurrir
comportamientos raros. Esperamos poder cambiar en el futuro la forma en
que se invoca debconf, transformandolo en un especie de demonio
transitorio.
La forma en que debconf averigua que ficheros de plantillas cargar y
cuando es tambien un arreglo poco elegante. Cuando los scripts
<<config>>, <<preinst>>, y <<postinst>> invocan debconf, este
averiguara automaticamente donde esta el fichero de plantilla, y lo
cargara. Los programas independientes que usan debconf provocaran que
debconf busque ficheros de plantilla en
<</usr/share/debconf/templates/progname.templates>>. Y si un <<postrm>>
desea usar debconf al purgar, las plantillas no estaran disponibles a
menos que debconf tenga la oportunidad de cargarlo a traves de
<<postinst>>. Esto es algo confuso, pero inevitable. En el futuro,
puede que algunos de estos programas sean capaces de usar
debconf-loadtemplate directamente.
El comportamiento historico de <</usr/share/debconf/confmodule>> de
manipular los descriptores de ficheros, configurando un descriptor de
fichero 3 para comunicarse con debconf, puede causar varios tipos de
problema cuando un <<postinst>> se comunica con debconf ya que el
script finaliza la comunicacion pero debconf no puede averiguar cuando
finaliza el script. Puede usar la orden <<STOP>> como un arreglo. En el
futuro, estamos considerando hacer que la comunicacion con debconf se
realice a traves de un <<socket>> o algun otro mecanismo ademas de la
entrada y salida estandar.
Debconf define <<DEBCONF_RECONFIGURE=1>> antes de ejecutar scripts
<<postinst>>, de forma que un script <<postinst>> que deba evitar
alguna operacion compleja al reconfigurarse puede examinar esa
variable. Este es solo un arreglo ya que lo correcto seria introducir
<<$1 = "reconfigure">>, pero hacerlo sin romper todos los <<postinst>>
que usan debconf es dificil. La via para abandonar este arreglo es
animar a la gente a que escriban ficheros <<postinst>> que acepten
<<reconfigure>>, y una vez que todos lo hagan, empezar a introducir ese
parametro.
V'EASE TAMBI'EN
debconf(7) es la guia de usuario de debconf.
La especificacion de debconf en las normas de Debian (debian-policy) es
la definicion estandar del protocolo de debconf. Puede encontrarlo
en<</usr/share/doc/debian-policy/debconf_specification.txt.gz>>.
debconf.conf(5) contiene mucha informacion util, incluyendo algo de
informacion acerca del sistema de la base de datos.
AUTOR
Joey Hess <joeyh@debian.org>
TRADUCCI'ON
Omar Campagne Polaino <ocampagne@gmail.com>, 2010
Si encuentra un fallo en la traduccion, por favor, informe de ello en
la lista de traduccion <debian-l10n-spanish@lists.debian.org>.
DEBCONF-DEVEL(7)