Blog Archives

RHEL5 init script for tomcat catalina

I have written an init script for Tomcat Catalina running in RHEL version 5. I have tested this script using Oracle Enterprise Linux 5.5 Carthage. The script should comply to the init standards defined for RedHat Enterprise Linux using the INIT Functions lib.

The script also alows the use of chkconfig eventhough you might want to alter the used priorities (56 10)

#!/bin/sh
#
# "$Id: catalina ,v 1.0 2010/08/10 Chris_g Exp $"
#
#   Startup/shutdown script for tomcat(Catalina) Application server.
#
#   Linux chkconfig stuff:
#
#   chkconfig: 2345 56 10
#   description: Startup/shutdown script for the tomcat application server.
######

# Source function library.
######
. /etc/init.d/functions

# Define where the catalina.sh script is located.
######
CATALINA_BIN='/u01/tomcat/bin/catalina.sh 1> /dev/null';

# Find the catalina process using ps / awk.
# The match function will return 0 when no match is found with the string "java".
# Position $9 should contain the path to the Java executable used by catalina.
######
PROC=`ps -efc | grep apache.catalina | awk 'BEGIN { FS=" "}; { if( match($9, "java") != 0 ) print $9;}'`

# Replace a potential empty string with a fake process so the RH daemon functions are able to parse
# it properly
######
if [[ "$PROC" == '' ]]; then
    PROC='Tomcat_JVM';
fi

# Define the application name that is listed in the daemonize step.
PROG='Tomcat JVM';

# LOCKFILE
LOCK='/var/lock/subsys/tomcat';

start () {
        echo -n $"Starting $PROG: "

        # start daemon
        daemon $CATALINA_BIN start
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch $LOCK
        return $RETVAL
}

stop () {
        # stop daemon
        echo -n $"Stopping $PROG: "
        killproc $PROC
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f $LOCK
}

restart() {
        stop
        start
}

case $1 in
        start)
                start
        ;;
        stop)
                stop
        ;;
        restart)
                restart
        ;;
        status)
                status $PROC
                RETVAL=$?
        ;;
        *)

        echo $"Usage: $prog {start|stop|restart|status}"
        exit 3
esac

exit $RETVAL

# INSTALL
1. Touch a new tomcat file in your init directory.
>touch /etc/init.d/tomcat
2. Copy paste the code above into this file using vi
vi /etc/init.d/tomcat
(putty users)
press the insert button (this should put vi in insert mode)
Alter the tomcat catalina.sh path and copy the altered code to your clipboard and paste it into putty using a richt mouse click.
press esc (this should get you out of insert mode)
next press ” shift + : “, “w”, “enter” (this should save the file)
3. If catalina.sh was able to start tomcat (all vars/java configured) then now the tomcat script should be able to handle the startup.
4. If catalina was allready running, try;

     service tomcat status
     This should allready give a result equal to;
     java (pid 14389) is running…

5. Add tomcat to the chkconfig for automatic startup
     chkconfig –level 2345 tomcat on

Hope this helps 😉

Application for running custom init scripting in a saver way.

Hi All,

Just Wrote :

AMIS.zip

An application to start / stop multiple custom scripts during INIT in a specific order without the need to understand the full INIT.d process. Written by AMIS to enable DBAs to create basic tiny startup / stop scripts and run them using the chkconfig / services commands. through a very basic config file.

Application should create a basic abstraction between the init.d process and the to be executed configurable scripts. main goal is to prevent poor scripting from killing the init.d proces, and follow the system guidlines concerning init scripting as much as possible.

Please tell us what you think or what could be improved. naturally even we dont know it all. Suggestions, Bugs, Hints, Tips, Arguments, Alternatives? Please let us know 🙂

Rename the “AMIS.zip.doc” file back to “AMIS.zip” to access its content. We have tested this script on the following systems.

RHEL 5.3     Perl v5.8.8
RHEL 5.2     Perl v5.8.8
RHEL 5.1     perl v5.8.8
SLES 9.0      perl v5.8.8

Need to compile the “Config::IniFiles”  even though its shipped with the app as module? use > cpan -i Config::IniFiles.

-Rgrds, Chris

Altering the Nagios daemon startup script to include NDO.

previously I wrote an article on how to create a deamon script for ndo. But when you are using Centreon the only “nice” way to do this is by altering the Nagios startupscript to include the ndo part.

Here is what i have done to make this possible.

First i wrote a function to find the PIDs for the ndo deamon process based on a specific config. In this one the config is hardcoded,
but you might also replace the $NagiosNdoConfig with $1 instead and call the function like;

getNdoPid “/usr/local/nagios/etc/yourconfig.cfg”

getNdoPid ()
{
 #Declare a var containing the correct ndo PID, there are processes being forked from ndo so we need to
 #do some awk filtering also to fetch the correct one.
 #Not that the parent process always has a parent pid "1" so we use that to filter the parent from the childs.
 ndoPID=`ps -ef | grep $NagiosNdoConf | grep "?" | awk -F ' '  '{if($3 == '1') print $2}'`
        #next we validate if we got an pid returned to us, and fill a wrapper that we will use like $? that ill convieniently call "ls" LastState.
        if [[ "$ndoPID" == '' ]]; then
            ls=1;
        else
            ls=0;
        fi
}

Next using the getNdoPid function u wrote another two functions to start and to stop the ndo daemon. I choose this method so i can include these function inside the existing start stop scripting used by nagios. In effect when you start nagios, th start case select is used which will call our ndo start script.

The ndo kill function

kill_ndo ()
{
        #Find the actual PID
        if [[ "$ndoPID" == '' ]]; then
             #No process running to kill...
             ls=0;
        else
             kill $ndoPID;
             sleep 2 #parent needs some time to kill the child processes if any
             getNdoPid
             if [[ "$ls" == '1' ]]; then
                   ls=0;
             else
                   ls=1;
             fi
        fi
}

and the start portion…
The ndo start function

start_ndo ()
{
        #always make sure ndo isnt running!
        $NagiosNdo -c $NagiosNdoConf;
        if [[ "$?" == '0' ]]; then
                ls=0;
        else
                ls=1;
        fi
}

Again i am using the ls (laststate) var to save the last state of the executed command. This is important because the state of a command can only be tested right after execution of that command. by using the ls var i make sure i am always testing the correct result. this is because the $? is also overwritten when performing an var assignment, if test etc.

Next I added a few vars for configuration, stuff like where the ndo2db bin is located, and the config file.

NagiosNdo=/usr/sbin/ndo2db;
NagiosNdoConf=/usr/local/nagios/etc/ndo2db.cfg;

naturally the NDO bin could also be found like;
NagiosNdo=`which ndo2db`;
Bu this will require the ndo2db bin to be somewhere in the path var. We are not sure this is always the case because there is no consensus on where these nagios bins should be placed. This may vary from distro to distro and from user to user. In my case, it being placed inside /user/bin this whould also work.

I also extended the functionality of the startupscript by adding new options to start, stop and restart the ndo deamon by using the nagios startupscript. This is what i did.

inside the “case” statement where the “/etc/init.d/nagios args” are tested i added some new options namely “startndo, stopndo, restartndo” and this is what it looks like.

For the option “/etc/init.d/nagios startndo”

 startndo)
                getNdoPid
                if [[ "$ls" == '1' ]]; then
                    start_ndo
                    if [[ "$ls" == '0' ]]; then
                        echo 'NDO deamon started succesfully';
                        exit 0;
                    else
                        echo 'Failed to start NDO, check your logging for more info';
                        exit 1;
                    fi
                else
                    echo "Ndo deamon allready running with PID : $ndoPID";
                    exit 1;
                fi
                ;;

for the “/etc/init.d/nagios stopndo” option

