#!/bin/sh
# ================================================================
#  pulp_celerybeat - Starts Pulp's Celery periodic task scheduler.
# ================================================================
#
# :Usage: /etc/init.d/pulp_celerybeat {start|stop|force-reload|restart|try-restart|status}
# :Configuration file: /etc/default/pulp_celerybeat or /etc/default/pulp_workers
#
# See http://docs.celeryproject.org/en/latest/tutorials/daemonizing.html#generic-init-scripts

### BEGIN INIT INFO
# Provides:          pulp_celerybeat
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop:     $network $local_fs $remote_fs
# Should-Start:      mongod qpidd rabbitmq-server
# Default-Start:     3 4 5
# Default-Stop:      0 1 2 6
# Short-Description: pulp's celery periodic task scheduler
### END INIT INFO

# Cannot use set -e/bash -e since the kill -0 command will abort
# abnormally in the absence of a valid process ID.
#set -e
VERSION=10.0
echo "celery init v${VERSION}."

if [ "$EUID" != "0" ]; then
    echo "Error: This program can only be used by the root user."
    echo "       Unprivileged users must use 'celery beat --detach'"
    exit 1
fi


# May be a runlevel symlink (e.g. S02celeryd)
if [ -L "$0" ]; then
    SCRIPT_FILE=$(readlink "$0")
else
    SCRIPT_FILE="$0"
fi
SCRIPT_NAME="$(basename "$SCRIPT_FILE")"

# /etc/init.d/pulp_celerybeat: start and stop the celery periodic task scheduler daemon.


scripts=""

if test -f /etc/default/pulp_workers; then
    scripts="/etc/default/pulp_workers"
    . /etc/default/pulp_workers
fi

EXTRA_CONFIG="/etc/default/${SCRIPT_NAME}"
if test -f "$EXTRA_CONFIG"; then
    scripts="$scripts, $EXTRA_CONFIG"
    . "$EXTRA_CONFIG"
fi

echo "Using configuration: $scripts"

CELERY_BIN=${CELERY_BIN:-"celery"}
DEFAULT_USER="celery"
DEFAULT_PID_FILE="/var/run/pulp/celerybeat.pid"
DEFAULT_LOG_FILE="/var/log/pulp/celerybeat.log"
DEFAULT_LOG_LEVEL="INFO"
DEFAULT_CELERYBEAT="$CELERY_BIN beat"

CELERYBEAT=${CELERYBEAT:-$DEFAULT_CELERYBEAT}
CELERYBEAT_LOG_LEVEL=${CELERYBEAT_LOG_LEVEL:-${CELERYBEAT_LOGLEVEL:-$DEFAULT_LOG_LEVEL}}


CELERYBEAT_USER=${CELERYBEAT_USER:-${CELERYD_USER:-$DEFAULT_USER}}

# Set CELERY_CREATE_DIRS to always create log/pid dirs.
CELERY_CREATE_DIRS=${CELERY_CREATE_DIRS:-0}
CELERY_CREATE_RUNDIR=$CELERY_CREATE_DIRS
CELERY_CREATE_LOGDIR=$CELERY_CREATE_DIRS
if [ -z "$CELERYBEAT_PID_FILE" ]; then
    CELERYBEAT_PID_FILE="$DEFAULT_PID_FILE"
    CELERY_CREATE_RUNDIR=1
fi
if [ -z "$CELERYBEAT_LOG_FILE" ]; then
    CELERYBEAT_LOG_FILE="$DEFAULT_LOG_FILE"
    CELERY_CREATE_LOGDIR=1
fi

export CELERY_LOADER

CELERYBEAT_OPTS="$CELERYBEAT_OPTS -f $CELERYBEAT_LOG_FILE -l $CELERYBEAT_LOG_LEVEL"

if [ -n "$2" ]; then
    CELERYBEAT_OPTS="$CELERYBEAT_OPTS $2"
fi

CELERYBEAT_LOG_DIR=`dirname $CELERYBEAT_LOG_FILE`
CELERYBEAT_PID_DIR=`dirname $CELERYBEAT_PID_FILE`

# Extra start-stop-daemon options, like user/group.

CELERYBEAT_CHDIR=${CELERYBEAT_CHDIR:-$CELERYD_CHDIR}
if [ -n "$CELERYBEAT_CHDIR" ]; then
    DAEMON_OPTS="$DAEMON_OPTS --workdir=$CELERYBEAT_CHDIR"
fi


export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

check_dev_null() {
    if [ ! -c /dev/null ]; then
        echo "/dev/null is not a character device!"
        exit 75  # EX_TEMPFAIL
    fi
}

maybe_die() {
    if [ $? -ne 0 ]; then
        echo "Exiting: $*"
        exit 77  # EX_NOPERM
    fi
}

