#!/bin/sh
#-*-Mode:sh;coding:utf-8;tab-width:4;c-basic-offset:4;indent-tabs-mode:()-*-
# ex: set ft=sh fenc=utf-8 sts=4 ts=4 sw=4 et nomod:

# Name of the running pid (argv[0])
PID_NAME=CloudI
# Name of this file
PROGNAME=cloudi

CLOUDI_UMASK="@CLOUDI_UMASK@"
CLOUDI_PID_FILE="@CLOUDI_PID_FILE@"
CLOUDI_NODE_NAME="@CLOUDI_NODE_NAME@"
ROOTDIR="@cloudi_prefix@"
BINDIR="$ROOTDIR/erts-@ERLANG_ERTS_VER@/bin"
EMU=beam
RELEASEDIR="$ROOTDIR/releases/@CLOUDI_CORE_RELEASE_VERSION@"
ROOT_BIN_DIR="$ROOTDIR/bin"
ROOT_ETC_DIR="$ROOTDIR/etc"
ROOT_LOG_DIR="$ROOTDIR/logs"
PROGNAME_FILE="$ROOT_BIN_DIR/$PROGNAME"
VMARGS_FILE="$ROOT_ETC_DIR/vm.args"
ERLCONFIG_FILE="$ROOT_ETC_DIR/vm.config"
TMPDIR="/tmp/$CLOUDI_NODE_NAME"
PIPE_DIR="$TMPDIR/shell/"
RUN_ERL_LOG_ACTIVITY_MINUTES="5"
RUN_ERL_LOG_ALIVE_MINUTES="15"
RUN_ERL_LOG_ALIVE_IN_UTC="1"
RUN_ERL_LOG_ALIVE_FORMAT="%Y-%m-%dT%H:%M:%SZ"
RUN_ERL_LOG_GENERATIONS="128"
RUN_ERL_LOG_MAXSIZE="536870912"
RUN_ERL_DISABLE_FLOWCNTRL="true"
ERL_CRASH_DUMP="erl_crash.dump"
ERL_AFLAGS=""
ERL_ZFLAGS=""
ERL_FLAGS=""
ERL_LIBS=""
ERL_COMPILER_OPTIONS="[]"
ERL_EPMD_ADDRESS=""
ERL_EPMD_PORT="4369"

# Default umask (u=rwx,g=rx,o=), if it wasn't provided to the configure script
if [ -z "$CLOUDI_UMASK" ]; then
    CLOUDI_UMASK="0027"
fi

# Default pid file path, if it wasn't provided to the configure script
if [ -z "$CLOUDI_PID_FILE" ]; then
    CLOUDI_PID_FILE="$ROOT_LOG_DIR/$CLOUDI_NODE_NAME.pid"
fi

# If the CloudI configuration causes a Distributed Erlang node connection to be
# attempted during a stop or restart
# (e.g., in cloudi_core_i_nodes.erl or nodefinder, due to the use of
#  net_kernel:connect_node/1 or net_kernel:hidden_connect_node/1),
# net_kernel source code will cause a delay based on the net_setuptime
# value that defaults to 7 seconds (it will take longer than 7 seconds).
#
# The SHUTDOWN_TIME_MAX value provides the maximum time a stop or restart
# will take
# (within the Erlang VM source code,
#  it can take ~10 seconds longer than that value).
#
# based on TIMEOUT_TERMINATE_MAX in cloudi_core_i_constants.hrl (milliseconds)
SHUTDOWN_TIME_MAX=65000

# default -heart timeout in seconds
HEART_BEAT_TIMEOUT=60

# wait indefinitely until the crash dump is completely written
ERL_CRASH_DUMP_SECONDS=-1

# Create nodetool command-line
NODETOOL="$BINDIR/escript $ROOT_BIN_DIR/nodetool"

# Common erl command-line arguments enforced on any vm.args file use
VMARGS="-mode embedded -shutdown_time $SHUTDOWN_TIME_MAX"

umask "$CLOUDI_UMASK"

# Any erl_crash.dump or core files will be created in the log directory
cd "$ROOT_LOG_DIR"

# CloudI epmd settings
export ERL_EPMD_ADDRESS
export ERL_EPMD_PORT
unset ERL_EPMD_RELAXED_COMMAND_CHECK
# Ensure epmd is running
$BINDIR/epmd -daemon -port "$ERL_EPMD_PORT"
if [ $? -ne 0 ]; then
    echo "EPMD failed to start!"
    exit 1
fi

