FAI Class Server

Introduction

The FAI Class Server (FCS) evolved during a project I did in summer 2005 at the Federal Institute of Technology Lausanne. The project was part of a FAI setup to allow for fully automated Debian GNU/Linux installations on a number of different machines (workstations, notebooks, servers, and cluster nodes).

FCS is a helper application to manage FAI classes in a centralized manner. Its main features are:

License

FAI Class Server (FCS) is licensed under the GNU General Public License.

Download

Current version: 0.1 (2005-10-18) [fcs-0.1.tar.gz (14 kB)]

Screenshots

Components

FCS consists of a server and a client part, the ladder one being divided into several parts. What follows is a description and configuration manual for all of these parts.

FCS server part

There are two operating modes fot the server part:

Both modes are functionally equivalent, however, there is a slight difference in the configuratin of the client parts. When running in stand-alone mode, the request path is always / whereas in CGI mode it depends on the location of the CGI script (e.g. /cgi-bin/fai/).

FCS client parts

At the moment there are two FCS client parts, one for hostname based class assignment and a second one for class dependency resolution. The parts come in the form of FAI class scripts that are located in the config/class directory.

The fcs-hostname script connects to the FCS server part and transmits the current (fully-qualified) hostname. In response it receives a list of class names the installing machine belongs to and adds those classes to the current list of classes.

The fcs-dependencies part behaves in a similar name but instead of the hostname it sends the current list of classes (including those added by the fcs-hostname script if it has been run before) to the server. The response again contains a list of classes to be added to the current class list, but this time as a function of the class list transmitted, namely the classes that depend on them (and so on—the process works recursively).

Installation

TODO

Configuration

Both, server and client parts, have various configuration options which are described below in detail. While the main configuration of the server part uses in-program configuration (meaning that a section of constants at the top of the source file can be edited), the remaining components use an approach based on text files.

Server part

Main configuration

The main configuration controls the port number of the built-in HTTP server and the locations of the different config files. The configuration options can be found at the top of the fcs.pl source file in the block titled Constants. The available options are:

Option Description
SERVER_PORT [Stand-alone mode only] Determines the port number that the built-in HTTP server listens on. Make sure you set this to a port number that is not otherwise in use or the server will fail to start.
CLASSES_DIR The location of the scripts used to determine if a given hostname is a member of the class. This must be a directory name. Unless the path starts with a slash, it will be interpreted relative to the directory containing the script. The functioning of these class membership scripts is described in more detail below.
DEP_CONFIG The location of the configuration file describing class dependencies. The must be the name of an existing file whose syntax is described in the section Class dependency configuration below.
ORDER_CONFIG The location of the configuration file describing class order. The file must exist and conform to the syntax described in the section Class order configuration below.

Class membership scripts

When the FCS server receives a request of the form ?hostname=myhost.mydomain.org, it executes every script in the CLASSES_DIR directory with the hostname (myhost.mydomain.org in the example) as the first argument. If the script returns with value 0 ("true"), the host is taken to belong to the given class. If it returns with a non-zero value ("false"), the machine is not part of the class and nothing happens.

An example script that retrieves host-to-class associations from a text file is included. It is described in more detail in the Example scripts section below.

The recommended way of handling class membership scripts is to have a separate directory containing the actual scripts and create symbolic links in the CLASSES_DIR directory with the names of the classes. The script can then retrieve the class name from the name it was called as (usually $0). Another possibility is to create symlinks to /bin/true or /bin/false for classes that all/no machines should be members of.

Class dependency configuration

The class dependency file describes dependencies between classes. A sample is provided for illustration purposes.

