debconf-devel (7) - Linux Manuals
debconf-devel: developers guide
NAME
debconf - developers guideDESCRIPTION
This is a guide for developing packages that use debconf.This manual assumes that you are familiar with debconf as a user, and are familiar with the basics of debian package construction.
This manual begins by explaining two new files that are added to debian packages that use debconf. Then it explains how the debconf protocol works, and points you at some libraries that will let your programs speak the protocol. It discusses other maintainer scripts that debconf is typically used in: the postinst and postrm scripts. Then moves on to more advanced topics like shared debconf templates, debugging, and some common techniques and pitfalls of programming with debconf. It closes with a discussion of debconf's current shortcomings.
THE CONFIG SCRIPT
Debconf adds an additional maintainer script, the config script, to the set of maintainer scripts that can be in debian packages (the postinst, preinst, postrm, and prerm). The config script is responsible for asking any questions necessary to configure the package.Note: It is a little confusing that dpkg refers to running a package's postinst script as "configuring" the package, since a package that uses debconf is often fully pre-configured, by its config script, before the postinst ever runs. Oh well.
Like the postinst, the config script is passed two parameters when it is run. The first tells what action is being performed, and the second is the version of the package that is currently installed. So, like in a postinst, you can use dpkg --compare-versions on $2 to make some behavior happen only on upgrade from a particular version of a package, and things like that.
The config script can be run in one of three ways:
- 1
- If a package is pre-configured, with dpkg-preconfigure, its config script is run, and is passed the parameters "configure", and installed-version.
- 2
- When a package's postinst is run, debconf will try to run the config script then too, and it will be passed the same parameters it was passed when it is pre-configured. This is necessary because the package might not have been pre-configured, and the config script still needs to get a chance to run. See HACKS for details.
- 3
- If a package is reconfigured, with dpkg-reconfigure, its config script it run, and is passed the parameters "reconfigure" and installed-version.
Note that since a typical package install or upgrade using apt runs steps 1 and 2, the config script will typically be run twice. It should do nothing the second time (to ask questions twice in a row is annoying), and it should definitely be idempotent. Luckily, debconf avoids repeating questions by default, so this is generally easy to accomplish.
Note that the config script is run before the package is unpacked. It should only use commands that are in essential packages. The only dependency of your package that is guaranteed to be met when its config script is run is a dependency (possibly versioned) on debconf itself.
The config script should not need to modify the filesystem at all. It just examines the state of the system, and asks questions, and debconf stores the answers to be acted on later by the postinst script. Conversely, the postinst script should almost never use debconf to ask questions, but should instead act on the answers to questions asked by the config script.
THE TEMPLATES FILE
A package that uses debconf probably wants to ask some questions. These questions are stored, in template form, in the templates file.Like the config script, the templates file is put in the control.tar.gz section of a deb. Its format is similar to a debian control file; a set of stanzas separated by blank lines, with each stanza having a RFC822-like form:
For some real-life examples of templates files, see
/var/lib/dpkg/info/debconf.templates, and other .templates files in that
directory.
Let's look at each of the fields in turn..
Don't make the mistake of thinking that the default field contains the
"value" of the question, or that it can be used to change the value of the
question. It does not, and cannot, it just provides a default value for the
first time the question is displayed. To provide a default that changes on
the fly, you'd have to use the SET command to change the value of a
question.
If you can't think up a long description, then first, think some more. Post
to debian-devel. Ask for help. Take a writing class! That extended
description is important. If after all that you still can't come up with
anything, leave it blank. There is no point in duplicating the short
description.
Text in the extended description will be word-wrapped, unless it is
prefixed by additional whitespace (beyond the one required space). You can
break it up into separate paragraphs by putting " ." on a line by itself
between them.
Debconf's reply can be broken down into two parts: A numeric result
code (the first word of the reply), and an optional extended result code
(the remainder of the reply). The numeric code uses 0 to indicate success,
and other numbers to indicate various kinds of failure. For full details,
see the table in Debian policy's debconf specification document.
The extended return code is generally free form and unspecified, so you
should generally ignore it, and should certainly not try to parse it in a
program to work out what debconf is doing. The exception is commands like
GET, that cause a value to be returned in the extended return code.
Generally you'll want to use a language-specific library that handles
the nuts and bolts of setting up these connections to debconf and
communicating with it.
For now, here are the commands in the protocol. This is not the definitive
definition, see Debian policy's debconf specification document for that.
If 'escape' is found among your capabilities, debconf will expect commands
you send it to have backslashes and newlines escaped (as \\ and \n
respectively) and will in turn escape backslashes and newlines in its
replies. This can be used, for example, to substitute multi-line strings
into templates, or to get multi-line extended descriptions reliably using
METAGET. In this mode, you must escape input text yourself (you can use
debconf-escape(1)
to help with this if you want), but the confmodule libraries will unescape
replies for you.
Setting the title from a template means they are stored in the same place
as the rest of the debconf questions, and allows them to be translated.
The priority field tells debconf how important it is that this question be
shown to the user. The priority values are:
Debconf decides if the question is actually displayed, based on its
priority, and whether the user has seen it before, and which frontend is
being used. If the question will not be displayed, debconf replies with
code 30.
If the backup capability is supported and the user indicates they want
to back up a step, debconf replies with code 30.
One common flag is the "seen" flag. It is normally only set if a user has
already seen a question. Debconf usually only displays questions to users if
they have the seen flag set to "false" (or if it is reconfiguring a package).
Sometimes you want the user to see a question again -- in these cases you can
set the seen flag to false to force debconf to redisplay it.
Here is a simple example of the debconf protocol in action.
For shell programming, there is the
/usr/share/debconf/confmodule library, which you can source at the top of
a shell script, and talk to debconf in a fairly natural way, using lower-case
versions of the debconf protocol commands, that are prefixed with "db_"
(ie, "db_input" and "db_go"). For details, see
confmodule(3)
Perl programmers can use the
Debconf::Client::ConfModule(3pm)
perl module, and python programmers can use the debconf python module.
The rest of this manual will use the /usr/share/debconf/confmodule library
in example shell scripts. Here is an example config script using that library,
that just asks a question:
Notice the uses of "|| true" to prevent the script from dying if debconf
decides it can't display a question, or the user tries to back up. In those
situations, debconf returns a non-zero exit code, and since this shell
script is set -e, an untrapped exit code would make it abort.
And here is a corresponding postinst script, that uses the user's answer to
the question to see if the system should be rebooted (a rather absurd
example..):
Notice the use of the $RET variable to get at the extended return code from
the GET command, which holds the user's answer to the question.
A more involved use of debconf would be if you want to use it in the
postrm when your package is purged, to ask a question about deleting
something. Or maybe you find you need to use it in the preinst or prerm for
some reason. All of these uses will work, though they'll probably involve
asking questions and acting on the answers in the same program, rather than
separating the two activities as is done in the config and postinst
scripts.
Note that if your package's sole use of debconf is in the postrm, you should
make your package's postinst source /usr/share/debconf/confmodule, to give
debconf a chance to load up your templates file into its database. Then the
templates will be available when your package is being purged.
You can also use debconf in other, standalone programs. The issue to watch
out for here is that debconf is not intended to be, and must not be used as
a registry. This is unix after all, and programs are configured by files in
/etc, not by some nebulous debconf database (that is only a cache anyway
and might get blown away). So think long and hard before using debconf in a
standalone program.
There are times when it can make sense, as in the apt-setup program which
uses debconf to prompt the user in a manner consistent with the rest of the
debian install process, and immediately acts on their answers to set up
apt's sources.list.
Besides the 'Description' field, you should translate the 'Choices' field
of a select or multiselect template. Be sure to list the translated choices
in the same order as they appear in the main 'Choices' field. You do not
need to translate the 'Default' field of a select or multiselect question,
and the value of the question will be automatically returned in English.
You will find it easier to manage translations if you keep them
in separate files; one file per translation. In the past, the
debconf-getlang(1)
and
debconf-mergetemplate(1)
programs were used to manage debian/template.ll files. This has been
superseded by the
po-debconf(7)
package, which lets you deal with debconf
translations in .po files, just like any other translations. Your
translators will thank you for using this new improved mechanism.
For the details on po-debconf, see its man page. If you're using
debhelper, converting to po-debconf is as simple as running the
debconf-gettextize(1)
command once, and adding a Build-Dependency on po-debconf and on debhelper
(>= 4.1.13).
Well, except for testing, debugging, and actually using debconf for more
interesting things than asking a few basic questions. For that, read on..
It's rather useful to use debconf's readline frontend when you're debugging
(in the author's opinion), as the questions don't get in the way, and all
the debugging output is easily preserved and logged.
It turns out that if you set up a ~/.debconfrc file for a normal
user, pointing at a personal config.dat and template.dat for the user, you
can load up templates and run config scripts all you like, without any root
access. If you want to start over with a clean database, just blow away the
*.dat files.
For details about setting this up, see
debconf.conf(5),
and note that /etc/debconf.conf makes a good template for a personal
~/.debconfrc file.
There are a lot of ways to do this, and most of them are wrong, and will
often earn you annoyed bug reports. Here is one right way to do it. It
assumes that your config file is really just a series of shell variables
being set, with comments in between, and so you can just source the file to
"load" it.
If you have a more complicated format, reading (and writing) it
becomes a bit trickier.
Your config script will look something like this:
And the postinst will look something like this:
Consider how these two scripts handle all the cases. On fresh installs the
questions are asked by the config script, and a new config file generated
by the postinst. On upgrades and reconfigures, the config file is read in,
and the values in it are used to change the values in the debconf database,
so the admin's manual changes are not lost. The questions are asked again
(and may or may not be displayed). Then the postinst substitutes the values
back into the config file, leaving the rest of it unchanged.
Since debconf is driven by your config script, it can't jump back to
a previous question on its own but with a little help from you, it can
accomplish this feat. The first step is to make your config script let
debconf know it is capable of handling the user pressing a back button.
You use the CAPB command to do this, passing backup as a parameter.
Then after each GO command, you must test to see if the user asked to back
up (debconf returns a code of 30), and if so jump back to the previous
question.
There are several ways to write the control structures of your program so it
can jump back to previous questions when necessary. You can write goto-laden
spaghetti code. Or you can create several functions and use recursion. But
perhaps the cleanest and easiest way is to construct a state machine. Here
is a skeleton of a state machine that you can fill out and expand.
This is its extended description.
.
Notice that:
on its own line sets off a new paragraph.
text is left alone, so you can use it for lists
of items, like this list. Be careful, since
it is not word-wrapped, if it's too wide
it will look bad. Using it for short items
is best
This is another question, of boolean type.
QUESTIONS
A question is an instantiated template. By asking debconf to display a
question, your config script can interact with the user. When debconf loads
a templates file (this happens whenever a config or postinst script is
run), it automatically instantiates a question from each
template. It is actually possible to instantiate several independent
questions from the same template (using the REGISTER command), but that is
rarely necessary. Templates are static data that comes from the templates
file, while questions are used to store dynamic data, like the current
value of the question, whether a user has seen a question, and so on. Keep
the distinction between a template and a question in mind, but don't worry
too much about it.
SHARED TEMPLATES
It's actually possible to have a template and a question that are shared
among a set of packages. All the packages have to provide an identical
copy of the template in their templates files. This can be useful if a
bunch of packages need to ask the same question, and you only want to
bother the user with it once. Shared templates are generally put in the
shared/ pseudo-directory in the debconf template namespace.
THE DEBCONF PROTOCOL
Config scripts communicate with debconf using the debconf protocol. This is
a simple line-oriented protocol, similar to common internet protocols such
as SMTP. The config script sends debconf a command by writing the command
to standard output. Then it can read debconf's reply from standard
input.
LIBRARIES
Setting things up so you can talk to debconf, and speaking the debconf
protocol by hand is a little too much work, so some thin libraries exist
to relieve this minor drudgery.
THE POSTINST SCRIPT
The last section had an example of a postinst script that uses debconf to
get the value of a question, and act on it. Here are some things to keep in
mind when writing postinst scripts that use debconf:
OTHER SCRIPTS
Besides the config script and postinst, you can use debconf in any of the
other maintainer scripts. Most commonly, you'll be using debconf in your
postrm, to call the PURGE command when your package is purged, to clean
out its entries in the debconf database. (This is automatically set up for
you by
dh_installdebconf(1),
by the way.)
LOCALIZATION
Debconf supports localization of templates files. This is accomplished by
adding more fields, with translated text in them. Any of the fields can be
translated. For example, you might want to translate the description into
Spanish. Just make a field named 'Description-es' that holds the
translation. If a translated field is not available, debconf falls back to
the normal English field.
PUTTING IT ALL TOGETHER
So you have a config script, a templates file, a postinst script that uses
debconf, and so on. Putting these pieces together into a debian package
isn't hard. You can do it by hand, or can use
dh_installdebconf(1)
which will merge your translated templates, copy the files into the right
places for you, and can even generate the call to PURGE that should go in
your postrm script. Make sure that your package depends on debconf (>= 0.5),
since earlier versions were not compatible with everything described in this
manual. And you're done.
DEBUGGING
So you have a package that's supposed to use debconf, but it doesn't quite
work. Maybe debconf is just not asking that question you set up. Or maybe
something weirder is happening; it spins forever in some kind of loop, or
worse. Luckily, debconf has plenty of debugging facilities.
ADVANCED PROGRAMMING WITH DEBCONF
Config file handling
Many of you seem to want to use debconf to help manage config files that
are part of your package. Perhaps there is no good default to ship in a
conffile, and so you want to use debconf to prompt the user, and write out
a config file based on their answers. That seems easy enough to do, but
then you consider upgrades, and what to do when someone modifies the config
file you generate, and dpkg-reconfigure, and ...
Letting the user back up
Few things are more frustrating when using a system like debconf than being
asked a question, and answering it, then moving on to another screen with a
new question on it, and realizing that hey, you made a mistake, with that
last question, and you want to go back to it, and discovering that you
can't.