case "$1" in
    start)
        # Make sure there is not already a node running
        $NODETOOL test
        if [ $? -eq 0 ]; then
            echo "Node is already running!"
            exit 1
        fi
        START_OPTION="console"
        HEART_OPTION="start"
        # CloudI run_erl logging settings
        export RUN_ERL_LOG_ACTIVITY_MINUTES
        export RUN_ERL_LOG_ALIVE_MINUTES
        export RUN_ERL_LOG_ALIVE_IN_UTC
        export RUN_ERL_LOG_ALIVE_FORMAT
        export RUN_ERL_LOG_GENERATIONS
        export RUN_ERL_LOG_MAXSIZE
        export RUN_ERL_DISABLE_FLOWCNTRL
        # OS process name created by run_erl
        export ESCRIPT_NAME="$PID_NAME"
        # CloudI environment variable settings
        export TMPDIR

        # accumulate start command-line for future execution
        RUN_PARAM="'$@'"

        export HEART_COMMAND="$PROGNAME_FILE $HEART_OPTION $RUN_PARAM"
        rm -rf "$TMPDIR"
        mkdir "$TMPDIR"
        chmod 700 "$TMPDIR"
        mkdir "$PIPE_DIR"
        chmod 700 "$PIPE_DIR"
        $BINDIR/run_erl -daemon "$PIPE_DIR" "$ROOT_LOG_DIR" "exec $PROGNAME_FILE $START_OPTION $RUN_PARAM" 2>&1
        ;;
    stop)
        # Wait for the node to completely stop
        $NODETOOL stop
        if [ $? -eq 0 -a -f "$CLOUDI_PID_FILE" ]; then
            PID=`cat "$CLOUDI_PID_FILE"`
            while `kill -0 "$PID" 2>/dev/null`;
            do
                sleep 1
            done
        fi

        # Remove the pid file
        rm -f "$CLOUDI_PID_FILE"
        # Remove temporary data directory
        rm -rf "$TMPDIR"
        ;;
    restart)
        # Restart the VM without exiting the process
        $NODETOOL restart
        exit $?
        ;;
    reboot)
        # Restart the VM completely (uses heart to restart it)
        $NODETOOL reboot
        exit $?
        ;;
    test)
        # Test if the VM is alive without any output
        $NODETOOL test
        exit $?
        ;;
    ping)
        # See if the VM is alive
        $NODETOOL ping
        exit $?
        ;;
    attach)
        # Make sure a node IS running
        $NODETOOL test
        if [ $? -ne 0 ]; then
            echo "Node is not running!"
            exit 1
        fi

        exec "$BINDIR/to_erl" "$PIPE_DIR"
        ;;
    remote_console)
        # Make sure a node IS running
        REMSH=`$NODETOOL args_remsh`
        if [ $? -ne 0 ]; then
            echo "Node is not running!"
            exit 1
        fi
        # CloudI erl settings
        export ERL_CRASH_DUMP
        export ERL_CRASH_DUMP_SECONDS
        unset ERL_CRASH_DUMP_NICE
        unset ERL_CRASH_DUMP_BYTES
        export ERL_AFLAGS
        export ERL_ZFLAGS
        export ERL_FLAGS
        export ERL_LIBS
        export ERL_COMPILER_OPTIONS

        eval exec "$BINDIR/erl" $REMSH
        ;;
    console)
        BOOTFILE="$PROGNAME"
        # CloudI erl settings
        export ERL_CRASH_DUMP
        export ERL_CRASH_DUMP_SECONDS
        unset ERL_CRASH_DUMP_NICE
        unset ERL_CRASH_DUMP_BYTES
        export ERL_AFLAGS
        export ERL_ZFLAGS
        export ERL_FLAGS
        export ERL_LIBS
        export ERL_COMPILER_OPTIONS
        # erl -heart settings
        export HEART_BEAT_TIMEOUT
        export HEART_KILL_SIGNAL=SIGKILL
        export HEART_NO_KILL=TRUE

        # Setup beam-required vars
        CMD="$BINDIR/erlexec -boot $RELEASEDIR/$BOOTFILE -config $ERLCONFIG_FILE -args_file $VMARGS_FILE $VMARGS"
        export EMU
        export ROOTDIR
        export BINDIR
        export PROGNAME

        # Dump the environment info to the console log
        echo "Exec: $CMD" -- ${1+"$@"}
        echo "Root: $ROOTDIR"

        # Store the pid
        echo $$ > "$CLOUDI_PID_FILE"

        # Start the VM
        exec $CMD -- ${1+"$@"}
        ;;
    *)
        echo "Usage: $PROGNAME {start|stop|restart|reboot|test|ping|console|attach|remote_console}"
        exit 1
        ;;
esac

