In some cases you will want to run cfengine on a system to configure it
from scratch. If the system is in a very bad way, it might not even be
able to parse the cfengine configuration file, perhaps because the
network was not properly configured or the DNS (Domain Name Service) was
out of action. To help prevent this situation, cfengine looks for a
script called cf.preconf
which gets executed prior to parsing and
can be used to perform any emergency tests. This file needs only
contain enough to get the system to parse the configuration files.
cf.preconf
may be any script in any language. It need not exist
at all! It is fed one argument by cfengine, namely the system hard-class
for the current system (e.g. ultrix
). Here is an example:
#!/bin/sh # # cf.preconf is an emergency/bootstrap file to get things going # in case cfengine is unable to parse its config file # backupdir=/iu/nexus/local/iu/etc # # If these files don't exist, you might not be able to parse cfengine.conf # if [ ! -s /etc/resolv.conf ]; then echo Patching basics resolv.conf file cat > /etc/resolv.conf << XX domain iu.hioslo.no nameserver 128.39.89.10 XX fi # # SVR4 # if [ "$1" = "solaris" ]; then if [ ! -s "/etc/passwd" ]; then echo Patching missing passwd file /bin/cp $backupdir/passwd /etc/passwd fi if [ ! -s "/etc/shadow" ]; then echo Patching missing passwd file /bin/cp $backupdir/shadow /etc/shadow fi fi # # BSD 4.3 # if [ "$1" = "linux" ]; then if [ ! -s "/etc/passwd" ] then echo Patching missing passwd file /bin/cp $backupdir/passwd.linux /etc/passwd fi fi
If, for some reason you are not satisfied with the defaults which
cfengine uses, then you can change them by making an entry in the
resource file. The default values are defined in the source code file
classes.c
in the distribution. The format of the resource file
is:
hardclass.variable: value
For example, you might want to forget about where your HPUX system
mounts its mail directory and mount it under /usr/spool/mail
. In
this case you would add the line:
hpux.maildir: /usr/spool/mail
To redefine the filesystem table for GNU/linux, you would write:
linux.fstab: /etc/linuxfstab
The full list of re-definable resources is:
mountcomm # command used to mount filesystems unmountcomm # command used to unmount filesystems ethernet # name of the ethernet device mountopts # options to above mount command fstab # the name of the filesystemtable maildir # the location of the mail directory netstat # the full path to netstat and options pscomm # the path to the system's ps command psopts # the options used by ps (default aux/ef)
You should never need to redefine resources unless you decide to do something
non-standard. Interested readers are referred to the values in classes.c
.
Cfengine is easily extensible so as to support a variety of architectures. You can even add your own. To do so you need, first of all, to define a new class for the operating system concerned. The file classes.c has been separated off from the remainder of the source code so that you can easily see which data structures need to be extended.
To make life as straightforward as possible, three unused classes have been defined. They are called (unremarkably) unused1, unused2 and unused3. If you add any further classes, it will be necessary to increase the constant clssattr defined in cf.defs.h by one for every new addition. You do not need to change clssattr if you simple replace one of the unused classes by a real class.
To see fully the impact of what you need to do, you should make a search for the strings unused? in all of the source files. Certain special cases need to be handled for each operating system. For example, the form of the filesystem table is quite radically different on some systems such as AIX. One thing you must do is to fill in the default values for the new operating system in the file classes.c.
If you fill in the details for a new operating system before it finds its way into a new release, you might consider sending the details to the bug list in the next paragraph.
Although every effort has been made to make the compilation of cfengine trouble free, you might still encounter some problems where non-standard features are concerned. The differences between systems is still a major headache.
Earlier versions of the GNU/Linux operating system do not have support
for some of the facilities which cfengine uses. In particular, the
ability to use NIS netgroups is absent from earlier versions. During
the installation procedure, the configure
script tests for this
possibility and advises you if the facility cannot be used. You can
still use cfengine in this case but netgroups will not be expanded.
Another problem with GNU/Linux concerns a special socket call to the
TCP/IP network interface. This is a command which configures the static
routing table and appears to be absent from all versions of Linux and
newer IRIX versions. There are also problems with NetBSD. These
features are undocumented and will be fixed as soon as they have been
understood! If you are running in verbose mode a warning message is
printed, otherwise cfengine will ignore attempts to set a default route
on the system.
A number of users have experienced a problem using flex and bison in place of lex and yacc. There appears to be a bug in one of these programs which causes cfengine to compile correctly but misinterpret its configuration files, generating an error of the form
cfengine:10:action contains invalid statement
for every line! The cure is to collect the latest versions of flex and bison from your nearest GNU site.
On really old systems, the configure program is not able to guess what kind of system you are working on. This is true of SunOS versions 4.0.* and also of BSD 4.3 systems. In such cases, you might be able to compile cfengine by using the autoconf option `host' to specify the host-type.
configure --host=sparc-sun-sunos4.0
Some other systems which will compile if forced are:
m68k-hp-bsd4.3 ?-?-bsd4.3 romp-ibm-aos ?-?-aos
On some systems, problems arise when using flex. Flex might generate a lexer file lex.yy.c which defines malloc or some other function to be of a type which conflicts with the system definition. If you obtain such a culture crash, edit the lexer file manually and simply delete the offending definitions, then run make again.
As of version 1.4.0 cfengine tries to link in features based on the Berkeley database library `libdb' and the TCP wrappers library `libwrap'. If you want to use these facilities, you will have to collect them and install them before compiling cfengine. Some problems have been experienced with the linux version of TCP wrappers. If you experience compilation problems, the best thing to do is to edit `src/conf.h' after configuration and remove the line beginning `#define HAVE_LIBWRAP'.
Newer solaris systems have ACLs. The ACL features only matured in version 2.5 of solaris however, and there have been some problems with the partial implementation in 2.4. If you obtain error messages about unknown ACL functions, edit the `config.cache' file in the cfengine root directory and set the value:
ac_cv_header_sys_acl_h=${ac_cv_header_sys_acl_h='no'}
If you use the DCE (Distributed computing environment) cfengine will try to compile the ACL extension for DFS. This requires the DCE library to be present on the system on which you are compiling. On some systems it also requires thread libraries to be present. Unfortunately, the autoconf program which generates the Makefiles cannot detect shared libraries, only archive libraries. This means that you need to edit the `config.cache' file to compile in this support. Set the following values:
ac_cv_lib_dce_main=${ac_cv_lib_dce_main='yes'} ac_cv_lib_dce_main=${ac_cv_lib_thread_main='yes'}
Finally, although the autoconfiguration program appends the same libraries to each executable, the following libraries are required only by the following programs.
cfengine -ldce -lthread -lm cfd -ldb -lpthread
If you experience a problem with cfengine, find a bug or have another suggestion which you wish to air, you can send your thoughts to the special mail address [email protected].
Always think a bit before sending a message to the list. This helps to keep down the traffic improves the signal to noise ratio of your thoughts! Try to solve the problem yourself first and look particularly to see whether your system is clean or whether you have installed software or patches which might conflict with cfengine (I can't really imagine how this would happen--but it might). Always be clear about what type of operating system you are running and whether or not it is a complete installation.
Some vendors have begun the practice of distributing systems without key programs like the C compiler, lex and yacc. If you have this problem, you can pick up GNU replacements gcc, flex and bison from any GNU site.
Here is a problem solver: an encyclopaedia of suggestions and uses for cfengine as accumulated over the years. If you have a contribution to make, please send it to [email protected]. Format your submission like this:
The table below is updated as the tips occur to me, or as others contribute their own. Please note that any focusing on particular operating systems is purely a matter of personal usage/experience and should not be interpreted as a reflection of how many `bugs' these systems may or may not contain.
cfengine -p -d3This just parses the file and dumps the contents of the parser to the output.
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}.
links: /usr/lib/sendmail ->! /local/mail/bin/sendmail /etc/sendmail.cf ->! /local/mail/etc/sendmail.cf
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=1An 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.
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" }
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
processes: # # Most users # "eggdrop" signal=kill # # One wise-guy has renamed the daemon! # ".*wiseguy.*myegg.*" signal=kill
processes: # # BSD - often need long descriptive lines # to find this daemon # SetOptionString "-ax" # Exactly one should be running "lmgrd" matches=1
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)"
editfiles: { home/.cshrc # Local fixes AppendIfNoSuchLine "alias lp special-print-command" # Security DeleteLinesMatching "xhost +" }
processes: "\(root\)\{0\}" signal=term # or kill
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 }
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'.
control: person = ( new-user ) editfiles: { /etc/group BeginGroupIfNoLineMatching "adm.*$(person).*" LocateLineMatching "adm.*" AppendToLineIfNotContains ",$(person)" EndGroup }
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=silentfor each partition you want to back up.
*.lnk
to the list of files to be excluded during
the copy.
# 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'.
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 ...
ld: 0711-317 ERROR: Undefined symbol: .pthread_sigmask ld: 0711-317 ERROR: Undefined symbol: .pthread_mutex_init ld: 0711-317 ERROR: Undefined symbol: .pthread_mutex_lock ld: 0711-317 ERROR: Undefined symbol: .pthread_mutex_unlockon AIX 4.2
% ./configure loading cache ./config.cache checking host system type... i386-pc-bsdi3.1 checking target system type... i386-pc-bsdi3.1 checking build system type... i386-pc-bsdi3.1 expr: syntax error, last argument was `' test: syntax error: Undefined error: 0 expr: syntax error, last argument was `' test: syntax error: Undefined error: 0 expr: syntax error, last argument was `' test: syntax error: Undefined error: 0 checking whether make sets ${MAKE}... (cached) yes checking for gcc... (cached) gcc checking whether the C compiler (gcc ) works... yes checking whether the C compiler (gcc ) is a cross-compiler... no ...
To correct this for BSDI I replaced the following script fragment from configure: ------------------------------------------------------------------------- # # Add to the default list of places in LDFLAGS to compensate for # ... the configure default value of LIBS on some systems # for x in /usr/local/gnu/lib /usr/local/gnulib /usr/local/lib /usr/lib /lib do if test -d "$x"; then y=`expr match "$LDFLAGS" ".*-L$x"` if test $y -eq 0; then LDFLAGS="$LDFLAGS -L$x" fi fi done # # Add to the default list of places in CPPFLAGS to match LDFLAGS above # for x in /usr/include /usr/local/gnu/include /usr/local/include do if test -d "$x"; then y=`expr match "$CPPFLAGS" ".*-I$x"` if test $y -eq 0; then CPPFLAGS="$CPPFLAGS -I$x" fi fi done ------------------------------------------------------------------------ With this script fragment, which successfully executed: ------------------------------------------------------------------------ # # Add to the default list of places in LDFLAGS to compensate for # ... the configure default value of LIBS on some systems # for x in /usr/local/gnu/lib /usr/local/gnulib /usr/local/lib /usr/lib /lib do if test -d "$x"; then case $LDFLAGS in .*-L$x) LDFLAGS="$LDFLAGS -L$x" ;; esac fi done # # Add to the default list of places in CPPFLAGS to match LDFLAGS above # for x in /usr/include /usr/local/gnu/include /usr/local/include do if test -d "$x"; then case $CPPFLAGS in .*-I$x) CPPFLAGS="$CPPFLAGS -I$x" ;; esac fi done ----------------------------------------------------------------------- I have not completed compiling, installing, testing yet, but presume I should be fine from here. Thanks for the help. -Jeff ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Jeff Reed Berkeley Software Design, Inc. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
hpux10
rather than
hpux
.
disable: hpux:: /usr/lib/sendmail.fc
links: hpux:: /etc/logingroup -> /etc/group
#!/usr/local/bin/cfengine -f #################################################### # # File: sendmail.conf # # Description: CFEngine script to setup the sendmail.cf. # #################################################### control: access = ( root ) # Postmaster sysadm = ( myPostmaster ) # NIS domain and group server site = ( myserver ) # DNS domain domain = ( myDNSdomain ) # our gateway host gtwyhost = ( mygateway ) # sendmail.cf can be big editfilesize = ( 1000000 ) actionsequence = ( copy files editfiles shellcommands ) # disable unwanted classes with "--undefine" option addclasses = ( maildom mailhst ) ################ # bindir - location of sendmail # libdir - location of current mail files # cfgdir - location of initial mail files # etcdir - location of hosts.smtp # own - who should own result files # grp - what group should result files be in ################ hpux:: bindir = ( /usr/lib ) libdir = ( /usr/lib ) cfgdir = ( /etc/newconfig ) etcdir = ( /etc ) own = ( root ) grp = ( sys ) hpux10:: bindir = ( /usr/sbin ) libdir = ( /etc/mail ) cfgdir = ( /usr/newconfig/etc/mail ) etcdir = ( /etc ) own = ( root ) grp = ( sys ) # disable with "--no-copy" option copy: $(cfgdir)/sendmail.cf dest=$(libdir)/sendmail.cf type=checksum mode=0644 owner=$(own) group=$(grp) force=true # checks for other important files files: $(libdir)/aliases mode=444 owner=$(own) group=$(grp) action=touch $(libdir)/rev-aliases mode=444 owner=$(own) group=$(grp) action=touch $(etcdir)/hosts.smtp mode=444 owner=$(own) group=$(grp) action=touch # disable with "--no-edit" option editfiles: any:: # setup general part of sendmail.cf { $(libdir)/sendmail.cf SetCommentStart '#' SetCommentEnd '' ResetSearch "1" UnCommentLinesMatching "#OP.*" # activate Postmaster ResetSearch "1" UnCommentLinesMatching "#DY.*" ResetSearch "1" LocateLineMatching "DY.*" ReplaceLineWith "DY$(site).$(domain)" # set site hiding ResetSearch "1" UnCommentLinesMatching "#DS.*" ResetSearch "1" LocateLineMatching "DS.*" ReplaceLineWith "DS$(gtwyhost)" # all-knowing SMTP host # Ruleset 0 setups ResetSearch "1" UnCommentLinesMatching "#R.*user@domain to SMTP relay.*" ResetSearch "1" LocateLineMatching "# try to connect to any host for user@domain" IncrementPointer "1" CommentNLines "1" } # add Postmaster alias { $(libdir)/aliases SetLine "Postmaster: $(sysadm)" AppendIfNoLineMatching "Postmaster.*" } # setup processing of local domain hosts maildom:: { $(libdir)/sendmail.cf SetCommentStart '#' SetCommentEnd '' ResetSearch "1" LocateLineMatching "DL.*" ReplaceLineWith "DL$(domain)" # Ruleset 0 setups ResetSearch "1" LocateLineMatching "# connect to hosts in local domain" IncrementPointer "1" UnCommentNLines "1" } # setup processing via class S mailhst:: { $(libdir)/sendmail.cf SetCommentStart '#' SetCommentEnd '' ResetSearch "1" UnCommentLinesMatching "#FS.*" # Ruleset 0 setups ResetSearch "1" LocateLineMatching "# connect to hosts in class S" IncrementPointer "1" UnCommentNLines "1" } # setup of list of hosts for class S { $(etcdir)/hosts.smtp EmptyEntireFilePlease Append "localhost1" Append "localhost2" } # disable with "--no-commands" option shellcommands: "$(bindir)/sendmail -bk" "$(bindir)/sendmail -bi" "$(bindir)/sendmail -bz" "$(bindir)/sendmail -bd" ################ # End of File ################
cfd
I get this error
/usr/lib/libwrap.a(options.o): In function `twist_option': options.o(.text+0x5f7): undefined reference to `deny_severity' /usr/lib/libwrap.a(options.o): In function `severity_option': options.o(.text+0x808): undefined reference to `deny_severity' options.o(.text+0x81c): undefined reference to `deny_severity' options.o(.text+0x821): undefined reference to `deny_severity' options.o(.text+0x826): undefined reference to `deny_severity' options.o(.text+0x82b): undefined reference to `allow_severity' make[1]: *** [cfd] Error 1
editfiles: linux:: { /etc/rc.d/rc.S HashCommentLinesContaining "motd" }
editfiles: sun4:: { /etc/hosts.equiv DeleteLinesMatching "+" }
# # rc.local # PATH=/local/gnu/bin:/bin:/usr/bin:/usr/sbin; export PATH #!/bin/sh if [ "`hostname`" = "net-server" ]; then echo Starting WWW server /local/httpd_1.4/httpd -d /local/httpd_1.4 echo Starting GNU finger server /local/etc/fingerd fi echo Starting ypbind /usr/lib/netsvc/yp/ypbind echo Adding a default route and flushing table route -f add default my-gateway 1 echo Starting xdm /local/bin/start-xdmNow add an entry to your `cfengine.conf' file like this
solaris:: { /etc/rc3.d/S99rc-local AutoCreate AppendIfNoSuchLine "exec sh /local/etc/rc.local" }
files: /tmp mode=1777 action=fixdirs
editfiles: { /etc/shells AppendIfNoSuchLine "/local/bin/tcsh" }
tcsh
prints an error message on startup and will not read my
`.cshrc' file.
disable: /etc/.login type=fileYou might want to replace this with a link to your own file.
files: solaris:: /etc/defaultrouter o=root g=other m=644 act=touch editfiles: solaris:: { /etc/defaultrouter AppendIfNoSuchLine "xxx.xxx.xxx.1" }where
xxx.xxx.xxx.1
is the IP address of your gateway.
files: /etc/system o=root g=root m=0644 action=touch
$(root)/filenameand set
$(root)
to ""
or "/a"
depending on context?
That way you could the above without screwing up other things which
might be needed. You can switch off the locks with -K
. And you
could override the `vfstab' location for solaris in the resource file.
freebsd:: { /etc/crontab HashCommentLinesContaining "daily" HashCommentLinesContaining "weekly" HashCommentLinesContaining "monthly" }
Go to the first, previous, next, last section, table of contents.