#!/bin/bash
#
# rasdaman     Startup script for the Rasdaman Server
#
# chkconfig: - 64 36
# description: Starts and stops the rasdaman server, and allows to initialize the database.
# processname: rasdaman
# config: /etc/rasdaman/rasmgr.conf
# config: /etc/sysconfig/rasdaman
# pidfile: /var/run/rasdaman.pid
#
### BEGIN INIT INFO
# Provides: rasdaman
# Required-Start: $postgresql
# Required-Stop:
# Should-Start: distcache
# Short-Description: Starts and stops the rasdaman server, and allows to initialize the database.
# Description: The rasdaman server is a raster data manager.
### END INIT INFO

# Version from spec
RASVERSION=8.4.0
# RASMAJORVERSION is major version, e.g., 8.0 (this should match RAS_VERSION)
RASMAJORVERSION=`echo "$RASVERSION" | sed 's/^\([0-9]*\.[0-9]*\).*$/\1/'`

# Names for messages
prog=rasdaman

# Source function library
. /etc/rc.d/init.d/functions
# Source variables for rasdaman
if [ -f /etc/sysconfig/rasdaman ]; then
        . /etc/sysconfig/rasdaman
fi

# Reset empty to defaults
rasmgr=${RASMGR-/usr/bin/rasmgr}
rasdl=${RASMGR-/usr/bin/rasdl}
rasctrl=${RASCONTROL-/usr/bin/rascontrol}
pidfile=${PIDFILE-/var/run/rasdaman.pid}
lockfile=${LOCKFILE-/var/lock/subsys/rasdaman}
wait_for_children=${WAIT_FOR_CHILDREN-5}
servers=${RASSERVERS-"-all"}
raslogin=${RASADMIN-rasadmin:d293a15562d3e70b6fdc5ee452eaed40}
rasdir=${RASDIR-/var/lib/rasdaman}
raslogdir=${RASLOGDIR-/var/log/rasdaman}
rasshell=${RASSHELL-/bin/bash}
petapath=${PETASCOPE_PATH-/usr/share/rasdaman/petascope}

# To check if postgres cluster was initialized
# we need this and we fetch it from our sysconfig not postgres one
PGDATA=${PGDATA-/var/lib/pgsql/data}

RETVAL=0

# For SELinux we need to use 'runuser' not 'su'
if [ -x /sbin/runuser ]
then
    SU=runuser
else
    SU=su
fi

raslog=$rasdir/startup.log
rascontrol="RASLOGIN=$raslogin $rasctrl"
deffile=$rasdir/basictypes.dl

# The semantics of these two functions differ from the way apachectl does
# things -- attempting to start while running is a failure, and shutdown
# when not running is also a failure.  So we just do it the way init scripts
# are expected to behave here.
start() {
  chown -R rasdaman:rasdaman "$raslogdir"
  # Make sure startup-time log file is valid
  if [ ! -e "$raslog" -a ! -h "$raslog" ]
  then
    touch "$raslog" || exit 1
    chown rasdaman:rasdaman "$raslog"
    chmod go-rwx "$raslog"
    [ -x /usr/bin/chcon ] && /usr/bin/chcon -u system_u -r object_r -t postgresql_log_t "$raslog" 2>/dev/null
  fi

  # Check for the PGDATA structure
  if [ -f "$PGDATA/PG_VERSION" ] && [ -d "$PGDATA/base" ]
  then
    echo
    echo $"PostgreSQL database was found."
    echo $"Version is not checked here."
    echo $"Location $PGDATA."
  else
    # No existing PGDATA! Warn the user to initdb it.
    echo
    echo "$PGDATA is missing. Use \"service rasmgr initdb\" to initialize the cluster first."
    echo "PostgreSQL database will be initialized automatically."
    echo_failure
    echo
    exit 1
  fi

  echo -n $"Starting $prog: "
  $SU -l rasdaman -s "$rasshell" -c "$rasmgr &" >> "$raslog" 2>&1 < /dev/null
  RETVAL=$?
  if [[ $RETVAL = 0 ]]
  then
    echo
    touch ${lockfile}
    pidof -s "$rasmgr" > ${pidfile}
  fi

  sleep $wait_for_children

  for SRV in $servers
  do
    echo $"$rasctrl: starting server $SRV..."
    $SU -l rasdaman -s "$rasshell" -c "$rascontrol -e -q -x up srv $SRV" >> "$raslog" 2>&1 < /dev/null
    RETVAL=$?
    if [[ $RETVAL != 0 ]]
    then
      exit $!
    fi
  done

  return $RETVAL
}

