Template-driven configuration system

From SME Server
Revision as of 23:09, 8 June 2015 by Stephdl (talk | contribs) (Created page with "{{Level|Developer}} ===Introduction=== This document attempts to explain the e-smith server and gateway's unique templated configuration system. It is aimed at experienced us...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
PythonIcon.png Skill level: Developer
Risk of inconsistencies with Koozali SME Server methodology, upgrades & functionality is high. One must be knowledgeable about how changes impact their Koozali SME Server. Significant risk of irreversible harm.


Introduction

This document attempts to explain the e-smith server and gateway's unique templated configuration system. It is aimed at experienced users and developers.

Design of the template system

Every piece of software has its own configuration format, and writing parsers for each one can be a complex, time-consuming and error-prone process. The e-smith software avoids the whole issue by using a template-driven system instead, using Perl's Text::Template module.

Templates are stored in a directory hierarchy rooted at /etc/e-smith/templates. Each configuration file is either a Text::Template file, or can be given a subdirectory in which template fragments are stored. These templates are then parsed (and in the case of a subdirectory of fragments, concatenated together) to generate the config files for each service on the system. The fragmented approach is part of e-smith's modular and extensible architecture; it allows third-party modules to add fragments to the configuration if necessary.

The Text::Template module

The text template module allows arbitary Perl code to be embedded in a template file by surrounding it in braces ({ and }). The code inside the braces is interpreted and its return value is substituted where the braces were. For instance:

The answer is { 2 + 2 }

becomes

The answer is 4

Variables can be passed in from the program which is expanding the template, hence:

Shopping list:

{ 
 my $output;
 foreach my $item (@list) {
   $output .= "* $item\n";
 }
 return $output;
}

could expand to:

Shopping list:
* bread
* milk
* bananas

The e-smith template system uses this mechanism to pass in global configuration variables such as those found in /home/e-smith/configuration to fill in the configuration files.

For instance, here is e-smith's version of the configuration for the NTP (Network Time Protocol) server:

Server { $NTPServer }
driftfile /etc/ntp/drift
authenticate no

Template expansion

Templates are expanded via a routine called processTemplate in the esmith::util Perl module. The program /sbin/e-smith/expand-template is a simple wrapper around this routine.

expand-template

The syntax of this command is:

/sbin/e-smith/expand-template filename

where filename is the name of the config file you want to generate, eg /etc/hosts.

esmith::util::processTemplate

The esmith::util::processTemplate routine takes arguments in one of two forms, which for convenience we'll call the "old" and "new" styles.

The old-style arguments require a reference to a hash containing the configuration values (usually obtained by tying a hash using esmith::config, see /sbin/e-smith/expand-template for an example), and the name of a config file to generate, eg /etc/hosts.

The new-style arguments take a hashref containing the tied hash of config data, template path, and optionally whatever other parameters you might want to specify. Here is a simple example:

processTemplate({
   CONFREF => \%conf,
   TEMPLATE_PATH => '/etc/hosts',
});

This will default the other parameters to sensible values. However we can explicitly set them if we prefer. The following example shows how to expand a template /etc/e-smith/templates-user/qmail to /home/e-smith/files/users/$username/.qmail, presumably within a loop which acts upon each user in turn:

processTemplate({ 
   CONFREF => \%conf, 
   TEMPLATE_PATH => '/qmail',
   TEMPLATE_EXPAND_QUEUE => [
       '/etc/e-smith/templates-user-custom',
       '/etc/e-smith/templates-user',
   ],
   OUTPUT_PREFIX => '/home/e-smith/files/users/$username',
   OUTPUT_FILENAME => '/.qmail',
   UID => $username,
   GID => $username,
   PERMS => 0644,
});

Custom template modifications

The first rule when customizing the e-smith server and gateway is this: If you want to change a configuration file, check whether there is a template for it in the /etc/e-smith/templates directory. If there is, make the change via the template mechanism! Otherwise your changes will be overwritten next time the configuration files are generated from the templates.

To allow customizations, and to clearly isolate user-customizations from package-installed templates, a second template tree is rooted at /etc/e-smith/templates-custom/ Templates found in this directory will override the templates in /etc/e-smith/templates/. Hence, to customize an existing template, copy any fragments of that template that you wish to change to the /etc/e-smith/templates-custom/ directory, and make any necessary changes there. If you only need to change (or add) one small fragment, there is no need to copy the entire collection of fragments across -- just copy the ones you need.

This provides a convenient backup mechanism: if you want to revert to the original template, simply rename the /etc/e-smith/templates-custom/ directory.

For example, here's how to make changes to the smb.conf file.

   Make the templates-custom directory:
   mkdir -p /etc/e-smith/templates-custom/etc

Copy existing files for smb.conf:

   cp -rp /etc/e-smith/templates/etc/smb.conf /etc/e-smith/templates-custom/etc/

Edit the individual fragments or create new ones that fit in between as required.

Expand the templates:

   /sbin/e-smith/expand-template /etc/smb.conf

When you've finished, the new changes will appear in the /etc/smb.conf file and can be modified from the /etc/e-smith/templates-custom/ directory.

   Note: Your custom templates should be checked after any upgrades to the e-smith software as your changes may be inconsistent with later releases.