[Zope-dev] Zope Start Script Woes

Sean Duffy swduffy at unmc.edu
Wed Jan 21 09:50:40 EST 2004


Hi,

These are probably more shell scripting issues, but I'm hoping that 
some scripter with an agile mind will show me the error of my ways, 
so here goes.

I have borrowed a script from the zope site and modified it for my
purposes, and it 'sort of' works.  The issues are:

Can't seem to get the Instance-Home stuff to work right without local
start scripts in each directory.  Right below the $INSTANCE_HOME/start
is the line I'd like to use to simplify the management of the 
instances.

Can't get stop to work right.  First 'stop' is not an instance, then 
the first instance does appear to get stopped, but it errors on the 
other two.  

I get a 'start0' for the value of $WAIT in the starting text display.
(should just be a big fat zero or one!)

And for some reason, the script dumps the entire local environment to
the display before it does anything; any ideas why?

All constructive criticism welcome, and I'll take some flames 
(high of 22 today).

System is RedHat-9.0 Zope-2.6.2 Python-2.2.3 

Zope is installed in /usr/local/zope
Instances are /var/zope-sites/

Here's the script:

#!/bin/sh

# /etc/init.d/zope-instances
#
# Starts or stops multiple instances of zope one by one or all at ones.
# Configuration is done all through one configuration file 
# /etc/zope-instances.conf which defines the location of the data-files,
# the user to run the instance, FTP portnrs, number of threads and if
the 
# zdaemon should be used (to start a new instance should the one crash) 
# all configurable per instance.
#
# Steps for creating and running a new instance:
#   - start with a normal working (fresh) distribution of Zope
# ... snip ...
#   - edit /etc/zope-instances.conf to run the new instance as you
desire
#   - start the new instance (/etc/init.d/zope-instances start
instance-name)
#
# Note: this script is only tested for Red Hat distributions. 
# Locations of scripts may vary from various distributions. 
# Use at own risk.
#
# created: Chaim Zax (chaim at climbing.nl)
# version 0.02, dd. 29-3-'03
# version 0.02a, stuffduff 20-01-'04

INSTANCES_CONF="/etc/zope-instances.conf"
DEFAULT_USER="www-data"
ZOPE_BASE="/usr/local/zope" 
PS="ps wax"

# Log- and pid-files
ZDAEMON_PIDFILE="/var/zProcessManager.pid"
ZDAEMON_LOGFILE="/var/Z2_debug.log"
ZOPE_PIDFILE="/var/Z2.pid"
ZOPE_LOGFILE="/var/Z2.log"
ZOPE_DEBUGFILE="/var/zope-debug.log"

# Function for showing help-text how to use this script
helpText ()
{
  echo "Starts or stops multiple instances of zope one by one or all 
at
ones."
  echo
  echo "  zope-instance [start/stop/restart/info/kill] [instance-name]
[-w] [-h]"
  echo
  echo "             start/stop    : starts or stops one or all
zope-instances"
  echo "             restart       : restarts one or all zope-
instances"
  echo "             info          : gets instance info as well as 
their
current status"
  echo "             kill          : kills one or all zope-instances,
even if orphaned"
  echo "                             USE THIS ONLY WHEN ZOPE SPINS OUT
OF CONTROL"
  echo "             instance-name : if not provided or 'all' 
indicates
all instances,"
  echo "                             else acts only on the given
instance"
  echo "             -w            : Do not wait for instance to
startup"
  echo "             -h            : This help-text"
}

startZope ()
{
  startingAndStopping "start" $1 $2
}

stopZope ()
{
  startingAndStopping "stop" $1 "-"
}

restartZope ()
{
  startingAndStopping "restart" $1 $2
}

infoZope ()
{
  startingAndStopping "info" $1 "-"
}

killZope ()
{
  if [[ $1 == "all" ]]; then
    killAll
  else
    killInstance $1
  fi
}

