#!/bin/sh # -*- tab-width:4;indent-tabs-mode:nil -*- # ex: ts=4 sw=4 et # /bin/sh on Solaris is not a POSIX compatible shell, but /usr/bin/ksh is. if [ `uname -s` = 'SunOS' -a "${POSIX_SHELL}" != "true" ]; then POSIX_SHELL="true" export POSIX_SHELL # To support 'whoami' add /usr/ucb to path PATH=/usr/ucb:$PATH export PATH exec /usr/bin/ksh $0 "$@" fi unset POSIX_SHELL # clear it so if we invoke other scripts, they run as ksh as well RUNNER_SCRIPT_DIR={{runner_script_dir}} RUNNER_SCRIPT=${0##*/} RUNNER_BASE_DIR={{runner_base_dir}} RUNNER_ETC_DIR={{runner_etc_dir}} RUNNER_LIB_DIR={{platform_lib_dir}} RUNNER_LOG_DIR={{runner_log_dir}} # Note the trailing slash on $PIPE_DIR/ PIPE_DIR={{pipe_dir}} RUNNER_USER={{runner_user}} PLATFORM_DATA_DIR={{platform_data_dir}} SSL_DIST_CONFIG=$PLATFORM_DATA_DIR/ssl_distribution.args_file RIAK_VERSION="git" WHOAMI=$(whoami) # Make sure this script is running as the appropriate user if ([ "$RUNNER_USER" ] && [ "x$WHOAMI" != "x$RUNNER_USER" ]); then type sudo > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "sudo doesn't appear to be installed and your EUID isn't $RUNNER_USER" 1>&2 exit 1 fi echo "Attempting to restart script through sudo -H -u $RUNNER_USER" >&2 exec sudo -H -u $RUNNER_USER -i $RUNNER_SCRIPT_DIR/$RUNNER_SCRIPT $@ fi # Warn the user if ulimit -n is less than 1024 ULIMIT_F=`ulimit -n` if [ "$ULIMIT_F" -lt 1024 ]; then echo "!!!!" echo "!!!! WARNING: ulimit -n is ${ULIMIT_F}; 1024 is the recommended minimum." echo "!!!!" fi # Make sure CWD is set to runner base dir cd $RUNNER_BASE_DIR # Make sure log directory exists mkdir -p $RUNNER_LOG_DIR # Make sure the data directory exists mkdir -p $PLATFORM_DATA_DIR # Warn the user if they don't have write permissions on the log dir if [ ! -w $RUNNER_LOG_DIR ]; then echo "!!!!" echo "!!!! WARNING: $RUNNER_LOG_DIR not writable; logs and crash dumps unavailable." echo "!!!!" fi # Extract the target node name from node.args NAME_ARG=`egrep '^\-s?name' $RUNNER_ETC_DIR/vm.args` if [ -z "$NAME_ARG" ]; then echo "vm.args needs to have either -name or -sname parameter." exit 1 fi # Extract the target cookie COOKIE_ARG=`grep '^\-setcookie' $RUNNER_ETC_DIR/vm.args` if [ -z "$COOKIE_ARG" ]; then echo "vm.args needs to have a -setcookie parameter." exit 1 fi # Identify the script name SCRIPT=`basename $0` # Parse out release and erts info START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data` ERTS_VSN=${START_ERL% *} APP_VSN=${START_ERL#* } # Add ERTS bin dir to our path ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin # Setup command to control the node NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG" NODETOOL_LITE="$ERTS_PATH/escript $ERTS_PATH/nodetool" # Common functions # Ping node without allowing nodetool to take stdin ping_node() { $NODETOOL ping < /dev/null } # Set the PID global variable, return 1 on error get_pid() { PID=`$NODETOOL getpid < /dev/null` ES=$? if [ "$ES" -ne 0 ]; then echo "Node is not running!" return 1 fi # don't allow empty or init pid's if [ -z $PID ] || [ "$PID" -le 1 ]; then return 1 fi return 0 } # Scrape out SSL distribution config info from vm.args into $SSL_DIST_CONFIG rm -f $SSL_DIST_CONFIG sed -n '/Begin SSL distribution items/,/End SSL distribution items/p' \ $RUNNER_ETC_DIR/vm.args > $SSL_DIST_CONFIG # Check the first argument for instructions case "$1" in start) # Make sure there is not already a node running RES=`ping_node` if [ "$RES" = "pong" ]; then echo "Node is already running!" exit 1 fi # Sanity check the app.config file RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/app.config` if [ $? != 0 ]; then echo "Error reading $RUNNER_ETC_DIR/app.config" echo $RES exit 1 fi HEART_COMMAND="$RUNNER_SCRIPT_DIR/$SCRIPT start" export HEART_COMMAND mkdir -p $PIPE_DIR $ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR \ "exec $RUNNER_SCRIPT_DIR/$SCRIPT console" 2>&1 # Wait for the node to come up. We can't just ping it because # distributed erlang comes up for a second before emqtt crashes # (eg. in the case of an unwriteable disk). Once the node comes # up we check for the node watcher process. If that's running # then we assume things are good enough. This will at least let # the user know when emqtt is crashing right after startup. WAIT=${WAIT_FOR_ERLANG:-15} while [ $WAIT -gt 0 ]; do WAIT=`expr $WAIT - 1` sleep 1 RES=`ping_node` if [ "$?" -ne 0 ]; then continue fi echo "emqtt is started successfully!" exit 0 done echo "emqtt failed to start within ${WAIT_FOR_ERLANG:-15} seconds," echo "see the output of 'emqtt console' for more information." echo "If you want to wait longer, set the environment variable" echo "WAIT_FOR_ERLANG to the number of seconds to wait." exit 1 ;; stop) UNAME_S=`uname -s` case $UNAME_S in Darwin) # Make sure we explicitly set this because iTerm.app doesn't for # some reason. COMMAND_MODE=unix2003 esac # Get the PID from nodetool get_pid GPR=$? if [ "$GPR" -ne 0 ] || [ -z $PID ]; then exit $GPR fi # Tell nodetool to initiate a stop $NODETOOL stop ES=$? if [ "$ES" -ne 0 ]; then exit $ES fi # Wait for the node to completely stop... while `kill -s 0 $PID 2>/dev/null`; do sleep 1 done ;; restart) ## Restart the VM without exiting the process $NODETOOL restart ES=$? if [ "$ES" -ne 0 ]; then exit $ES fi ;; reboot) ## Restart the VM completely (uses heart to restart it) $NODETOOL reboot ES=$? if [ "$ES" -ne 0 ]; then exit $ES fi ;; ping) ## See if the VM is alive ping_node ES=$? if [ "$ES" -ne 0 ]; then exit $ES fi ;; attach) if [ "$2" = "-f" ]; then echo "Forcing connection..." else # Make sure a node is running RES=`ping_node` ES=$? if [ "$ES" -ne 0 ]; then echo "Node is not running!" exit $ES fi fi shift exec $ERTS_PATH/to_erl $PIPE_DIR ;; console) RES=`ping_node` if [ "$RES" = "pong" ]; then echo "Node is already running - use '$SCRIPT attach' instead" exit 1 fi # Sanity check the app.config file RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/app.config` if [ $? != 0 ]; then echo "Error reading $RUNNER_ETC_DIR/app.config" echo $RES exit 1 fi # Setup beam-required vars ROOTDIR=$RUNNER_BASE_DIR BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin EMU=beam PROGNAME=`echo $0 | sed 's/.*\///'` CMD="$BINDIR/erlexec -boot $RUNNER_BASE_DIR/releases/$APP_VSN/$SCRIPT \ -embedded -config $RUNNER_ETC_DIR/app.config \ -pa $RUNNER_LIB_DIR/basho-patches \ -args_file $RUNNER_ETC_DIR/vm.args -- ${1+"$@"}" export EMU export ROOTDIR export BINDIR export PROGNAME # Dump environment info for logging purposes echo "Exec: $CMD" echo "Root: $ROOTDIR" # Log the startup logger -t "$SCRIPT[$$]" "Starting up" # Start the VM exec $CMD ;; chkconfig) RES=`$NODETOOL_LITE chkconfig $RUNNER_ETC_DIR/app.config` if [ $? != 0 ]; then echo "Error reading $RUNNER_ETC_DIR/app.config" echo $RES exit 1 fi echo "config is OK" ;; escript) shift $ERTS_PATH/escript "$@" ;; version) echo $RIAK_VERSION ;; getpid) # Get the PID from nodetool get_pid ES=$? if [ "$ES" -ne 0 ] || [ -z $PID ]; then exit $ES fi echo $PID ;; *) echo "Usage: $SCRIPT {start|stop|restart|reboot|ping|console|attach|chkconfig|escript|version|getpid}" exit 1 ;; esac exit 0