stopndo)
                getNdoPid
                if [[ "$ls" == '1' ]]; then
                     echo "$ls";
                     exit 1;
                else
                     kill_ndo
                     sleep 2 #it needs some time to kill the childs (that get ppid 1 when the parent quits)
                     getNdoPid
                     if [[ "$ls" == '1' ]]; then
                         echo "Ndo stopped succesfully";
                         exit 0;
                     else
                         echo "Unable to kill ndo, please review you logging";
                         exit 1;
                     fi
                fi
                ;;

And a restart option “/etc/init.d/nagios restartndo”

restartndo)
                $0 stopndo
                $0 startndo
                ;;

To include the start and stop options in the nagios start and stop process all you need to do is add the start and or stop options in there.
Here is an example

 start)
                echo -n "Starting nagios:"
                $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1;
                if [ $? -eq 0 ]; then
                        su - $NagiosUser -c "touch $NagiosVarDir/nagios.log $NagiosRetentionFile"
                        rm -f $NagiosCommandFile
                        touch $NagiosRunFile
                        chown $NagiosUser:$NagiosGroup $NagiosRunFile
                        $NagiosBin -d $NagiosCfgFile
                        if [ -d $NagiosLockDir ]; then touch $NagiosLockDir/$NagiosLockFile; fi
                        #chmod 777 $NagiosCommandFile
                        start_ndo
                        echo " done."
                        exit 0
                else
                        echo "CONFIG ERROR!  Start aborted.  Check your Nagios configuration."
                        exit 1
                fi
                ;;
#Stop portion
stop)
                echo -n "Stopping nagios: "

                pid_nagios
                killproc_nagios nagios
                kill_ndo
                # now we have to wait for nagios to exit and remove its
                # own NagiosRunFile, otherwise a following "start" could
                # happen, and then the exiting nagios will remove the
                # new NagiosRunFile, allowing multiple nagios daemons
                # to (sooner or later) run - John Sellens
                #echo -n 'Waiting for nagios to exit .'
                for i in 1 2 3 4 5 6 7 8 9 10 ; do
                    if status_nagios > /dev/null; then
                        echo -n '.'
                        sleep 1
                    else
                        break
                    fi
                done
                if status_nagios > /dev/null; then
                    echo ''
                    echo 'Warning - nagios did not exit in a timely manner'
                else
                    echo 'done.'
                fi

                rm -f $NagiosStatusFile $NagiosRunFile $NagiosLockDir/$NagiosLockFile $NagiosCommandFile
                ;;

        status)
                pid_nagios
                printstatus_nagios nagios
                ;;

Now when i start and stop nagios using the centreon “start / stop / reload” options my ndo daemon is also started / stopped. Ps. This manual uses Nagios 3.0 and Centreon 2.2

This is what a restart looks like 😉

[root@UX127 var]# service nagios restartndo
Ndo stopped succesfully
NDO deamon started succesfully

Rgrds,

wait in Bash..

This is an alternative for sleep [i]n[/i]

function wait(){
    BOGUS=`read -n1 -t1 any_key`
    BOGUS=''
}

If you have sleep available, you rather use sleep then this method! i.e.

$N=1;
while :
do
    echo "$N"
    sleep 1
    let N=$N+1;
done

NRPE – Check_memory script

this script is intended to “mime” the NSClient++ checkMem option on linux. Most check_mem scripts i have found where rather “minimal” so i ended up writing my own one. Feel free to test, use, alter, redis or what ever with it 🙂

Here is a new version. Improvements.

– Var footprints reduced to a bare minimum.
– Free command is now only executed once.
– Corrected the swap validation that was using the wrong vars.
– Added small corrections like adding ; within “ execs to mark end of command etc.

Here you go 🙂

    #!/bin/bash
#
#
# @Type 	: Bash
# @Date 	: 19-05-2009
# @Author 	: Chris Gralike
# @Category	: Nagios Monitoring/SLA
# @Category	: MemoryCheck Linux, All memory spaces
# @Company	: AMIS Services BV.
# @License	: GNU_Public
# @ToDo		: See Comments in script. Suggestions are welcome... 
##