# Start one or more instances depending of $1 and $2
startingAndStopping ()
{
  MODE=$1  # mode is 'start', 'restart', 'stop' or 'info'
  INSTANCE=$2
  WAIT=$3

  if [ ! -e $INSTANCES_CONF ]; then
    echo "ERROR: No configuration file '$INSTANCES_CONF'"
    exit 1
  fi

  SETUP="no"
  # sift through the configuration file, one line at a time
  while read LINE; do
    if [[ ${LINE::1} != "#" ]]; then
      set $LINE

      if [[ $1 != "" ]]; then
        # starts, restarts or stops all instances (one per loop)
        if [[ $INSTANCE == "all" ]]; then
          STARTUP_MODE=$8
          if [[ $STARTUP_MODE == 'start' || ($MODE != 'start' && $MODE
!= 'restart') ]]; then
            actionOnInstance $MODE $1 $2 $3 $4 $5 $6 $7 $8 $WAIT
          fi
          SETUP="done"
  
        # starts or stops only the provided instance and breaks out of
the loop
        elif [[ $INSTANCE == $1 ]]; then
          actionOnInstance $MODE $1 $2 $3 $4 $5 $6 $7 $8 $WAIT
          SETUP="done"
          break
        fi
      fi
    fi
  done < $INSTANCES_CONF

  # the instance-name doesn't correspond to the ones in the
configuration file
  if [[ $SETUP == "no" ]]; then
    echo "ZOPE-INSTANCE NOT STARTED/STOPPED! No instance found with
name'$INSTANCE'. Check the configuration file ($INSTANCES_CONF)."
    echo "Possible options are:"
    echo "- all (for starting and stopping all zope instances below)"
    cat $INSTANCES_CONF | awk '{ print "- " $1 }' | grep -v "#"
  fi
}

actionOnInstance () 
{
  MODE=$1
  INSTANCE_NAME=$2
  WAIT=$10

  if [[ $MODE == "start" ]]; then
    startInstance $2 $3 $4 $5 $6 $7 $8 $9 $WAIT
  elif [[ $MODE == "restart" ]]; then
    stopInstance $2 $3 $4 $5 $6 $7 $8
    sleep 1
    startInstance $2 $3 $4 $5 $6 $7 $8 $9 $WAIT
  elif [[ $MODE == "stop" ]]; then
    stopInstance $2 $3 $4 $5 $6 $7 $8 $9
  elif [[ $MODE == "info" ]]; then
    infoOnInstance $2 $3 $4 $5 $6 $7 $8 $9
  else
    echo "Error: Unknown action on instance $1"
  fi
}

# with name, data directory, user, HTTP portnr, FTP portnr, number of
threads, manager
startInstance ()
{
  INSTANCE_NAME=$1
  INSTANCE_HOME=$2
  USER=$3
  HTTP_PORT=$4
  FTP_PORT=$5
  THREADS=$6
  USE_MANAGER=$7
  STARTUP_MODE=$8
  WAIT=$9

  # check for a running or starting instance, abort if found
  if [[ "`isHumming $INSTANCE_NAME`" = "yes" ]]; then
    if [ -e $INSTANCE_HOME$ZOPE_PIDFILE ]; then
      echo "Zope-instance '$INSTANCE_NAME' is already running."
    else
      echo "Zope-instance '$INSTANCE_NAME' is already being started."
    fi

  else
    # remove old pid files in case of a previous crash
    rm -f $INSTANCE_HOME$ZDAEMON_PIDFILE
    rm -f $INSTANCE_HOME$ZOPE_PIDFILE
  
    echo "Starting Zope-instance: $INSTANCE_NAME..."
    echo "     data: '$INSTANCE_HOME', user: '$USER'"
    echo "     http: $HTTP_PORT, ftp: $FTP_PORT, threads: $THREADS,"
    echo "     use manager: $USE_MANAGER, default: $STARTUP_MODE, 
wait:
$WAIT"

    # create the necessary startup parameters
    if [[ $USER == "default" ]]; then
      USER=$DEFAULT_USER
    fi
  
    if [[ $USE_MANAGER == "yes" ]]; then
      MANAGER="1"
    else
      MANAGER="0"
    fi
  
    if [[ $ZOPE_DEBUGFILE != "" ]]; then
      STUPID_LOG_FILE="$INSTANCE_HOME$ZOPE_DEBUGFILE"
      Z_DEBUG_MODE=1
      export STUPID_LOG_FILE Z_DEBUG_MODE
    fi

    # what works
    $INSTANCE_HOME/start &

    # what we'd like but won't recognize instance home
    # exec /usr/bin/python $ZOPE_BASE/z2.py -z $ZOPE_BASE -u $USER \
    #     -w $HTTP_PORT -f $FTP_PORT -t $THREADS -Z $MANAGER \
    #     -l $INSTANCE_HOME$ZOPE_LOGFILE \
    #     -D "$@" $INSTANCE_HOME/var/startup.log &

    # wait for the instance to start up.
    WAIT="1"
    if [[ $WAIT == 1 ]]; then
      echo -n "     starting"
      waitForStartup $INSTANCE_NAME
    fi
    echo
  fi
}

