Previous Up Next

3  Configuration files

There are currently three configuration files, parsed in that order: pica.conf, hosts.conf and objects.conf. All of them are placed in the /etc/pica directory. The first is a configuration file to control behaviour of the pica main script; the second, a description of the hosts PICA will work on; the last, a description of the objects to process.

3.1  Basic syntax

All the configuration files share a common syntax, similar to that of the DNS config files. Before being read, they are parsed by the Perl PreProcessor. Generally speaking, there are properties and constants, assigned to those properties. The properties must match the following regex:

(\w|/|\.|-)+

That is, letters, slashes, dots and hyphens, in whatever order you want. Note that there are some reserved words, that vary between configuration files.

On the other hand, constants come in three flavours:

Plain
The same as properties.
Single quoted constants
Whatever you want to put between single quotes, including (but not limited to ;-)) single quotes, as \.
Double quoted constants
Whatever you want to put between double quotes, including double quotes, as \".

Please note that the difference between single and double quotes is purely aesthetic. Just a last note: everything is case-sensitive in every configuration file!

3.2  The Perl PreProcessor

This PICA component is the one that reads your files first, to transform them into what PICA will really read. In fact, is a Perl sub (well, two), not an independent program or CPAN module or something. The idea is being able to change (in a general and efficient way) the configuration files, depending on variables (yes, local variables) and some other checks. All of that, using arbitrary Perl expressions, that can not only return boolean values for conditions, but also generate part of the configuration or distribution files.

As the preprocessor is used on every PICA configuration and distribution file, the results become terribly dynamic. Imagine generating a configuration file for your servers, based on the name of the host, the name of the final file to be installed, the time of the day or some other external file or condition! You have all the power of Perl in your hands!

The directives recognized by PPP are:

To support your nifty conditions, there are sub definitions (actually, only two, ingroup and members) and some variables ($picahost and $picaobject, only defined for objects.conf; more on that later). Subs are defined in user.pm, a special module to put all of that stuff, placed in the PICA directory, usually /var/lib/pica. The user is supposed to modify that file if he wants to add a new function. The current list of defined subs is:

ingroup
Takes one argument and returns true if the current processing host (that is, picahost) belongs to the given group.
members
Takes one argument, and returns the list of members of the given group, or "" if there aren’t any.

To add a function, you have to write it in user.pm and add it to the EXPORT and EXPORT_OK variables. Moreover, if you want to access a new variable, you’ll have to make a glob to see it and be able to modify it’s value. You can copy and paste the current subs and globs.

3.3  pica.conf

This configuration file defines some paths needed by PICA. It’s a defaults environment with some definitions. There is one special definition, protecteddirs, with a list of directories never to be deleted, under any circumstances (this list is checked every time PICA is about to delete some directory recursively). Here’s a pica.conf sample file:

defaults {
   picaroot  = /var/lib/pica;               # config files
   picatmp   = /var/lib/pica/tmp;
   picasrc   = /var/lib/pica/src;           # distribution files
   picainclude = /usr/lib/pica/include;

   sshpath   = '/usr/local/bin/ssh '; # ssh binary
   diffpath  = '/usr/bin/diff'; # diff binary for -f command
   tarpath   = '/bin/tar';      # tar binary
   rsyncpath = '/usr/local/bin/rsync';

   protecteddirs {
      /,
      /bin,
      /usr/bin,
      /lib,
      /usr/lib,
      /var/lib/pica
   }
}

I hope all of this is self-explanatory.

3.4  hosts.conf

It is used to configure the hosts that should be administered using PICA. We can organize the hosts in different, possibly overlapped, groups that can be later used in conditions, so we could install a given file only in hosts belonging to a given group. We can also define variables for a given host and use them later. We also can specify different values for an object variable depending on the group we are working on by calling the ingroup sub.

Note that every host should be “declared” for PICA to know about it. It’s a way to try to prevent you from shooting yourself in the foot.

A simple example of the hosts.conf file could be the following:

defaults {
   vars {
      ## ---- User defined variables ----
      docdir  = '/home/httpsd/html/red';
   }
}

##
## Hosts Definitions
##
host machine3;
host machine2 {
    vars {
       var = 'this variable sucks';
    }
}
host machine1;
host machine4;
host machine5;
host machine6;
host machine7;
host machine8 {
    fqdn = machine8.otherdomain.net;
}

###########################
# Host Group Definitions  #
###########################

##
## Group Definitions
##

## Servers
hostgroup servers {
    members { machine2, machine1, machine4, machine7, machine5, machine6 }
}

## RedHat Linux Servers
hostgroup redhat {
    members { 
        machine2, machine1, machine4, machine5, machine6
    }
}

## Debian Linux Servers
hostgroup debian {
    members { 
        machine8
    }
}

#####################
# Mail servers
#####################
## No relay
hostgroup mailmaster {
    members { machine2, machine1, machine4 }
}
## Mailing lists servers
hostgroup listservers {
    members { machine4 }
}
## Main domain server
hostgroup ulpgcmaster {
    members { machine4 }
}

################
## DNS Servers
################
hostgroup dnsservers {
    members { machine2, machine1, machine4, machine5, machine6 }
}
hostgroup dnsmaster {
    members { machine5, machine6 }
}

################
## NTP Service
################
## Stratum-2
hostgroup stratum2 {
    members { machine2, machine1, machine4, machine5, machine6, machine7 }
}

##
## GSM server
##
hostgroup sms {
    members { machine5 }
}

