Re: Debian Configuration Packaging System
On Mon, 25 Feb 2008, Frank Küster wrote:
Uh, you can dpkg-divert conffiles, but not generally configuration files, since
many won't even be known to dpkg. I must admit I'm a bit sceptical about a
proposal on configuration, written by someone who lets this important
distinction slip by...
No, I really meant configuration files. While our system certainly
applies to all conffiles, it also applies to various other classes of
files:
1) Those that are accidentally not marked as conffiles (e.g.
/etc/adduser.conf).
2) Those that are initially created via a system like debconf but that
preserve user changes, often because they support other configuration
options than those in debconf (e.g. /etc/krb5.conf or
/etc/ssh/sshd_config) [the dpkg-divert doesn't do anything here, but the
system still works].
3) Scripts that are not marked as conffiles but which cannot be configured
in any way other than by modifying the script.
I probably should have said this explicitly earlier, but our system is
currently only an 80% solution, because it cannot override any package's
configuration file handling system that does not preserve manual changes.
It turns out that these are fairly rare, and can be handled with some
annoyance (e.g. releasing a new version of our configuration package
whenever a new release of such a package comes out, so that the
configuration package wins).
I would like to see it become a 100% solution, since I think support for
easily creating configuration packages would be really valuable for a lot
of organizations using Debian and Ubuntu. The primary difficulties are
interacting nicely with systems like ucf and debconf; I don't think that
it is possible to achieve 100% without some changes to Debian itself.
Because of ucf's architecture, it would be easy to make ucf interact
nicely with our system (and our system should perhaps use ucf itself,
since it seems to be a strict improvement over the just marking things as
conffiles).
There are really two problems with debconf in our system. The first is
that debconf asks questions which our configuration package system will
override. Using 'DEBCONF_PRIORITY=critical apt-get install' limits them,
but some packages we configure prompt for information even with critical
DEBCONF_PRIORITY (is this a bug?). The second problem is that some
packages override any manual changes to the relevant configuration file.
Because the code to take action based on debconf selections in so
decentralized, this second problem is relatively hard.
For the second debconf problem, the easiest "solution" would be to add to
our system support for pre-seeding the debconf database for package X and
then running the configure script for package X. We have the tools to do
this, and it would work, but it would lose a property of our system that I
really like: support for uninstalling configuration packages.
I would prefer to come up with a solution that does not lose this feature.
I can think of several solutions preserving this feature that require
changing every package that blindly overwrites user configuration on
package upgrades to do some sort of check before doing so; I would love to
hear ideas for mechanisms for achieving our goals (see
<http://debathena.mit.edu/config-packages/#philosophy>) without having to
change all such packages.
Later on you wrote something about symlinks, do you use them, too? Here's one
more complication: While I think that "preserve local changes" also includes the
symlink-or-not state of a file and thus must be respected by maintainer scripts,
I do not think that this is usually done. In particular, every configuration
file handling that was first written for sarge (where sed -i wouldn't work)
probably used tempfiles and mv, and I have not seen a single case where the
script checked whether it was dealing with a symlink.
To be precise, after installing a package that intends to configure
/etc/ldap/ldap.conf, the system will be in the following configuration:
$ ls -l /etc/ldap/ldap.conf* [irrelevant stat information removed]
/etc/ldap/ldap.conf -> ldap.conf.debathena
/etc/ldap/ldap.conf.debathena
/etc/ldap/ldap.conf.debathena-orig
$ /usr/sbin/dpkg-divert --list | grep ldap
diversion of /etc/ldap/ldap.conf to /etc/ldap/ldap.conf.debathena-orig by debathena-ldap-config
So, yes, our system uses both symlinks and dpkg-divert. Simply placing
files at /etc/ldap/ldap.conf (rather than using a symlink) doesn't work
because it would require running dpkg-divert at preinst rather than
postinst, which results in needing to pre-depend the packages whose
configuration one is changing, and lots of other problems.
It's not just ucf, it's also perfectly possible that a maintainer script edits a
configuration file, e.g. after debconf prompting, in order to take over user
changes from a related package's configuration file, or similar.
How do you deal with that?
Indeed, there's almost nothing that we can do about that. Fundamentally,
postinst scripts have arbitrary execution, and almost any system one
designs to handle configuration can be thwarted, at least temporarily, by
a package postinst script. I also haven't run across this in any package
I've cared about.
One idea that would deal with this problem (and solve all the other
problems we've discussed other than the unecessary prompting problem)
would be for dpkg to run postinst scripts in a special environment that
rewrites filenames according to the diversion database (an evil LD_PRELOAD
hack might work; chrooting into a special fuse filesystem certainly
would). However, this requires changes to dpkg that I doubt the dpkg
maintainers would accept (correct me if I'm wrong!).
-Tim Abbott
Reply to: