help-cfengine
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: processing order, preprocessing, etc.


From: Wheeler, John
Subject: RE: processing order, preprocessing, etc.
Date: Sun, 22 Dec 2002 13:19:52 -0600

I wrestled with this problem myself, combed through the archives and read how a few others resolved this issue. My situation is probably a little unique in that all the hosts I support are solaris (well most anyway). After performing a similar analysis I finally came up with a method to resolve this problem that appears to satisfy most of your requirements.

My requirements were as follow:
1) scripts are restricted to sh/ksh
2) must not leave any package archives on host after install
3) must use solaris based package administration
4) must be able to push out software on demand

Its not quite the "cfengine way" but as close as I could get. it goes a little like this:

I have a file based database like this:

# more pkgs
sunos_5_8 add SMCzlib 1.1.4 zlib-1.1.4-sol8-sparc-local
sunos_5_8 add EBopenssl 0.9.6g openssl-0.9.6g-sol8-sparc
sunos_5_8 add EBopenssh 3.4p1 openssh-3.4p1-sol8-sparc
sunos_5_6 add SMCzlib 1.1.4 zlib-1.1.4-sol26-sparc-local
sunos_5_6 add EBopenssl 0.9.6g-eb1 openssl-0.9.6g-eb1-sol6-sparc
sunos_5_6 add EBopenssh 3.4p1_0.9.6g openssh-3.4p1-sol6-sparc
dev add EBxvfb X11R6.6 xvfb-6.6-sol6-sparc
cessna add EBcronolog 1.6.2 cronolog-1.6.2-sol8-sparc
web001prod add EBcronolog 1.6.2 cronolog-1.6.2-sol8-sparc
web002prod add EBcronolog 1.6.2 cronolog-1.6.2-sol8-sparc

<CLASS> <ACTION> <PKGNAME> <VERSION> <PKGFILENAME>

And a cfengine file as follows

# more installsoftware.conf

classes:
        copyfiles = ( FileExists(/var/cfengine/scripts/copyfiles) )
control:
        actionsequence  = (
                        copy.install
                        files.install
                        shellcommands.install
                        tidy.install
                        )
tidy:
        install.copyfiles::
                /var/cfengine/scripts
                        pattern=copyfiles
                        recurse=0
                        age=0

                /var/cfengine/software
                        pattern=*
                        recurse=0
                        age=0
files:
        install.copyfiles::
                /var/cfengine/scripts/copyfiles
                        mode=755
                        owner=root
                        action="">
copy:
        install::
                /cfengine/software/pkgs
                        dest=/var/cfengine/scripts/pkgs
                        type=checksum
                        define=checksoftware
                        server=$(masterhost)
shellcommands:
        install.checksoftware::
                '/var/cfengine/scripts/checksw $(allclasses)'

        install.copyfiles::
                '/var/cfengine/scripts/copyfiles'
                        define=installsoftware

        install.Hr00.!copyfiles::
                '/var/cfengine/scripts/checksw $(allclasses)'

        install.installsoftware::
                '/var/cfengine/scripts/installsw'

Basically how this works is that if the pkgs file database changes, all hosts check to see if they have something to install or remove. Remove is not implemented. If they have something to install, a file called copyfiles is created that uses cfengine to copy the file from a host running cfservd.

# more checksw
#!/bin/ksh
# Script expects classes passed to it in cfengine format
CLASSES=`echo $1|/usr/bin/awk -F= '{print $2}'|sed s/:/" "/g`

cmdline()
{
        echo "in cmdline"
        while getopts dc: c
        do
                case $c in
                        c) CLASSES=$OPTARG;;
                        d) DEBUG=1;;
                esac
        done
}

init()
{

        PKGS=/var/cfengine/scripts/pkgs
        ADDFILE=/var/cfengine/scripts/addsw
        RMFILE=/var/cfengine/scripts/rmsw
        SCRIPT=/var/cfengine/scripts/copyfiles
        DEBUG=
        DEBUG1=1
        # by default don't install sw
        INSTALLSW=1

        COPYSRC=/cfengine/software
        COPYDST=/var/cfengine/software
        MASTER=meriadoc
}

cleanup()
{
        [ $DEBUG ] && echo "in cleanup"
        if [ -f $ADDFILE ]
        then
                rm $ADDFILE
        fi
        if [ -f $RMFILE ]
        then
                rm $RMFILE
        fi
}
# Hard coded paths

init
cleanup

{
while read line
do
        [ $DEBUG ] && echo "Line:$line"
        PKGCLASS=$(echo $line|awk '{print $1}')
        for CLASS in $CLASSES
        do
                [ $DEBUG ] && echo "Checking pkgclass $PKGCLASS = cf $CLASS?"
                if [ "$PKGCLASS" = "$CLASS" ]
                then
                        [ $DEBUG ] && echo "$PKGCLASS = $CLASS"
                        PKGACTION=$(echo $line|awk '{print $2}')
                        PKGNAME=$(echo $line|awk '{print $3}')
                        PKGVERSION=$(echo $line|awk '{print $4}')
                        PKGFILE=$(echo $line|awk '{print $5}')

                        pkginfo -q $PKGNAME
                        if [ $? -eq 0 ]
                        then
                                [ $DEBUG ] && echo $PKGNAME installed
                                INSTVER=$(pkginfo -x $PKGNAME |awk '$0 ~ /\(.*\)/ {
print $2}')
                                [ $DEBUG ] && echo $INSTVER

                                if [ "$INSTVER" !=  "$PKGVERSION" ]
                                then
                                        [ $DEBUG1 ] && echo "$PKGNAME installed but
"
                                        [ $DEBUG1 ] && echo 'install version != pkg
version'
                                        INSTALLSW=0
                                        set -A FILES ${FILES[*]} $PKGFILE
                                        echo $PKGNAME >>$RMFILE
                                        echo $PKGFILE >>$ADDFILE
                                fi
                        else
                                [ $DEBUG1 ] && echo $PKGNAME not installed
                                INSTALLSW=0
                                set -A FILES ${FILES[*]} $PKGFILE
                                echo $PKGFILE >>$ADDFILE
                        fi
                        continue 2
                else
                        [ $DEBUG ] && echo "Class:$CLASS not = pkg class"
                fi
        done
done
} <$PKGS

if [ -n "${FILES[*]}" ]
then
        [ $DEBUG1 ] && echo "Have files to copy"
        echo "#!/usr/local/sbin/cfagent -f -A" > $SCRIPT
        echo "control:" >> $SCRIPT
        echo "\tInform                  = ( on )" >> $SCRIPT
        echo "\tWarnings                = ( on )" >> $SCRIPT
        echo "\tVerbose                 = ( on )" >> $SCRIPT
        echo "\tactionsequence          = ( copy )" >> $SCRIPT
        echo "\tdomain                  = ( eb.com )" >> $SCRIPT
        echo "\ttimezone                = ( CST )" >> $SCRIPT
        echo "\tsmtpserver              = ( mailhost.eb.com )" >> $SCRIPT
        echo "\tSplayTime               = ( 0 )" >> $SCRIPT
        echo "copy:" >> $SCRIPT
        for FILENAME in ${FILES[*]}
        do
                echo "\t$COPYSRC/$FILENAME" >> $SCRIPT
                echo "\t\tdest=$COPYDST/$FILENAME" >> $SCRIPT
                echo "\t\tmode=750" >> $SCRIPT
                echo "\t\tserver=$MASTER" >> $SCRIPT
        done
fi

return $INSTALLSW

If the copyfiles script exists, classes are enabled to copy and install the packages. Finally cleanup classes are enabled in tidy to remove the package files.

# more installsw
#!/bin/ksh
RMSW=/var/cfengine/scripts/rmsw
ADDSW=/var/cfengine/scripts/addsw
SWDIR=/var/cfengine/software
ADMIN=/var/cfengine/scripts/admin
if [ -f $RMSW ]
then
        {
        while read PKGNAME
        do
                pkgrm  -a $ADMIN -n $PKGNAME
        done
        } <$RMSW
        rm $RMSW
else
        [ $DEBUG ] && echo "No Sofware to remove"
fi

if [ -f $ADDSW ]
then
        {
        while read PKGNAME
        do
                pkgadd -d $SWDIR/$PKGNAME -a $ADMIN -n all
        done
        } <$ADDSW
        rm $ADDSW
else
        [ $DEBUG ] && echo "No Sofware to add"
fi


-----Original Message-----
From: Luke A. Kanies [mailto:address@hidden]
Sent: Sunday, December 22, 2002 12:23 PM
To: address@hidden
Subject: Re: processing order, preprocessing, etc.


On Sun, 22 Dec 2002, Kai Großjohann wrote:

> "Luke A. Kanies" <address@hidden> writes:
>
> > I have 70 servers, 100 or so packages, and multiple versions of each
> > package.  I want to define some way to configure the correct version of
> > the correct packags on every host.  I'd prefer to do it based on some kind
> > of classing; I always want the most recent version of ssh, but I can't
> > always just upgrade Oracle or whatever.
> >
> > I am trying to figure out a way to store all of the information I am
> > working with (default package versions, package installation methods, and
> > which hosts have which packages) in cfengine configs, and let cfengine do
> > the installing.
>
> It seems to me it would be quite simple to store a list of
> package/version pairs in a file and to write a shell script to
> iterate over that list and invoke an installer.
>
> So why not use that approach?

Because then cfengine isn't in charge of making sure everything looks the
way it's supposed to.  My goal is to keep all of the configuration data in
the cfengine configs, and as much as possible of the methods in there also
(the installation method might be as simple as setting a set of files to
be pulled down).

I can obviously write a script to do all of the installation, and to
figure out what needs to be done, but then I'm not using my configuration
management tool to do anything involving packages, and if there's a
problem, I basically have to fix it manually, rather than letting cfengine
just do it for me.

I have thought about writing a cfengine code generator, kind of like
TemplateTree.  Then I store all of my configuration data in meta-files,
and use those files to generate my configs.  I can't take advantage of
cfengine's configuration language, but at least I can take advantage of
its other capabilities.  Until cfengine supports multiple namespaces,
which Mark says will happen sometime (early?) next year, and maybe
supports a couple more features, I will probably go with this approach.
The resulting cfengine configs will use all application-specific variables
(e.g., mysql-version, instead of a version variable for each package), so
it'll be a bit ugly, and will be a much larger config, but, oh well.

Luke

--
Millions long for immortality who do not know what to do with
themselves on a rainy Sunday afternoon.         -- Susan Ertz



_______________________________________________
Help-cfengine mailing list
address@hidden
http://mail.gnu.org/mailman/listinfo/help-cfengine


reply via email to

[Prev in Thread] Current Thread [Next in Thread]