Configuration Management
Rereading the discussions I realized it might be better to cleanly divide this text into two sections: managing configuration data, and determining configuration when installing packages. Hopefully this will result in a better presentation of my ideas. I also expanded a few sections with ideas gathered from various suggestions. Managing configuration data =========================== 1. The configuration space All configuration information is stored in what I call the configuration space. This is a database with a special design which resembles to method we look at configuration information. This is done by defining a hierarchy of information. The toplevel of the hierarchy is for packages. Each package is free to use a flat space, or divide it's space further into subhierarchies. If multiple packages share a common purpose they may use a shared toplevel hierarchy, preferably with the same name as a shared (virtual) packagename (for example, both mutt and elm can use mail-reader, strn an nn could use news-reader). This shared tree can also be used as a default, ie a variable /news-reader/nntpserver can be used by strn if /strn/nntpserver does not exist. 2. Types of variables Multiple types of variables can be stored in the configuration space. A preliminary list of types is: strings, numbers, lists, hostnames, IP addresses. Each variable can have meta-data associated with it for special purposes. The only meta-data currently defined is an "isdefault" flag, which states of a variable has been changed from it's default value. This can be used when upgrading a package to check if the user has changed the default, or it's safe to change it to a new default. This gives us the same result as the md5sum-checking dpkg does for conffiles, but on a much finer-grained level (per variable instead of per file). 3. Accessing the configuration The configuration space is implemented by a shared library. This library contains all functions necessary to open the database, retrieve and store information and close it. For scripts there will also be a dpkg-var utility to access the configuration space. Install-time configuration ========================== 1. The configuration module. The configuration module (configmodule for short) We want to make a package which does not break older dpkg's, and we want to be able to get the configuration information before the package is unpacked. To do this we add a configuration module (configmodule for short) to the package besides the current control.tar.gz and data.tar.gz . Since all installation-software (apt, dselect, dpkg) download the package before installing it, we can extract this module before the package is unpacked. Since older dpkg's will not process the extra file, we can do to things: either create an extra assertion "--assert-configmodule" in dpkg which is checked in the preinst, or up the versionnumber of the package. 2. What does the configmodule do? The configmodule is the part of a package that will determine the configuration before the package is installed. This means it is run _before_ the preinst, and before the package is unpacked! Unless pre-depends are used, this will mean that the module can only assume the base-system is installed. 3. How does the configmodule get it's information? The configmodule needs a way to retrieve information from the configuration space, ask the user for information if necessary, etc. But we don't want to implement a user interface for each package. To solve this we use a seperate frontend, which provides the configmodule with a method to access the configuration space and interact with the user. 4. How do the configmodule and the frontend interact? Of course the configmodule and the frontend must exchange data to do their work. We do this in a very simple manor: dpkg starts both the configmodule and the frontend, and connect the stdin/stdout from the module to the stdout/stdin of the frontend. We can then use stdin/stdout to communicate, while still having stderr available to report errors. 5. The frontend There are two types of frontends possible: interactive and non-interactive. Interactive frontends allow the user to answers questions and see messages. Non-interactive frontends get all information from a database (SQL, LDAP, db, textfiles, etc.). If a non-interactive frontend is used and the configmodule refuses to accept the information the frontend retrieves, it can exit with a non-zero exit code, indicating to dpkg it's not possible to install the package with the current configurationdatabase. 6. Communication language This communication between the frontend and the configmodule should be as simple as possible. Since most IO implementations default to line-buffered IO, so we use a simple language where each command is exactly one line. A prelimary list of commands is: General commands: VERSION <number> The version-number of the communication-language the module will use. CAPB Asks the frontent for a list of capabilities. The includes interactiveness! STOP We are finished. Store the new variables now if transactions are used and flush the diskcache to make sure we don't loose anything. Interface commands: RESET Clear the accumalated set of TEXT and INPUT commands TEXT <string> Show a string to the user. The string is need not be shown until a GO command is given. INPUT <comment> <type> <variable> Asks the user for to enter a value of type <type> which should be stored in <variable>. Show <comment> as a comment before the inputbox/line. If <variable> has been given a value with SET use that as a default. This question is not asked until a GO command is given. This allows us to ask multiple questions in a single screen. BEGINBLOCK ... ENDBLOCK Define the beginning and end of a block of interface commands GO Show the current set of accumulated questions to the user and allow the user to change the answers. Configuration space access: UNSET <variable> Remove <variable> from the configurationspace SET <variable> <type> <value> Set a variable <variable> of type <type> to <value> and unset the isdefault metaflag. DSET <variable> <type> <value> Set a default-value. Same as above, but change <variable> only if the meta-data isdefault flag is still set. GET <variable> Return the value of variable <variable> The frontend responds to each command by returning a status code and, if needed, extra data after the status code. The frontend has complete responsibility for the layout of the questions, with the exception that the ordering of interface information within a block may not be changed. 7. Extra note(s) Some people wondered how to manage shared configuration-data such as install-mime. Actually this is quite easy: simply call a special install-mime which can interact with the frontend from your configmodule and let that do the configuration.
pgpMe0oHAfej5.pgp
Description: PGP signature