################
## Misc services
################
hostgroup imapservers {
    members { machine4 }
}
hostgroup popservers {
    members { machine4 }
}
hostgroup simapservers {
    members { machine4 }
}
hostgroup tftpservers {
    members { machine4 }
}
hostgroup ftpservers {
    members { machine4 }
}
#######################
## Some networks
#######################
hostgroup net1 {
    members { machine2, machine4, machine7 }
}
hostgroup net2 {
    members { machine1 }
}
hostgroup net3 {
    members { machine5, machine6 }
}
#########################################
## Documentation hosts
#########################################
hostgroup doc {
    members { machine5, machine6 }
}

Whoa! What a giant file. Well, perhaps you have noticed under all this mess that hosts (not hostgroups) can have attributes, such as “fqdn”. This way we can specify host information such as the name PICA will use to create the secure connection. The list of possible host attributes is:

fqdn
As we already said, it sets the name PICA will use to connect to the host. If we don’t specify it, PICA will use the host identifier (yes, the word after the reserved word “host”). This attribute is useful if you have hosts in different domains and don’t want to use the FQDN for the host definition. We can also define which user we want to connect as for a particular machine, with the “sshuser” attribute.
method
Is the method used to copy files to the host. Its possible values are “ssh” and “tar”. It will be discused later, in page ??.
shellcmd
Is an attribute that specifies the complete command used to connect to the remote host. It uses the variables $sshargs and $cmd, which will be interpolated by the ssh arguments and the command to be executed, respectively. It defaults to “$sshpath \$sshargs picasshuser@$picafqdn $cmd”.
sshuser
The user we will connect to the machine with. It’s usually root, but for some machines we would want to change the default.
defpathdir
Default path to install, for the objects with relative “source” attribute values and no “path” attribute.

One very important thing to note here is that there are some special values in the hosts.conf defaults environment. These variables point to important directories in the remote machines1. We would like them to change in a per-host basis, but, by now, they are “global”. Of course, chances are this will change sometime in the future.

The list of special values is:

picaalarms
Directory where the alarms reside. In fact, directories with the name of the different priorities are created, and the alarms really reside there.
picabin
Directory where misc binaries will be put, as scheduler.
picalib
Directory for collections of things.
picaobj
Directory for objects used by alarms, mostly.

Just one last note: it is possible to specify hostgroups in the “members” attribute of a hostgroup, so you can build hostgroup hierarchies. It’s very useful if you have a group like “DNS servers” and subgroups like “Windows DNS servers” and “Linux DNS servers” (i.e.: perhaps you want to treat all DNS servers at once for some things, and separately for other things).

3.5  objects.conf

This one defines all the objects that will be distributed using PICA, and depends on the current host. In general, one can include or generate dynamically parts of it, depending on evaluations of previously defined variables. The variables available at this time for the PPP will be:

  1. Variables defined in the hosts.conf “defaults” environment
  2. Variables defined in the objects.conf “defaults” environment
  3. Variables defined in any of the groups which the current host belongs to
  4. Variables defined in the current host

The latter, of course, have preference in case of multiple definition. We also can use the internal variable $picahost to get the name of the current host. Because of that, the possibilities explode here: we can write entire Perl scripts (or in other languages, as far as we call them from Perl) to dynamically generate out configuration files on the fly, depending on defined variables, the day of the week, or whathever condition we can imagine. And here resides the power of PICA.

The mandatory and optional attributes for the two types of objects are:

For any of these attributes we can define default values in the “defaults” environment (see example).

A simple objects.conf file could be:

## Default values
defaults {
      uid = 0;
      gid = 0;
      perms = 644;
      verbatim = 0;
      vars {
         globalvar1 = 'value1';
      }
}

file motd {
    path = '/etc/motd';
    source = 'Services/Info/motd';
}

##################################
# Configuration for Service: NTP #
##################################
group NTP {
    file ntp.conf {
       path = '/etc/ntp.conf';
       source = 'Services/NTP/ntp_conf.cfg';
    }
    file step-tickers {
       path = '/etc/ntp/step-tickers';
       source = 'Services/NTP/step-tickers.cfg';
    }
    ##
    ## Documentation for this Service
    ##
#if (ingroup('doc'))
    file README.ntp {
       path = '<#$docdir#>/Services/NTP/README';
       source = '<#$picasrc#>/Services/NTP/README';
    }
#fi
}

##################################
# Configuration for Service: DNS #
##################################
#if (ingroup('dnsservers'))
group DNS {
    file named.conf {
         path = '/etc/named.conf';
         source = 'Services/DNS/named_conf.cfg';
    }
    ##
    ## Documentation for this Service
    ##
#  if (ingroup('doc'))
    file README.dns {
       path = '<#$docdir#>/Services/DNS/README';
       source = 'Services/DNS/README';
    }
#  fi
#fi
}

## DNS check
alarm DNSChkUrgent {
    priority = 'Urgent';
    source = 'alarms/DNSChk';
    perms = '755';
    uses {
        file dnschk.conf {
            source = 'alarms/conf/dnschk.conf';
            path = '<#picaobj#>/conf/dnschk.conf';
        }
    }
}

We also have a defaults section that will be seen from any object, and we can also define variables that will only be seen by the object they are defined in.

Anytime PICA operates with an object, it will build a namespace containing all the variables seen by that object in the host it is working on. Of course, the most specific definition has precedence. That is, if we define a variable in an object, and that object belongs to a group where the same variable is also defined, the value used is the one given in the object definition. In addition to these variables, we always have available $picahost and $picaobject, which hold the current host and object we are processing.

As a side note, since pica 0.3.6, files that happen to be directories are copied recursively, but treated verbatim (that is, no preprocessing is done on any file).


Previous Up Next