Go to the first, previous, next, last section, table of contents.


General

Q:
How can I check to see what cfengine will do without going through the whole program using `-n'?
A:
Run cfengine with options:

  cfengine -p -d3

This just parses the file and dumps the contents of the parser to the output.
Q:
Why doesn't cfengine have classes for each hour, instead of just for days?
A:
It does from version 1.3.20 and upward. The hours are denoted in 24 hour clock notation by Hr00---Hr23. Other time classes are also possible @xref{Using cfengine as a front-end for cron,Using cfengine as a front-end for cron,Using cfengine as a front-end for cron,cfengine-Tutorial}.
Q:
How can I replace the stupid version of sendmail my vendor ships with my OS with, say, Berkeley sendmail?
A:
First of all, compile your new sendmail in a filesystem which is held separate from the OS, for example `/local/mail'. You can keep all the files under this new file tree. Now you need to replace `/usr/lib/sendmail' with the new version and `/etc/sendmail.cf' or `/etc/mail/sendmail' with the new files, so that the system can find them.

   links:
      /usr/lib/sendmail ->! /local/mail/bin/sendmail
      /etc/sendmail.cf  ->! /local/mail/etc/sendmail.cf

Q:
How can I prevent big log-files like `/var/adm/wtmpx' and `httpd/access_log' from filling up my partitions?
A:
Add a line to disable the files once a week. That way you still get a chance to look at them, but you keep the size down:

   disable::

      Sunday::

         #
         # Do this to throw away old entries
         #

         /var/adm/wtmpx rotate=truncate

         #
         # Or this to keep the last lot
         #

         /var/adm/wtmpx rotate=1

An alternative to using disable would be to use tidy, but then you lose the file once and for all. Note though, that `wtmpx' gets updated all the time, so an age age=0 is necessary to have any effect at all. Some daemons, like `httpd', lose their ability to write to a log file if you rename and create a new file. The rotate feature in cfengine preserves the open file handle, fixing this problem.
Q:
How can I fix exports in cfengine?
A:
This is a complicated matter. There are lots of ways to do it. The key is either to edit the file `/etc/exports' (`/etc/dfs/dfstab' in solaris), or to execute an export (share) command directly from shellcommands. Under Solaris 2 this is quite easy owing to the fact that the file `dfstab' is just a script itself, rather than a configuration file like the old `/etc/exports' file. Since editing is limited and you need to specify a list of hosts which might change in time, one of the following is probably the best bet:

shellcommands:

   solaris::

      "/usr/sbin/share -F nfs -o rw=netgroup /var/mail"

On non-solaris systems:

editfiles:

   { /etc/exports

   AppendIfNoSuchLine "/site/host/fs -access=netgroup"
   }

Q:
How can I distribute key setup files to users and keep them up to date?
A:
The copy facility will distribute to all users if you use the home directive. For instance, to copy a basic `.cshrc' file or `.xsession', you could write

copy:

   /local/masterfiles/.cshrc     dest=home/.cshrc
   /local/masterfiles/.xsession  dest=home/.xsession

Q:
Some users set up their own IRC listen services called "eggdrop" which fill up the disk with all kinds of garbage. How can I kill all these processes?
A:

processes:

  #
  # Most users
  #

  "eggdrop"  signal=kill

  #
  # One wise-guy has renamed the daemon!
  #

  ".*wiseguy.*myegg.*"  signal=kill

Q:
My license server keeps crashing! How can I check that it's ok?
A:

processes:

  #
  # BSD - often need long descriptive lines
  #       to find this daemon
  #

  SetOptionString "-ax"

  # Exactly one should be running

  "lmgrd" matches=1

Q:
I want to use cfengine to keep DNS tables up to date, using editfiles. How can I make cfengine automatically restart the name server after the edits?
A:
This can be done in two ways. Probably, you need to update a serial number as well as restarting the daemon. You might use a Makefile to simplify this.

control:

  actionsequence = ( editfiles control )

  solaris::
           named = ( /usr/sbin/in.named)
  linux:
  freebsd:
           named = ( /usr/sbin/named )
  sun4:
           named = ( /usr/etc/named )

editfiles:

 # edit files here

shellcommands:

   #
   # If you use make to sort out the details
   #

  "/local/gnu/bin/make -f /local/named/Makefile > /dev/null"

Or if you need to explicitly restart the name daemon, you could supplement the above with an explicit restart command (this means you lose the cache),

processes:

  "named" signal=kill restart "$(named)"

Q:
How can I edit all users' login files?
A:
You can use the 'home' pseudo-variable to iterate over all users' homedirectories:

editfiles:

    { home/.cshrc

    # Local fixes

    AppendIfNoSuchLine "alias lp  special-print-command"

    # Security

    DeleteLinesMatching "xhost +"
    }

Q:
How can I kill all processes except for root processes?
A:
The following regular expression matches lines which do not contain the string root:

processes:

 "\(root\)\{0\}"  signal=term # or kill

Q:
How can I make cfengine distribute my `/etc/motd' file?
A:
You will need a master file which contains the text you want to put on your servers. Let us define a variable `masterfile' which contains this. This master file needs to be available on all hosts on a common NFS filesystem, for instance. (This will change when remote copying is implemented in cfengine.) Now you can do something like the following script. Note that we define a version number for motd which just prevents cfengine from editing the file every single time. You have to change this version number yourself in the config file to force an update. If you don't care about this, just leave out the Begin..End parentheses.

control:

masterfile = ( /usr/local/admin/motd-master )

editfiles:

  any::

     { /etc/motd

     BeginGroupIfFileIsNewer "$(masterfile)"
       EmptyEntireFilePlease
       InsertFile "$(masterfile)"
       PrependIfNoSuchLine "This system is running $(class):$(arch)"
       AppendIfNoSuchLine "$(motd_version)"
     EndGroup
     }

