#!/bin/bash

#############################################################################
# Control script for landscape services.  Allows for operations on all the
# services at once.
############################################################################

PROG=$(basename $0)
INIT_SYSTEM=$(dpkg -S /sbin/init|cut -f 1 -d :|cut -f 1 -d -)

# Make sure only root can run our script
if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root" 1>&2
   exit 1
fi

if [[ $# -eq 0 ]]; then
    cat << EOF
Control all landscape daemons with one command.
Usage: $PROG {start|stop|restart|status}
EOF
    exit 0
fi

DEFAULT_CONF="/etc/default/landscape-server"
MAINTENANCE_FLAG="/opt/canonical/landscape/maintenance.txt"

. $DEFAULT_CONF || exit 1

# Ordered list of services as SVC_${NAME}
SERVICES=("APPSERVER" "ASYNC_FRONTEND" "JOBHANDLER" "MSGSERVER" \
          "PINGSERVER" "APISERVER" "PACKAGEUPLOADSERVER" \
          "PACKAGESEARCH")

ACTION=$1
if [ "$ACTION" = "stop" ]; then
    # reverse service order for stopping to avoid 503 errors from the UI
    REVERSE_SERVICES=$(echo ${SERVICES[@]} | tr ' ' '\n' |  tac)
    unset SERVICES
    SERVICES=${REVERSE_SERVICES[@]}
fi

# XXX When deploying in charm mode we also want to stop any batch jobs. This
#     should be eventually be the default behavior, but we trigger it
#     conditionally for sake of keeping the semantics of lsctl unchanged
#     in non-charm deployments
if [ "$DEPLOYED_FROM" = "charm" ]; then
    SERVICES=("CRON" ${SERVICES[@]})
fi

# basename of init script
SVC_APPSERVER="landscape-appserver"
SVC_ASYNC_FRONTEND="landscape-async-frontend"
SVC_JOBHANDLER="landscape-job-handler"
SVC_MSGSERVER="landscape-msgserver"
SVC_PINGSERVER="landscape-pingserver"
SVC_APISERVER="landscape-api"
SVC_PACKAGEUPLOADSERVER="landscape-package-upload"
SVC_PACKAGESEARCH="landscape-package-search"
SVC_CRON="landscape-cron"

# Wrapper around /usr/sbin/service normalizing exit values across System V
# init scripts and upstart jobs.
service_ctl () {
    local name=$1
    local action=$2
    if [ "$name" = "landscape-cron" ]; then
        case "$action" in
        "stop")
            # Prevent further jobs from triggering and wait for current ones
            # to complete.
            echo " * Waiting for Landscape cron jobs to complete"
            touch $MAINTENANCE_FLAG
            /opt/canonical/landscape/wait-batch-scripts
            echo "   ...done."
        ;;
        "start")
            echo " * Re-enabling Landscape cron jobs"
            rm -f $MAINTENANCE_FLAG
            echo "   ...done."
        ;;
        esac
        return 0
    fi
    if [ -f "/etc/init/${name}.conf" -a "$INIT_SYSTEM" = "upstart" ]; then
        local status_line=$(service $name status)
        local goal=$(echo $status_line | awk -F'[ /]' '{print $2;}')

        if [ "$action" = "$goal" ]; then
            return 0
        fi

        if [ "$action" = "status" -a "$goal" = "stop" ]; then
            echo $status_line
            return 3
        fi
    fi

    if [ -f "/lib/systemd/system/${name}.service" -a "$INIT_SYSTEM" = "systemd" ]; then
        # In case the schema check fails we want to fail gracefully and return 0,
        # which matches the behavior of both System V and Upstart scripts (see
        # also standalone/debian/landscape-server.landscape-package-search.upstart
        # and #1598016).
        if [ "$action" = "start" ] || [ "$action" = "restart" ]; then
            if ! /opt/canonical/landscape/landscape-schema-check > /dev/null 2>&1; then
                # In case of a restart, stop the service before returning gracefully.
                if [ "$action" = "restart" ]; then
                    service $name stop
                fi
                return 0
            fi
        fi
    fi

    service $name $action || status=$?

    return $status
}

final_status=0

for i in ${SERVICES[@]}; do
    svcname="SVC_${i}"
    runname="RUN_${i}"
    echo "== ${!svcname} =="
    if [[
        $RUN_ALL = "yes" || \
        ${!runname} == "yes" || \
        ${!runname} -gt 0
    ]]; then
	service_ctl ${!svcname} $ACTION || final_status=$?
    else
        echo "... Not enabled, skipping."
    fi
done

exit $final_status