# When stopping httpd a delay of >10 second is required before SIGKILLing the
# httpd parent; this gives enough time for the httpd parent to SIGKILL any
# errant children.
stop() {
  running=`$SU -l rasdaman -s "$rasshell" -c "$rascontrol -e -q -x list srv | awk '{ if (\\$6 == \"UP\") print \\$2;}'"`
  for SRV in $running
  do
    echo $"$rasctrl: stoping server $SRV..."
    $SU -l rasdaman -s "$rasshell" -c "$rascontrol -e -q -x down srv $SRV -kill" >> "$raslog" 2>&1 < /dev/null
  done

  sleep $wait_for_children

  $SU -l rasdaman -s "$rasshell" -c "$rascontrol -e -q -x down host -all" >> "$raslog" 2>&1 < /dev/null

  RETVAL=$?

  [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

#
# Initializes RASBASE
#
initdb(){
  bhostname=`hostname`
  mv /etc/rasdaman/rasmgr.conf /etc/rasdaman/rasmgr.conf.init
  cat /etc/rasdaman/rasmgr.conf.init | sed -e "s/ -host [^ ]*/ -host $bhostname/g" > /etc/rasdaman/rasmgr.conf

  service postgresql initdb
  service postgresql start

  # create rasdaman user in postgres
  $SU -l postgres -c "createuser -d -r -S rasdaman"
  RETVAL=$?
  if [[ $RETVAL != 0 ]]
  then
    echo $"creating rasdaman user in postgres failed"
    exit $!
  fi

  # create database
  $SU -l rasdaman -s "$rasshell" -c "createdb RASBASE"
  RETVAL=$?
  if [[ $RETVAL != 0 ]]
  then
    echo $"creating RASBASE in postgres failed"
    exit $!
  fi

  # insert type definitions
  $SU -l rasdaman -s "$rasshell" -c "$rasdl -c --connect RASBASE && $rasdl -r $deffile -i --connect RASBASE"
  RETVAL=$?
  if [[ $RETVAL != 0 ]]
  then
    echo $"inserting type definitions to rasdaman with rasdl failed"
    exit $!
  fi
}

#
# Update RASBASE
#
updatedb()
{
  $SU -l rasdaman -s "$rasshell" -c "update_db.sh"
}

#
# Initializes/updates the petascope database
#
initpetascopedb(){
  # determine tomcat user, seems to vary between different distributions
  tomcat_user=`grep -i tomcat /etc/passwd | awk -F ':' '{ print $1; }' | head -n 1`
  if [ -z "$tomcat_user" ]; then
    tomcat_user="tomcat6"
  fi

  # update petascope user in configuration, unless the user has changed it
  grep 'metadata_user=tomcat6' /etc/rasdaman/petascope.properties > /dev/null
  if [ $? -ne 0 ]; then
    sed -i 's/^metadata_user=.\+/metadata_user='$tomcat_user'/' /etc/rasdaman/petascope.properties
  fi

  # create petascope user in postgres if it isn't already created
  $SU -l postgres -s "$rasshell" -c "psql -c 'SELECT * FROM pg_user'" | grep "$tomcat_user" > /dev/null
  if [ $? -ne 0 ]; then
    echo creating user
    $SU -l postgres -c "createuser -SRd $tomcat_user"
    RETVAL=$?
    if [[ $RETVAL != 0 ]]
    then
      echo $"creating petascope user in postgres failed"
      exit $!
    fi
  fi

  $SU -l $tomcat_user -s "$rasshell" -c "update_petascopedb.sh"
}

#
# Drop RASBASE
#
dropdb(){
  echo dropping RASBASE...
  $SU -l rasdaman -s "$rasshell" -c "dropdb RASBASE"
  RETVAL=$?
  if [[ $RETVAL != 0 ]]
  then
    echo $"dropdb failed"
    exit $!
  fi
  echo dropping user...
  $SU -l postgres -s "$rasshell" -c "dropuser rasdaman"
  RETVAL=$?
  if [[ $RETVAL != 0 ]]
  then
    echo $"drop user failed"
    exit $!
  fi
}

#
# Drop the petascope database
#
droppetascopedb(){
  echo dropping petascopedb...
  $SU -l postgres -s "$rasshell" -c "dropdb petascopedb"
  RETVAL=$?
  if [[ $RETVAL != 0 ]]
  then
    echo $"dropdb failed"
    exit $!
  fi
}

# See how we were called.
case "$1" in
  start)
  start
  ;;
  stop)
  stop
  ;;
  status)
  status -p ${pidfile} $rasmgr
  $SU -l rasdaman -s "$rasshell" -c "$rascontrol -e -q -x list srv"
  RETVAL=$?
  ;;
  restart)
  stop
  start
  ;;
  condrestart)
  if status -p ${pidfile} $rasmgr >&/dev/null; then
    stop
    start
  fi
  ;;
  initdb)
  initdb
  ;;
  updatedb)
  updatedb
  ;;
  initpetascopedb)
  initpetascopedb
  ;;
  updatepetascopedb)
  initpetascopedb
  ;;
  dropdb)
  dropdb
  ;;
  droppetascopedb)
  droppetascopedb
  ;;
  *)
  echo $"Usage: $prog {start|stop|restart|condrestart|status|"
  echo $"                 initdb|updatedb|dropdb|"
  echo $"                 initpetascopedb|updatepetascopedb|droppetascopedb}"
  RETVAL=3
esac

exit $RETVAL