## You are free to alter, modify and distribute the content of this file
 # This file is offered "as is", and we offer no guarantee on functionality
 # and or outcome of this check. Neither can the author nor AMIS be
 # responsible for any damages caE by this script. 
 #
 # Have fun with it, and we hope it proves usefull
 # Script is based on precentage orientated monitoring / SLAs
 ##

#Get Options
while getopts 'u:v:w:x:y:z:hpef' OPT; do
  case $OPT in
    u) U=$OPTARG;;
    v) V=$OPTARG;;
    w) W=$OPTARG;;
    x) X=$OPTARG;;
    y) Y=$OPTARG;;
    z) Z=$OPTARG;;
    e)  E="yes";;
    f)  FR="yes";;
    p)  P="yes";;
    h)  H="yes";;
    *)  unknown="yes";;
  esac
done
#Help Output
USAGE="
	usage: $0 [ -option [value]]
	
	[options:]
		-h		->	Show this help page
		-p		->	Show performance options
		-e		->	Warn/Crit based on usage precentage, warn/crit based on usage orientation
		-f		->	Warn/Crit based on free precantage, warn/crit based on free space orientation
		-u [valeu]	->	Physical warning treshold (in %)
		-v [value]	->	Physical critical treshold (in %)
		-w [value]	->	Virtual waring treshold (in %)	
		-x [value]	->	Virtual critical treshold (in%)
		-y [value]	->	Swap warning value (in%)
		-z [value]	->	Swap critical value (in%)
