#!/bin/sh
#
# simplevisor-control
# 
# Control script for simplevisor: simple daemons supervisor
#

RETVAL=0

[ -r "/etc/sysconfig/simplevisor" ] && . "/etc/sysconfig/simplevisor"

CMD=${SIMPLEVISOR_CMD-`which simplevisor 2>/dev/null`}
if [ -z "${CMD}" -o ! -x "${CMD}" ]; then
    echo "simplevisor not found"
    exit 5
fi

CONF=${SIMPLEVISOR_CONF-/etc/${NAME}/${NAME}.conf}
if [ ! -r "${CONF}" ]; then
    echo "configuration file not readable"
    exit 5
fi

NAME=${SIMPLEVISOR_NAME-simplevisor}
PIDFILE=${SIMPLEVISOR_PIDFILE-/var/run/${NAME}.pid}
LOCKFILE=${SIMPLEVISOR_LOCKFILE-/var/lock/subsys/${NAME}}
MAXAGE=${SIMPLEVISOR_MAXAGE-10}
USER=${SIMPLEVISOR_USER}
if [ -n "${USER}" -a `id -un` = "${USER}" ]; then
    # no need to change user...
    USER=
fi

SUBPATH="$2"

simplevise() {
    if [ -n "${USER}" ]; then
        runuser -s /bin/sh ${USER} -c "${CMD} --pidfile ${PIDFILE} --conf ${CONF} $*"
    else
        ${CMD} --pidfile ${PIDFILE} --conf ${CONF} $*
    fi
}

start() {
    echo -n "Starting ${NAME}: "
    if [ "x${SUBPATH}" = "x" ]; then
        simplevise --daemon start
    else
        simplevise start ${SUBPATH}
    fi
    RETVAL=$?
    [ "x${SUBPATH}" != "x" ] && return
    if [ ${RETVAL} -eq 0 ]; then
        touch ${LOCKFILE}
        echo "started"
    else
        echo "failed to start, check the logs for more information"
    fi
}

status() {
    echo -n "${NAME} status: "
    simplevise status ${SUBPATH}
    RETVAL=$?
    [ "x${SUBPATH}" != "x" ] && return
    if [ ${RETVAL} -eq 0 ]; then
        ok=`find ${PIDFILE} -mmin -${MAXAGE}`
        if [ "x$ok" = "x" ]; then
            date=`date +"%Y/%m/%d-%H:%M:%S" -r ${PIDFILE}`
            echo "stuck since $date"
            RETVAL=4
        fi
    else
        echo "not running with return code ${RETVAL}"
    fi
}

stop() {
    echo -n "Stopping ${NAME}: "
    simplevise stop ${SUBPATH}
    RETVAL=$?
    [ "x${SUBPATH}" != "x" ] && return
    if [ ${RETVAL} -eq 0 ]; then
        rm -f ${LOCKFILE} ${PIDFILE}
        echo "stopped"
    else
        echo "failed to stop, check the logs for more information"
    fi
}

stop_supervisor() {
    echo -n "Stopping supervisor ${NAME}: "
    simplevise stop_supervisor
    RETVAL=$?
    if [ ${RETVAL} -eq 0 ]; then
        rm -f ${LOCKFILE} ${PIDFILE}
        echo "supervisor stopped"
    else
        echo "failed to stop supervisor, check the logs for more information"
    fi
}

restart_child() {
    echo "Restarting ${NAME} child: "
    simplevise restart_child ${SUBPATH}
    RETVAL=$?
}

check() {
    echo "Check ${NAME}: "
    simplevise check ${SUBPATH}
    RETVAL=$?
}

configtest() {
    echo "Check ${NAME} configuration: "
    simplevise check_configuration
    RETVAL=$?
}

wake_up() {
    echo "Wake up ${NAME}: "
    simplevise wake_up
    RETVAL=$?
}

usage() {
    commands="start|stop|restart|status|check|configtest|help"
    commands="${commands}|stop-supervisor|restart-supervisor|restart-child|wake-up"
    echo "Usage: ${NAME} {${commands}} [PATH]" >&2
    RETVAL=1
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  stop-supervisor)
    stop_supervisor
    ;;
  restart)
    echo "Restarting ${NAME}"
    stop
    if [ ${RETVAL} -eq 1 ]; then
        echo "skipping start action"
    else
        sleep 0.5
        start
    fi
    ;;
  restart-supervisor)
    echo "Restarting supervisor ${NAME}"
    stop_supervisor
    if [ ${RETVAL} -eq 1 ]; then
        echo "skipping start action"
    else
        sleep 0.5
        start
    fi
    ;;
  restart-child)
    restart_child
    ;;
  wake-up)
    wake_up
    ;;
  status)
    status
    ;;
  check)
    check
    ;;
  configtest)
    configtest
    ;;
  *)
    usage
    ;;
esac

exit ${RETVAL}

=head1 NAME

simplevisor-control - run simplevisor as a service

=head1 SYNOPSIS

B<simplevisor-control> command [path]

=head1 DESCRIPTION

The B<simplevisor-control> script can be used to run simplevisor as a service.

If this script is used the pidfile value specified in the simplevisor
configuration file will be ignored.

=head1 OPTIONS

B<command>
run "simplevisor-control help" to list the available commands

B<path>
look at simplevisor man page for path behavior.

=head1 EXAMPLES

On Linux you can look at the script shipped in the examples folder which is
called simplevisor-new-instance, it creates folders and the configuration to
run a simplevisor instance.

    mkdir -p /var/lib/myinstance/bin
    mkdir -p /var/lib/myinstance/data
    mkdir -p /var/lib/myinstance/etc

Create a file /var/lib/myinstance/bin/service with content and make it
executable:

    #!/bin/sh
    #
    # init script that can be symlinked from /etc/init.d
    #
    
    # chkconfig: - 90 15
    # description: my simplevisor instance
    
    . "/var/lib/myinstance/etc/simplevisor.profile"
    exec "/usr/bin/simplevisor-control" ${1+"$@"}

/var/lib/myinstance/etc/simplevisor.profile could look like:

    # main
    export SIMPLEVISOR_NAME=myinstance
    # if you want to run it as another user:
    #export SIMPLEVISOR_USER=games
    export SIMPLEVISOR_CONF=/var/lib/myinstance/etc/simplevisor.conf
    export SIMPLEVISOR_PIDFILE=/var/lib/myinstance/data/simplevisor.pid
    export SIMPLEVISOR_LOCKFILE=/var/lib/myinstance/data/simplevisor.lock

Create /var/lib/myinstance/etc/simplevisor.conf according to simplevisor
documentation.

For Red Hat or Fedora you can symlink service script:

    ln -s /var/lib/myinstance/bin/service /etc/init.d/myinstance

And use it as a normal service:

    /sbin/service myinstance start|stop|status|restart|check

=head1 AUTHOR

Massimo Paladin <massimo.paladin@gmail.com>

Copyright (C) CERN 2013-2021
