Let's write a very simple configuration for a network with only one server called hal, where all the hosts are of the same operating system type. In such an example we can avoid using classes altogether.
control: site = ( univ ) domain = ( univ.edu ) actionsequence = ( mountall mountinfo addmounts mountall links ) binservers: hal homeservers: hal mailserver: hal:/var/spool/mail mountables: hal:/univ/home1 hal:/univ/home2 hal:/univ/local links: /usr/local -> /univ/local
In this example, we have only one type of host so the configuration is the same for each of them: no class references are required. If we look through the action sequence we see that the program first mounts all the filesystems which are already defined on each host. It does this to be sure that everything which is already set up to be mounted is mounted. Let's assume that there are no problems with this.
The next thing that happens is that mountinfo
builds a list of
the filesystems which each host has successfully mounted. Then by
calling addmounts
we ask cfengine to check whether the host is
missing any filesystems. What happens is that cfengine first looks to
see what servers are defined for each host. In this case all hosts on
the network have only one server: hal. Hal is defined as a server for
both binary data and `home' data -- i.e. users' home directories. The
list mountables
tells cfengine what filesystems are available
over the network for the server hal. There are three filesystems which
can be mounted, called `/univ/home1', `/univ/home2' and
`/univ/local'. Cfengine checks to see whether each of these
filesystems is mounted and, if not, it builds the necessary directories,
edits the necessary files and mounts the filesystems.
Finally we come to links
in the action sequence. This tells
cfengine to look at the defined links. There is one link defined: a
link from `/usr/local' to the mounted filesystem
`/univ/local'. Cfengine checks and tries to make the link if
necessary. If all goes well, each host on the network should now have
at least three filesystems mounted and a link from `/usr/local' to
`/univ/local'.
Here is another simple example program for checking and automatically
mounting an NFS based /usr/local
and all home directories onto
all hosts on a small network. Here we have several servers and must
therefore use some classes.
# # Mounts # control: site = ( mysite ) domain = ( mysite.country ) sysadm = ( mark ) netmask = ( 255.255.255.0 ) actionsequence = ( mountall mountinfo addmounts mountall links ) mountpattern = ( /$(site)/$(host) ) homepattern = ( u? ) # u1 u2 u3 etc.. groups: MyGroup = ( host1 host2 binserver1 binserver2 ) ###################################################################### homeservers: MyGroup:: host1 binservers: MyGroup.sun4:: server1 MyGroup.ultrix:: server2 mailserver: host1:/usr/spool/mail mountables: host1:/mysite/host1/u1 host1:/mysite/host1/u2 server1:/mysite/server1/local server2:/mysite/server2/local ########################################################################## links: /usr/local -> /${site}/${binserver}/local
Let's suppose we run this program on host2 which is an ultrix machine.
This host belongs to the class mygroup
and the hard-class
ultrix
. This tells us that its homeserver is host1, its binary
server is server2 and its mailserver is host1. Moreover, since the
homepattern matches any filesystem ending in u-something, it recognizes
the two home directories in the mountables list -- and therefore the
two binary directories also.
The action sequence starts by mounting all of the filesystems currently in the filesystem table `/etc/fstab'. It then scans the list of mounted filesystems to find out what is actually mounted. Since the homeserver is host1, we know that our host has to mount all home-filesystems from this server, so it checks for `host1:/mysite/host1/u1' and `host1:/mysite/host1/u2'. If they are not present they are added to `/etc/fstab'(3). Next, we know that the binary server is server1, so we should check for `server1:/mysite/server1/local'. The mail server is also checked for and added if necessary. Cfengine then tries to mount all filesystems once again, so that the new filesystems should be added.
Note that, in the process of adding the filesystems to `/etc/fstab', cfengine creates the directories up to and including the point at which the filesystems should be mounted. If something prevents this -- if we try to mount on top of a plain file for instance --- then this will result in an error.
Finally, we reach the link section and we try to expand the variables.
$(site)
expands to `mysite'. $(binserver)
expands
first to the hostname (host2), but `/mysite/host2/local' does not
exist, so it then goes to the binserver list, which substitutes server1
for the value of $(binserver)
. Since
`/mysite/server1/local' does exist and is now mounted, cfengine
makes a link to this directory from `/usr/local'. The script is
then completed.
If the script is run again, everything should now be in place so nothing happens. If for some reason it failed the first time, it will fail again. At any rate it will either do the job once and for all or signal an error which must be corrected by human intervention(4).
Go to the first, previous, next, last section, table of contents.