stopInstance ()
{
  INSTANCE_NAME=$1
  INSTANCE_HOME=$2

  # check for a running or starting instance, abort if found
  if [[ "`isHumming $INSTANCE_NAME`" = "yes" ]]; then
    if [ ! -e $INSTANCE_HOME$ZOPE_PIDFILE ]; then
      echo "Zope-instance '$INSTANCE_NAME' is being started. Wait for it
to start up before stopping it, or kill ALL zope processes with the
'kill-all' option (not recommended)."
      echo
    else

      # If we're running the zdaemon, kill it first to prevent it from 
      # re-spawning a new zope-instance.
      if [ -e $INSTANCE_HOME$ZDAEMON_PIDFILE ]; then
        echo -n "Stopping ZDaemon for $INSTANCE_NAME... "
        ZDAEMON_PID=`cat $INSTANCE_HOME$ZDAEMON_PIDFILE`
        kill $ZDAEMON_PID 2/dev/null && true
        echo "done"
      fi

      # Kill the actual zope-instance
      if [ -e $INSTANCE_HOME$ZOPE_PIDFILE ]; then
        echo -n "Stopping Zope-instance: $INSTANCE_NAME... "
        ZOPE_PID=`cat $INSTANCE_HOME$ZOPE_PIDFILE | cut -d' ' -f2`
        kill $ZOPE_PID 2/dev/null && true
        echo "done"
      else
        echo "Zope-instance '$INSTANCE_NAME' was not running"
      fi

      cleanUp $INSTANCE_HOME
    fi

  else
    echo "Zope-instance '$INSTANCE_NAME' was not running"
    cleanUp $INSTANCE_HOME
  fi
}

# remove all floating pid and socket files
cleanUp () 
{
  INSTANCE_HOME=$1

  # Do some cleaning up.
  if [ -e $INSTANCE_HOME$ZDAEMON_PIDFILE ]; then
    rm -f $INSTANCE_HOME$ZDAEMON_PIDFILE
  fi
  if [ -e $INSTANCE_HOME$ZOPE_PIDFILE ]; then
    rm -f $INSTANCE_HOME$ZOPE_PIDFILE
  fi

}