Each line consists of two parts; a classname and a list of required classes (separated by whitespace or commas). Empty lines and comment lines (starting with the # character) are ignored.

Example: You want all machines that are members of the NOTEBOOK class automatically to be members of the PCMCIA and WIRELESS classes. Simply add the following line to the configuration file:

NOTEBOOK    PCMCIA, WIRELESS

An important feature of FCS' class dependencies is the ability to resolve transitive dependencies. Let us explain this by means of a simple example:

Example: You want your desktop machines to have KDE and Xfce installed by default. On some machines, however, you decide to use the GNOME desktop instead. Because Xfce lacks a few applications that you want to make available to your users, you decide to install a subset of GNOME (a GNOMEAPPS class) whenever Xfce is installed. For this scenario you would use the following setup:

GNOME 	    GNOMEAPPS
XFCE        GNOMEAPPS
DESKTOP     KDE, XFCE

As you can see there is a transitive dependency "DESKTOP => XFCE => GNOMEAPPS". So whenever a machine is a member of the DESKTOP class you not only want it to belong to XFCE but also to GNOMEAPPS.

This kind of dependency is automatically resolved by FCS as long as dependencies for required classes are defined before they are used. In the above example, if the DESKTOP class were defined in the first line, the transitive dependency could not be resolved (because by the time FCS reads the DESKTOP line it does not know about XFCE's dependency on GNOMEAPPS.

Class order configuration

A class order file defines a class order that is used during a reorder request. While class order is not used by the client parts included with FCS, it can prove useful in post-install scripts when you need scripts for individual classes to be run in a particular order.

The syntax for class order files is very simple. Each line contains the name of a class and the order of the lines defines the order used for sorting. Again, empty lines and lines with a leading # are ignored.

Example: To impose the order "X, KDE, DESKTOP", the configuration file could look as follows:

# Make sure X is configured before KDE
X

KDE
DESKTOP

If classes are to be sorted that cannot be found in the class order configuration they are inserted at the end of the list. This can lead to a problem with two of FAI's predefined classes: DEFAULT (always first) and LAST (always last). If you omit them from your configuration, they might both end up at the end of the list, so DEFAULT would not be guaranteed to be the first class in the list anymore.

To work around this possible source of error, FCS handles these two classes in a special way: Unless specified otherwise the DEFAULT is automatically assumed to be at the first position, while the LAST class is automatically appended at the end.

In certain cases you may not want all unknown classes to be at the end of the list (remember: they would still precede the LAST class). For this case you can use the * placeholder. A final example illustrates this:

Example: You want all unknown classes to be between BASE and DESKTOP:

BASE
X

# Unknown classes before DESKTOP
*

DESKTOP

Recommended file structure

This section describes a possible file structure for the server part of FCS. It is merely a recommendation and by no means a requirement, so it can be adapted according to the needs of the user.

Directory Contents Description
./ fcs.pl FCS server part, main program
./classes/ CLASS_A -> ../scripts/text.pl
CLASS_B -> ../scripts/text.pl
CLASS_C -> ../scripts/text.pl
Host-to-class association scripts (symlinks in this case): called with the hostname as the first argument
./config/ CLASS_A
CLASS_B
CLASS_C
Host-to-class association configuration files for scripts/text.pl
./scripts/ text.pl Example script: text-based host-to-class association
./deps/ deps.conf Class dependency configuration
./order/ order.conf Class order configuration

Example scripts

Client parts

Configuration of the client parts is rather straightforward. It is limited to a single configuration file as can be seen from the following table explaining the equally simple file structure:

Directory Contents Description
./FAI/config/class 60-fcs-hostname.source
98-fcs-dependencies.source
Scripts for determining hostname-dependent class membership and class dependencies
./FAI/config/class fcs.conf Configuration file used by the FCS client part scripts

The fcs.conf configuration file has a number of settings that influence the behavior of the client parts:

Option Description
FCS_HOST The name of the host the FCS server part is running on.
FCS_PORT The port number of the FCS server part.
FCS_BASE_URL The URL where the FCS server part can be reached.
FCS_DEBUG Enables debug mode for the client parts. In debug mode the scripts wait for the user to press the Enter key after their task is completed. Uncomment this setting to enable debug mode.
FCS_SLEEP The amount of time (as understood by the sleep command) to wait after a task is completed. This delay can be useful if you want to double-check the functioning of your FCS setup.
FCS_ERROR_SLEEP The amount of time to wait after an error has occurred (e.g. if the FCS server could not be reached). The format is the same as for FCS_SLEEP.

Since the configuration file is sourced by the client parts, you can use Bash-style comments.