Note that, if you want special messages added just for, say, linux, then you can single out linux using a special class, or add a special edit after this one. Note, if you want to keep the first kernel line in this file, you can change this to:
editfiles:

   any::

   { /etc/motd

   BeginGroupIfFileIsNewer "$(masterfile)"
     IncrementPointer "1"
     DeleteLinesAfterThisMatching ".*"
     InsertFile "$(masterfile)"
     AppendIfNoSuchLine "$(motd_version)"
   EndGroup
   }

bug-cfengine exchange: (Reply courtesy of David Masterson).
I like cfengine a lot and it helps me very much, but I am a little concerned about security. I'm using cfengine to keep some files like /etc/hosts /etc/printcap /etc/mount etc. up to date. So cfengine is started by root in a cron job and reads its cfengine.conf file and all the other information from a filesystem which is common to all the systems. If now somebody manage to alter the cfengine.conf file he can do everything he wants. Wouldn't it be a good idea to make the cfengine.conf file something like a pgp signed messages, so that cfengine can test if this file was created by the right person? Or are there other tips to make it more secure? I'm not sure, but I think you're over-reacting or you need to be more specific about where you think the holes are in Cfengine's security. If you follow the tips of any standard systems administrator using cfengine or not, there should be few issues concerning security (ie. if security broke, there would be little chance that cfengine could do anything about it anyway). Ask yourself some of the standard questions with respect to security on UNIX: If you're still worried about the security of your script (be it a cfengine script or not), you could always adjust your cron script to "decrypt" the script file before executing it (see crypt(1)). Personally, I think if you've set the permissions on your script files properly, then, if someone breaks into those scripts, they've already broken into your system to a point where they could do what they wanted anyway.
Q:
How can I distribute password files in cfengine, but keep certain passwords different on some machines, like I can with NIS?
A:
If you keep a file with special local passwords, you can override the password file using editfiles. First you use copy to get the distributed file, then you edit the file like this:

  editfiles:

    { /etc/passwd

    SplitOn ":"

    ForEachLineIn "/usr/local/etc/passwd.local"

       ReplaceLinesMatchingField "1"

    EndLoop
    }

This means, if the first field of each line in the files matches in both files (and both files have the same column format) then replace the line in `/etc/passwd' with the line from `/usr/local/etc/passwd.local'.
Q:
How can I add entries to a list, like in the fiel `/etc/group'?
A:
Okay, suppose you wanted to make sure that a special user was in the group `adm', you would use a construction like this:
  control:

      person = ( new-user )

  editfiles:

   { /etc/group

   BeginGroupIfNoLineMatching "adm.*$(person).*"
     LocateLineMatching "adm.*"
     AppendToLineIfNotContains ",$(person)"
   EndGroup
   }

Q:
How can I take backups with cfengine?
A:
If you have a spare disk partition, you could make a mirror of the most important files. You would use something like this:

 control:

      excludecopy = ( *.mp3 *.o *.dvi *.ps *.zip *tar* *.lnk
                       core a.out *.au *.wav .* *.exe *.tgz )

 copy:

   BackupHost.Hr21::

     /site/host/home dest=/site/host/backup2/u1 r=inf size=<4mb backup=false action=silent

for each partition you want to back up.
Q:
I am using SAMBA and have windows file system data on my unix machine. When I try to make a backup by remote copying files, cfengine goes into a recursive loop when it meets short cuts.
A:
Short cuts do not seem to respect the unix file protocols. They look like directories to cfengine and this causes it problems since they do not parse like directories. Add *.lnk to the list of files to be excluded during the copy.
Q:
Is it possible to force shellcommands to change its working directory? separating the commands with ";" seems to be not possible. shellscripts should not be used for this purpose.
A:
(By Rolf Ebert, ebert@pe-muc.de ) I, too, have the need to pass variables to shellcommands and the shellcommands must be executed in a given directory. Here is how most of my shellcommands look like:
      # generate MMC configs
       '$(shell) "PUBLIC=$(public); export PUBLIC; cd $(public)/mmc/config; ./blinksrv.x.cfm.in > blinksrv.x.cfm"'
$(shell) is defined as '/bin/sh -c'. The actual script to be executed is `blinksrv.x.cfm.in' which is located in `$(public)/mmc/config'. It generates a file in the same directory. As an input parameter the script needs the environment variable `PUBLIC'.
Q: Using cfengine with the AFS.
We use AFS, therefore our directory structures look like this: `/afs/btv.ibm.com/system/current/rs_aix43/...' and so on. I want to build a cf file that can pull what AFS calls the "sysname" into the equation so I can have one cf file that can get data from the proper rs_aix directory depending on what level of AIX, or SUN for that matter, it happens to run on. If I use cfengine's class structure I would have to have a cf file for each AIX/SUN level rather than one that can handle them all. That is why I want exec to work. Can anyone offer an answer to this type of scenario?
A: Courtesy of Jeff Blaine
We reference @sys all the time in our cfengine files. It expands to the current machine's AFS sysname on the fly. It's part of AFS, use it!
control:
  #
  # ... stuff deleted ...
  #
  rcf_repos = ( /afs/whatever/our_admin_area/config )
  #
  # ... stuff deleted ...
  #

copy:

  # ... stuff deleted ...
  #
  #  SunOS 4 and IRIX automountd startup file to define /net -hosts
  #
  (sun4|irix|irix64)::
      $(rcf_repos)/@sys/etc/auto.master dest=/etc/auto.master mode=444 \
owner=root group=1 type=checksum
  #
  # ... stuff deleted ...


Go to the first, previous, next, last section, table of contents.