"
#Show usage if requested
if [ "$H" = "yes" -o $# -lt 1 ]; then
	echo "$USAGE"
	exit 0
fi
#Check if all the thresholds are defined.
if [ "$W" = "" -o "$X" = "" -o "$U" = "" -o "$V" = "" -o "$Y" = "" -o "$Z" = "" ]; then
	echo "All the [u,v,w,x,y,z] options should be defined! \r\n"
	exit 0
fi
#Check if all the thresholds are integers
# if syntax is $0 -e -u 10 -v 10 -w 10 -x 10 -y 10 -z 10 -p things are allright
# if syntax is $0 -e -u 10 -v 10 -w 10 -x 10 -y 10 -z -p A bunch of errors arise because " " is not equal too ""
# and failes the check above.
# This typo needs to be fixed someday...
#Check the orientation
if [ "$E" = "yes" -a "$FR" = "yes" ]; then
	echo "You cant use both the free, as E orientation for the tresholds. Please select -e or -f as orientation"
	exit 0
elif [ "$E" = "yes" ]; then
	# Check the critical / warning thresholds
	if [ "$W" -gt "$X" -o "$U" -gt "$V" -o "$Y" -gt "$Z" ]; then
		echo "Warning: Warning > Critical while using usage orientation!"
	fi	

elif [ "$FR" = "yes" ]; then
	# Check the warning / Critical thresholds
	if [ "$W" -lt "$X" -o "$U" -lt "$V" -o "$Y" -lt "$Z" ]; then
                echo "Warning: Warning < Critical while using free space orientation!"
        fi
else
	echo "Please define an orientation using either the -e or the -f option"
	exit 0;
fi

#Get physiscal numbers 
FRE=`free -m`

PT=`echo "$FRE" | grep Mem | awk '{ print $2; exit;}';`
PU=`echo "$FRE" | grep Mem | awk '{ print $3; exit;}';`
FP=$(($PT-$PU));
#Get virtual memory numbers
VU=`echo "$FRE" | grep buffers/cache | awk '{ print $3; exit;}';`
VF=`echo "$FRE" | grep buffers/cache | awk '{ print $4; exit;}';`
VT=$(($VU+$VF));
#Get Swapped memory numbers
ST=`echo "$FRE" | grep Swap | awk '{ print $2; exit;}';`
SU=`echo "$FRE" | grep Swap | awk '{ print $3; exit;}';`
SF=$(($ST-$SU));

#still needs to be done in an nice syntax.
#Start validating our numbers.
if [ "$E" = "yes" ]; then
	#calculate E precentages
	PPF=`echo "scale=5; (100/$PT)*$PU" | bc -l | awk -F '.' '{ print $1; exit; }'`
	VPF=`echo "scale=5; (100/$VT)*$VU" | bc -l | awk -F '.' '{ print $1; exit; }'`
	SPF=`echo "scale=5; (100/$ST)*$SU" | bc -l | awk -F '.' '{ print $1; exit; }'`
	#still needs to be done in an nice syntax.
	if [ "$P" = "yes" ]; then
        	#not sure about the syntax...
		PD="|Ph=$PPF%;$U;$V; Vi=$VPF%;$W;$X; Sw=$SPF%;$Y;$Z;"
	else
        	PD=""
	fi

	MSG="Ph:$PU/$PT($PPF%), Vi:$VU/$VT($VPF%), Sw:$SU/$ST($SPF%) $PD"

	#Validate Physical Memory
	if [ "$PPF" -gt "$U" -a "$PPF" -gt "$V" ]; then
		NPE=2
	elif [ "$PPF" -gt "$U" -a "$PPF" -lt "$V" ]; then
		NPE=1
	elif [ "$PPF" -lt "$U" -a "$PPF" -lt "$V" ]; then
		NPE=0
	else
		#unknown crit and warn the same?
		NPE=3
	fi 
	#Validate Virtual Memory
	if [ "$VPF" -gt "$W" -a "$VPF" -gt "$X" ]; then
       	        NVE=2
        elif [ "$VPF" -gt "$W" -a "$VPF" -lt "$X" ]; then
       		NVE=1
   	elif [ "$VPF" -lt "$W" -a "$VPF" -lt "$X" ]; then
               	NVE=0
       	else
               	#unknown crit and warn the same?
               	NVE=3
       	fi
	#Validate Swap memory
	if [ "$SPF" -gt "$W" -a "$SPF" -gt "$X" ]; then
                NSE=2
        elif [ "$SPF" -gt "$W" -a "$SPF" -lt "$X" ]; then
                NSE=1
        elif [ "$SPF" -lt "$W" -a "$SPF" -lt "$X" ]; then
                NSE=0
        else
                #unknown crit and warn the same?
                NSE=3
        fi
	#We only want to see the most critical,...
	if [ "$NPE" -eq "2" -o "$NVE" -eq "2" -o "$NSE" -eq "2" ]; then
		echo "Critical - $MSG"
		exit 2
	elif [ "$NPE" -eq "1" -o "$NVE" -eq "1" -o "$NSE" -eq "1" ]; then
		echo "Warning - $MSG"
		exit 1
	elif [ "$NPE" -eq "0" -a "$NVE" -eq "0" -a "$NSE" -eq "0" ]; then
                echo "Ok - $MSG"
                exit 0
	else
		echo "Unknown - $MSG"
		exit 3
	fi
elif [ "$FR" = "yes" ]; then
	#calculate free precentages
	PPF=`echo "scale=5; (100/$PT)*$FP" | bc -l | awk -F '.' '{ print $1; exit; }'`
	VPF=`echo "scale=5; (100/$VT)*$VF" | bc -l | awk -F '.' '{ print $1; exit; }'`
	SPF=`echo "scale=5; (100/$ST)*$SF" | bc -l | awk -F '.' '{ print $1; exit; }'`
	
	#still needs to be done in an nice syntax.
	if [ "$P" = "yes" ]; then
			#not sure about the syntax...
			PD="|Ph=$PPF%;$U;$V; Vi=$VPF%;$W;$X; Sw=$SPF%;$Y;$Z;"
	else
			PD=""
	fi

	MSG="Ph:$FP/$PT($PPF%), Vi:$VF/$VT($VPF%), Sw:$SF/$ST($SPF%) $PD"

        #Validate Physical Memory
        if [ "$PPF" -lt "$U" -a "$PPF" -lt "$V" ]; then
                NPE=2
        elif [ "$PPF" -lt "$U" -a "$PPF" -gt "$V" ]; then
                NPE=1
        elif [ "$PPF" -gt "$U" -a "$PPF" -gt "$V" ]; then
                NPE=0
        else
                #unknown crit and warn the same?
                NPE=3
        fi
        #Validate Virtual Memory
        if [ "$VPF" -lt "$W" -a "$VPF" -lt "$X" ]; then
                NVE=2
        elif [ "$VPF" -lt "$W" -a "$VPF" -gt "$X" ]; then
                NVE=1
        elif [ "$VPF" -gt "$W" -a "$VPF" -gt "$X" ]; then
                NVE=0
        else
                #unknown crit and warn the same?
                NVE=3
        fi
        #Validate Swap memory
        if [ "$SPF" -lt "$W" -a "$SPF" -lt "$X" ]; then
                NSE=2
        elif [ "$SPF" -lt "$W" -a "$SPF" -gt "$X" ]; then
                NSE=1
        elif [ "$SPF" -gt "$W" -a "$SPF" -gt "$X" ]; then
                NSE=0
        else
                #unknown crit and warn the same?
                NSE=3
        fi
        #We only want to see the most critical,...
        if [ "$NPE" -eq "2" -o "$NVE" -eq "2" -o "$NSE" -eq "2" ]; then
                echo "Critical - $MSG"
                exit 2
        elif [ "$NPE" -eq "1" -o "$NVE" -eq "1" -o "$NSE" -eq "1" ]; then
                echo "Warning - $MSG"
                exit 1
        elif [ "$NPE" -eq "0" -a "$NVE" -eq "0" -a "$NSE" -eq "0" ]; then
                echo "Ok - $MSG"
                exit 0
        else
		 echo "Unknown - $MSG"
                exit 3
        fi
else
	echo "Something is very off..... please review all the settings, or report this as a bug"
	exit 3
fi

Rgrds Chris

Compare File contence using VBScript.

Ever had the need to compare a file using VBS? You might wonder why you might need something like that? For instance. You have all your coperate templates on your network, but you want to upload these to your portable clients so they always have access to these templates. To keep these clients up-to-date you only want to upload these template each time a version file is changed on the network.

To do this you need to compare the contence of that file. Here is a script that will enable you to do just that.

Set Fso = WScript.CreateObject(“Scripting.FileSystemObject”)

CopyTemplates = “NotSet”
If Fso.FileExists(“C:\office\version.txt”) then
set objFile1 = Fso.opentextfile(“C:\AMIS-Huisstijl\office\versie.txt”,1)
Else
CopyTemplates = “True”
End If
If Fso.FileExists(“F:\office\version.txt”) then
set objFile2 = Fso.opentextfile(“F:\AMIS-Huisstijl\office\versie.txt”,1)
Else
CopyTemplates = “True”
End If
If CopyTemplates = “NotSet” Then
arrFile1 = split(objFile1.ReadAll,vbNewLine)
arrFile2 = split(objFile2.ReadAll,vbNewLine)
objFile1.close
objFile2.close
If ubound(arrFile1) ubound(arrFile2) then
intLineCount = ubound(arrFile2)
strError = strFile2 & ” is bigger than ” & strFile1
Else
intLineCount = ubound(arrFile2)
End if
for i = 0 to intLineCount
if not arrFile1(i) = arrFile2(i) then
exit for
end if
next
If i < (intLineCount + 1) then
CopyTemplates = “True”
Elseif strError “” then
CopyTemplates = “True”
Else
CopyTemplates = “False”
End If
WScript.Echo “Copy Templates = ” & CopyTemplates
End If