infoOnInstance ()
{
  INSTANCE_NAME=$1
  INSTANCE_HOME=$2
  USER=$3
  HTTP_PORT=$4
  FTP_PORT=$5
  THREADS=$6
  USE_MANAGER=$7
  STARTUP_MODE=$8
  WAIT=$9

  echo "Status of Zope-instance: $INSTANCE_NAME"
  echo "     data: '$INSTANCE_HOME', user: '$USER'"
  echo "     http: $HTTP_PORT, ftp: $FTP_PORT, threads: $THREADS,"
  echo "     use manager: $USE_MANAGER, default: $STARTUP_MODE, wait:
$WAIT"
  echo -n "     current status: "

  # check if an instance of z2.py is running with the correct
instance-name
  HUMMING=`isHumming $INSTANCE_NAME`

  # check for a running zdaeom with the correct pid
  if [ -e $INSTANCE_HOME$ZDAEMON_PIDFILE ]; then
    ZDAEMON_PID=`cat $INSTANCE_HOME$ZDAEMON_PIDFILE`

    if [[ "`ps wax | awk '{ print $1 }' | grep $ZDAEMON_PID`" != "" ]];
then
      ZDAEMON="running"
    else
      ZDAEMON="crashed"
    fi
  else
    ZDAEMON="off_or_starting"
  fi

  # check for a running zope with the correct pid
  if [ -e $INSTANCE_HOME$ZOPE_PIDFILE ]; then
    ZOPE_PID=`cat $INSTANCE_HOME$ZOPE_PIDFILE | cut -d' ' -f2`

    if [[ "`ps wax | awk '{ print $1 }' | grep $ZOPE_PID`" != "" ]];
then
      ZOPE="running"
    else
      ZOPE="crashed"
    fi
  else
    ZOPE="off_or_starting"
  fi

  # lets make sense of what we have found
  if [[ $ZOPE == "running" ]]; then
    if [[ $ZDAEMON == "running" ]]; then
      echo "RUNNING (ZDaemon running as well)"
    else
      echo "RUNNING (without ZDaemon)"
    fi
  elif [[ $ZOPE == "crashed" ]]; then
    if [[ $ZDAEMON == "running" ]]; then
      echo "RESTARTING after crash (if all is well)"
    else
      if [[ $HUMMING = "yes" ]]; then
        echo "CRASHED, but zope is still humming (sorry, i can't figure
it out)"
      else
        echo "CRASHED, AND NOT BEING RESTARTED (ZDaemon not running)"
      fi
    fi
  elif [[ $ZOPE == "off_or_starting" ]]; then
    if [[ $HUMMING = "yes" ]]; then
      echo "BEING STARTED"
    else
      echo "NOT RUNNING"
    fi
  else
    echo "ERROR IN SCRIPT (sorry)"
  fi

  echo
}

isHumming ()
{
  INSTANCE_NAME=$1
  HUMMING=`$PS | grep -v grep | grep "z2\.py.*$INSTANCE_NAME"`

  if [[ $HUMMING != "" ]]; then
    echo "yes"
  else
    echo "no"
  fi
}

waitForStartup () 
{
  INSTANCE_NAME=$1
  TIMEOUT=300

  while [[ $TIMEOUT 0 && "`isStarted $INSTANCE_NAME`" == "no" ]]; do
    sleep 1
    echo -n '.'
    TIMEOUT=`expr $TIMEOUT - 1`
  done

  if [[ "`isStarted $INSTANCE_NAME`" == "yes" ]]; then
    echo "done"
  else
    echo "FAILED"
  fi
}

isStarted () 
{
  INSTANCE_NAME=$1

  if [ -e $INSTANCE_HOME$ZOPE_PIDFILE ]; then
    ZOPE_PID=`cat $INSTANCE_HOME$ZOPE_PIDFILE | cut -d' ' -f2`

    if [[ $ZOPE_PID != "" ]]; then
      echo "yes"
    else
      echo "no"
    fi
  else
    echo "no"
  fi
}

killAll () 
{
  kill `ps wax | grep z2.py | grep -v grep | awk '{ print $1 }'`
}

killInstance ()
{
  INSTANCE_NAME=$1
  kill `$PS | grep -v grep | grep "z2\.py.*$INSTANCE_NAME" | awk '{
print $1 }'`
}

# --- main ----

if [[ $# 1 && $2 != "-w" ]]; then
  INSTANCE=$2
else
  INSTANCE="all"
fi

if [[ $2 == "-w" || $3 == "-w" ]]; then
  WAIT=0
else
  WAIT=1    
fi

# these are our options...
case $1 in
  "start")
    startZope $INSTANCE $WAIT ;;
  "stop")
    stopZope $INSTANCE ;;
  "restart")
    restartZope $INSTANCE $WAIT ;;
  "info")
    infoZope $INSTANCE ;;
  "kill")
    killZope $INSTANCE ;;
  "-h")
    helpText
    exit 0 ;;
  *)
    echo "Unknown option '$1'"
    helpText
    exit 1

esac

And here's the conf:

# /etc/zope-instances.conf
#
# Configuration file to run zope with mulitple instances. This file is
used 
# with the /etc/init.d/zope-instances script to start and stop the zope 
# instances described below.
#
# name, data directory, user, http portnr, ftp portnr, number of
threads, manager, default

dev	/var/zope-sites/dev	zope	8082	8022    1  no	start
qat	/var/zope-sites/qat	zope	8081	-       2  no	start
prd	/var/zope-sites/prd	zope	8080	-       4  yes	start






More information about the Zope-Dev mailing list