#!/bin/bash
# Wrapper around /sbin/service command.
#
# Some services do not start or stop properly and return non-zero values
# for some commands. To test it try this quick sequence:
#
#   service xxx start
#   service xxx status
#   service xxx stop
#   service xxx status
#
# This simple wrapper works with any service and just pass over the request
# to /sbin/service, but for few problematic ones it waits until service is
# fully started or stopped.
#
# To test the implementation use:
#
#   service-wait xxx test-wait
#
SERVICE=$1
COMMAND=$2

[ -f /etc/sysconfig/service-wait ] && source "/etc/sysconfig/service-wait"

# maximum time to wait (in seconds)
WAIT_MAX=${WAIT_MAX:-30}
RETRY_INTERVAL=${RETRY_INTERVAL:-1}
TOMCAT_PORT=${TOMCAT_PORT:-8443}
TOMCAT_SERV_PORT=${TOMCAT_SERV_PORT:-8005}
TOMCAT_TEST_URL=${TOMCAT_TEST_URL:-https://localhost:$TOMCAT_PORT/candlepin/status}
MONGO_PORT=${MONGO_PORT:-27017}
POSTGRES_PORT=${POSTGRES_PORT:-5432}
POSTGRES_DATA=${POSTGRES_DATA:-/var/lib/pgsql/data}
FOREMAN_TEST_URL=${FOREMAN_TEST_URL:-http://localhost:5500/foreman/api}
KATELLO_TEST_URL=${KATELLO_TEST_URL:-http://localhost:5000/katello/api}

# for some services we add few extra seconds after start
ADDITIONAL_SLEEP=5

wait_for_url() {
  RETVAL=5
  tries=0

  while [[ $RETVAL -ne 0 && $tries -lt $WAIT_MAX ]]; do
    tries=$((tries + 1))
    /usr/bin/curl -ks --noproxy '*' $1 > /dev/null
    RETVAL=$?
    sleep $RETRY_INTERVAL
  done
}

# before start or restart
before_start() {
  test 1 -eq 1 # noop
}

# after start or restart
after_start() {
  case "$SERVICE" in
    tomcat|tomcat6)
      # RHBZ 789288 - wait until data port is avaiable
      wait_for_url $TOMCAT_TEST_URL
      ;;
    foreman)
      wait_for_url $FOREMAN_TEST_URL
      ;;
    katello)
      wait_for_url $KATELLO_TEST_URL
      ;;
    mongod)
      # RHBZ 824405 - wait until service is avaiable
      for i in {1..$WAIT_MAX}; do mongo --eval "printjson(db.getCollectionNames())" 2>/dev/null 1>&2 && break; sleep 1; done
      sleep $ADDITIONAL_SLEEP
      ;;
    postgresql)
      # RHBZ 800534 for RHEL 6.x - pg sysvinit script return non-zero when PID is not created in 2 seconds
      RETVAL=0
      # and wait until port is really avaiable
      for i in {1..$WAIT_MAX}; do netstat -ln | grep -q ":$POSTGRES_PORT\s" && break; sleep 1; done
      # and create lock and pid files if they does not exist
      [ -f "/var/lock/subsys/postgresql" ] || touch "/var/lock/subsys/postgresql"
      [ -f "/var/run/postmaster.${POSTGRES_PORT}.pid" ] || head -n 1 "$POSTGRES_DATA/postmaster.pid" > "/var/run/postmaster.${POSTGRES_PORT}.pid"
      sleep $ADDITIONAL_SLEEP
      ;;
    httpd)
      sleep $ADDITIONAL_SLEEP
      ;;
  esac
}

before_stop() {
  case "$SERVICE" in
    tomcat6|tomcat)
      # RHBZ 789288 - wait until service port is avaiable
      for i in {1..$WAIT_MAX}; do netstat -ln | grep -q ":$TOMCAT_SERV_PORT\s" && break; sleep 1; done
      ;;
  esac
}

after_stop() {
  test 1 -eq 1 # noop
}

before_status() {
  test 1 -eq 1 # noop
}

after_status() {
  test 1 -eq 1 # noop
}

case "$COMMAND" in
  start)
    before_start
    /sbin/service "$SERVICE" "$COMMAND"
    RETVAL=$?
    after_start
    ;;
  stop)
    before_stop
    /sbin/service "$SERVICE" "$COMMAND"
    RETVAL=$?
    after_stop
    ;;
  restart)
    before_start
    /sbin/service "$SERVICE" "$COMMAND"
    RETVAL=$?
    after_start
    ;;
  status)
    before_status
    /sbin/service "$SERVICE" "$COMMAND"
    RETVAL=$?
    after_status
    ;;
  test-wait)
    echo -n "Starting $SERVICE... "
    /usr/sbin/service-wait "$SERVICE" "start" >/dev/null 2>&1
    [ $? -eq 0 ] && echo "OK" || echo "FAIL"
    echo -n "Querying $SERVICE... "
    /usr/sbin/service-wait "$SERVICE" "status" >/dev/null 2>&1
    [ $? -eq 0 ] && echo "OK" || echo "FAIL"
    echo -n "Stopping $SERVICE... "
    /usr/sbin/service-wait "$SERVICE" "stop" >/dev/null 2>&1
    [ $? -eq 0 ] && echo "OK" || echo "FAIL"
    echo -n "Querying $SERVICE... "
    /usr/sbin/service-wait "$SERVICE" "status" >/dev/null 2>&1
    [ ! $? -eq 0 ] && echo "OK" || echo "FAIL"
    echo -n "Starting $SERVICE... "
    /usr/sbin/service-wait "$SERVICE" "start" >/dev/null 2>&1
    [ $? -eq 0 ] && echo "OK" || echo "FAIL"
    echo -n "Querying $SERVICE... "
    /usr/sbin/service-wait "$SERVICE" "status" >/dev/null 2>&1
    [ $? -eq 0 ] && echo "OK" || echo "FAIL"
    echo -n "Stopping $SERVICE... "
    /usr/sbin/service-wait "$SERVICE" "stop" >/dev/null 2>&1
    [ $? -eq 0 ] && echo "OK" || echo "FAIL"
    ;;
  *)
    /sbin/service $1 $2
    RETVAL=$?
esac

exit $RETVAL
