Article Figure 1 Listing 1 Listing 2 Listing 3
Listing 4 feb2007.tar

Listing 3 Patchit

#!/sbin/sh
###########################################################
#
#  patchit.sh
#      
#  Description: This script patches the server using the patches that 
#  have been downloaded from the  patch server.  It runs first as a cron 
#  job changes the run level and patches the box based on the patch 
#  cluster loaded in the local patch directory
#  
#  The local patch directory is determined by an entry in the "host_type" 
#  file in the patch directory located on the patch server.
# 
#  Author:     James Hartley
#  Date:     05/06/2006
#
#  Special Requirements: 
#  
#
#  /admin/software/patch/getpatch script
# 
#  should be run before any patching. getpatch run as cron job before 
#  patching.  getpatch as the name implies grabs the patch cluster for
#  the host.  It also creates the required logfile
#
#  /etc/patchlog
# 
#  this file must be present to patch.  
# 
#  The following files are required on the host. 
#
#  /etc/init.d/patch 
#  /etc/rc1.d/S300patch -> /etc/init.d/patch
#  /etc/rc3.d/S300patch -> /etc/init.d/patch 
#
#  /etc/rc1.d/S300patch patches the box at run level 1. 
#  /etc/rc3.d/S300patch checks status after boot and 
#  mails a patch complete message if the file 
#
#  /etc/patchdone exist.
#
#  Basic Functionality: 
#
#  if [ -f /etc/patchflag ] is true AND
#  if [ -f /etc/patchlog ] is true then; 
#
#  the system will go to run level 1 to patch.      
#
#  the system will attempt to patch itself at run level 1. 
#  if successful the system will rm the patchflag file and make an entry 
#  in the patchlog that the patch succeeded and then mv the patch log to:
#
#  /etc/patchlog.`date +%y%m%d` 
#
#  The system sets up a reboot to level 3 and on boot
# 
#  if [ -f /etc/patchflag ] is false the system will boot normally.  In 
#  fact it is an error if the file exists on boot after the patch is 
#  complete. It is also an error if the file /etc/patchlog exist after boot.
#
#  if [ -f /etc/patchdone ] is true then the system send
#  a message that the patching operation is complete. 
#
#  WARNING: you still must check the logfile to determine which patches 
#  were added to the system and if the cluster installed correctly.
#
#
#
###############################################################
#
# this line for testing.
set -x
#
# Grab some environment information
#

PATH=/usr/sbin:/usr/bin
export PATH

HOST=`/usr/bin/hostname`
LOGFILE="/etc/patchlog"
PATCHFLAG="/etc/patchflag"
PATCHDONEFLAG="/etc/patchdone"
FROM="unixdude_from_mars@ymp.gov"
SUBJECT="patching the world over from $HOST"
RECIPIENT="root"
CURRENT_RUNLEVEL=`/usr/bin/who -r | /usr/bin/awk '{print $7}'`

mailmessage ()
{
   echo $1 | mailx -r $FROM -s $SUBJECT $RECIPIENT
}

#
#  Begin execution 
#

if [ $CURRENT_RUNLEVEL = 3 ] &&  [ ! -f $PATCHFLAG ] && [ ! -f $LOGFILE ]; then
        if [ -f "$PATCHDONEFLAG" ]; then
       mailmessage "patching operation completed on $HOST" 
           rm $PATCHDONEFLAG
       exit 0
        else
       echo "no patching go away"
       exit 0
        fi
elif [ $CURRENT_RUNLEVEL = 3 ] && [ -f $PATCHFLAG ] && [ ! -f $LOGFILE ]; then 
    mailmessage "ERROR: patchflag set patchlog does not exist. was \
                 grabpatch run on $HOST"
    rm $PATCHFLAG
    exit 1;
elif [ $CURRENT_RUNLEVEL = 3 ] && [ ! -f $PATCHFLAG ] && [ -f $LOGFILE ]; then
    echo "ERROR: patchflag not set patchlog exist on $HOST" >> $LOGFILE
    mailmessage "ERROR: patchflag not set patchlog exist. see \
      logfile.`date +%y%m%d on $HOST"
    mv $LOGFILE $LOGFILE.`date +%y%m%d`
    exit 2;
 
elif [ $CURRENT_RUNLEVEL = 3 -a -f $PATCHFLAG -a -f $LOGFILE ];then

       echo "bringing the system down to user-level 1" >> $LOGFILE 
       #
       # In order to go all the way to run level zero and back up we 
       # invoke sed and change the default run level s and init 6
       #
       sed '/initdefault/{ s/3/1/; }' /etc/inittab > /etc/inittab.patch
       cp  /etc/inittab /etc/inittab.orig
       mv  /etc/inittab.patch /etc/inittab
       cat /etc/inittab >> $LOGFILE
       /usr/bin/sync 
       NEW_RUNLEVEL=6

       # Bring the system to new runlevel, this action is similar 
       # to forking a processing, the script will not return after we
       # obtain run level one, so the rest of the activity will have to 
       # occur via a start and stop script at the appropriate run level. 

       init $NEW_RUNLEVEL
       exit 0


elif [ $CURRENT_RUNLEVEL = 1 -a -f $PATCHFLAG -a -f $LOGFILE ]; then
    echo "patching system" >> $LOGFILE
    rm $PATCHFLAG
        # 
    #  fix the inittab file back to the original
    #
    /usr/bin/sed '/initdefault/{ s/1/3/; }' /etc/inittab > /etc/inittab.patch
    cp  /etc/inittab /etc/inittab.orig2
     mv  /etc/inittab.patch /etc/inittab
    cat /etc/inittab >> $LOGFILE
        INSTALLDIR=`grep INSTALLDIRECTORY $LOGFILE |awk '{ print $2 }'`
    cd $INSTALLDIR
        #
        # here is where we patch the system
    #
        for file in `ls -l | grep '^d' | awk '{ print $9 }'`;
        do 
           cd $file
           if [ -f install_cluster ]; then
        ./install_cluster -q >> $LOGFILE 
       fi
       cd $INSTALLDIR
        done

    #
    # here is the clean up
    #
        echo "patching should be completed" >> $LOGFILE
    mv $LOGFILE $LOGFILE.`date +%y%m%d`
        touch $PATCHDONEFLAG
    NEW_RUNLEVEL=6
    init $NEW_RUNLEVEL
    exit 0
else
    echo "we do nothing here"
fi