create_default_dir() {
    if [ ! -d "$1" ]; then
        echo "- Creating default directory: '$1'"
        mkdir -p "$1"
        maybe_die "Couldn't create directory $1"
        echo "- Changing permissions of '$1' to 02750"
        chmod 02750 "$1"
        maybe_die "Couldn't change permissions for $1"
        if [ -n "$CELERYBEAT_USER" ]; then
            echo "- Changing owner of '$1' to '$CELERYBEAT_USER'"
            chown "$CELERYBEAT_USER" "$1"
            maybe_die "Couldn't change owner of $1"
        fi
        if [ -n "$CELERYBEAT_GROUP" ]; then
            echo "- Changing group of '$1' to '$CELERYBEAT_GROUP'"
            chgrp "$CELERYBEAT_GROUP" "$1"
            maybe_die "Couldn't change group of $1"
        fi
        echo "- Restoring context of $1 to 'pulp_var_run_t'"
        restorecon /var/run/pulp
        maybe_die "Couldn't restore context of $1"
    fi
}

check_paths() {
    if [ $CELERY_CREATE_LOGDIR -eq 1 ]; then
        create_default_dir "$CELERYBEAT_LOG_DIR"
    fi
    if [ $CELERY_CREATE_RUNDIR -eq 1 ]; then
        create_default_dir "$CELERYBEAT_PID_DIR"
    fi
}


check_status() {
    if [ ! -e $CELERYBEAT_PID_FILE ]; then
        local pid=
    else
        local pid=`cat "$CELERYBEAT_PID_FILE"`
    fi

    if [ -z "$pid" ]; then
        echo "${SCRIPT_NAME} is stopped."
        exit 1
    fi
    local failed=
    kill -0 $pid 2> /dev/null || failed=true
    if [ "$failed" ]; then
        echo "${SCRIPT_NAME} is missing."
        exit 1
    fi
    echo "${SCRIPT_NAME} (pid $pid) is running."
    exit 0
}


create_paths () {
    create_default_dir "$CELERYBEAT_LOG_DIR"
    create_default_dir "$CELERYBEAT_PID_DIR"
}


wait_pid () {
    pid=$1
    forever=1
    i=0
    while [ $forever -gt 0 ]; do
        kill -0 $pid 1>/dev/null 2>&1
        if [ $? -eq 1 ]; then
            echo "OK"
            forever=0
        else
            kill -TERM "$pid"
            i=$((i + 1))
            if [ $i -gt 60 ]; then
                echo "ERROR"
                echo "Timed out while stopping (30s)"
                forever=0
            else
                sleep 0.5
            fi
        fi
    done
}


stop_beat () {
    echo -n "Stopping ${SCRIPT_NAME}... "
    if [ -f "$CELERYBEAT_PID_FILE" ]; then
        wait_pid $(cat "$CELERYBEAT_PID_FILE")
    else
        echo "NOT RUNNING"
    fi
}

_chuid () {
    su - "$CELERYBEAT_USER" -s /bin/sh -c "$CELERYBEAT $*"
}

start_beat () {
    echo "Starting ${SCRIPT_NAME}..."
    _chuid --app=$CELERYBEAT_APP --scheduler=$CELERYBEAT_SCHEDULER $CELERYBEAT_OPTS $DAEMON_OPTS --detach \
                --pidfile="$CELERYBEAT_PID_FILE"
}

# this function implements the fix for bz #1145723
write_log_message () {
  touch $CELERYBEAT_LOG_FILE && chown $CELERYD_USER $CELERYBEAT_LOG_FILE
  chmod 640 $CELERYBEAT_LOG_FILE
  echo -n `date "+%Y-%m-%d %T"` >> $CELERYBEAT_LOG_FILE
  echo " $1" >> $CELERYBEAT_LOG_FILE
}



case "$1" in
    start)
        check_dev_null
        check_paths
        write_log_message "**********************************************************"
        write_log_message "* Celerybeat startup requested. After startup is         *"
        write_log_message "* complete, messages will be logged to /var/log/messages.*"
        write_log_message "**********************************************************"
        start_beat
    ;;
    stop)
        check_paths
        stop_beat
    ;;
    reload|force-reload)
        echo "Use start+stop"
    ;;
    restart)
        echo "Restarting celery periodic task scheduler"
        check_paths
        stop_beat
        check_dev_null
        write_log_message "**********************************************************"
        write_log_message "* Celerybeat startup requested. After startup is         *"
        write_log_message "* complete, messages will be logged to /var/log/messages.*"
        write_log_message "**********************************************************"
        start_beat
    ;;
    status)
        check_status
    ;;
    create-paths)
        check_dev_null
        create_paths
    ;;
    check-paths)
        check_dev_null
        check_paths
    ;;
    *)
        echo "Usage: /etc/init.d/${SCRIPT_NAME} {start|stop|restart|status|create-paths|check-paths}"
        exit 64  # EX_USAGE
    ;;
esac

exit 0
