[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Configuration management again



It seems to me there are about 3 very separate and distinct issues
which people are confusing here. They are:-

1. Separating non-interactive and interactive configuration of packages
   somehow.

2. Making some kind of persistent storage manager for package configuration
   data.

3. Making some kind of global "registry" for Debian from which one can
   configure most things.

My points for issue #1:-

There is NO reason not to do this for the post-inst script. Make postinst
non-interactive, and add an interactive script, config. It CAN be made
backwards-compatible as well:-

#!/bin/sh
# sample postinst
if ! dpkg --assert-runs-config >/dev/null 2>/dev/null; then
	sh /var/lib/dpkg/info/sample.config
fi

Bad things about this are (1) that it references /var/lib/dpkg directly,
so if we change the name of the directory we have difficulty, (2)
that it "complicates scripts for the sake of backwards-compatibility"
(although not much), and most importantly (3) that it makes it difficult
to tell if a postinst is interactive. Good things are that it is fully
backwards-compatible, does what we need it too, and does it concisely.

The issue of being able to tell if a postinst is interactive is actually
quite important, since for a real non-interactive dpkg run, such packages
CANNOT (and MUST NOT) be configured.

My points for issue #2:-

By writing a tool, say "dconfig", we can kill two birds with one stone.
The (currently imaginary) "dconfig" program asks the user questions,
then stores the result in your persistent storage. Now, here's where
the clever bit comes in. "dconfig" is also a script generator. It
would work like this:-

# sample file /usr/lib/dconfig/sample
[config db]
misc/sample/			dir
misc/sample/run_daemon		bool	"Whether to run the sample daemon"

[config script]
section ();
text ("Welcome to the sample package configuration.\n"
	"First, we need to know whether you want to run the daemon.");
get (misc/sample/run_daemon, "Do you want to run the sample daemon?");

[get vars]
RUN_DAEMON=(misc/sample/run_daemon) ? "Yes" : "No"
# End of sample file.

Now, we run this through "dconfig --make-script sample", and it churns
out some fairly standardized fragments for the "config" and "postinst"
scripts:-

# config fragment
mkdir -p /etc/debian/sample
if [ -x /usr/bin/dconfig ]; then
	dconfig --register sample
	dconfig --configure sample
	echo "eval `dconfig --get-vars`" > /etc/debian/sample/config
else
cat <<EOF
Welcome to the sample package configuration.
First, we need to know whether you want to run the daemon.
EOF
	RES=""
	while [ "$RES" = "" ]; do
		echo -n "Do you want to run the sample daemon? "
		read ANS
		if [ "$ANS" = "y" -o "$ANS" = "Y" -o "$ANS" = "yes" -o
			"$ANS" = "Yes" -o "$ANS" = "YES" ]; then
			RES="Yes"
		elif [ "$ANS" = "n" -o "$ANS" = "N" -o "$ANS" = "no" -o
			"$ANS" = "No" -o "$ANS" = "NO" ]; then
			RES="No"
		fi
	done
	echo "RUN_DAEMON=$RES" > /etc/debian/sample/config
fi
# end config fragment

# postinst fragment
if ! dpkg --assert-runs-config >/dev/null 2>/dev/null; then
	sh /var/lib/dpkg/info/sample.config
fi
. /etc/debian/sample/config
# end postinst fragment

After the use of these fragments, the packager only has to put
things in his postinst fragments saying things like

if [ "$RUN_DAEMON" = "Yes" ]; then
	...
fi

This solution allows the user to get away without ANY kind of
persistent storage management (as they are), or use it all if
they want to.

There are a couple of other issues relating to interactivity.
First, some scripts NEED to ask questions after determining
a given state of affairs exists. For example, AFAIK, the
fdutils package will ask you if you want to create some new
device nodes (or it did at one point).

This is the type of question which can only be asked at run time.
IMHO the best way to deal with this non-interactively would be to
have the user able to determine between three states IF they
are preconfiguring: "Do it if it can be", "Don't", and "ask me".
It would of course default to "ask me".

Points relating to #3:-

I think this is probably a bad idea. Some things like /etc/default/rcS
could probably benefit from this. However, I think that designing
custom-built configuration tools for these sorts of things would
be better. For simple cases, we can design a "generic" tool for
editing such things. Putting this data into a global "registry"
physically would normally be a bad idea. However, designating various
configuration items with registry keys could be beneficial. A physical
registry could then be maintained as a "master" for a cluster, or
whatever. Each time a machine booted, it would sync the registry
values against the real ones.

For example, one of the first things rcS might do could be:-

/bin/dregistry --sync --nonet /etc/default/rcS
. /etc/default/rcS

A bit later, we might see a script /etc/init.d/dreg-sync, which could
do the following:-

/bin/dregistry --sync-remote http://master/cluster/registry
/bin/dregistry --sync --all

In short, I like the idea of a registry as a way of centrally controlling
configurations. As a way of keeping configurations permanently, I don't,
because its not very flexible. Having something which understands your
text-based config files and writes to them as an admintool backend, and
also which can sync from a registry when wanted would be good.

-- 
Tom Lees <tom@lpsg.demon.co.uk> <tom@debian.org>  http://www.lpsg.demon.co.uk/
PGP Key: finger tom@master.debian.org, http://www.lpsg.demon.co.uk/pgpkeys.asc.


Reply to: