|
@ -2,25 +2,41 @@ |
|
|
# -*- tab-width:4;indent-tabs-mode:nil -*- |
|
|
# -*- tab-width:4;indent-tabs-mode:nil -*- |
|
|
# ex: ts=4 sw=4 et |
|
|
# 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 |
|
|
|
|
|
|
|
|
|
|
|
# clear it so if we invoke other scripts, they run as ksh |
|
|
|
|
|
unset POSIX_SHELL |
|
|
|
|
|
|
|
|
RUNNER_SCRIPT_DIR=$(cd ${0%/*} && pwd -P) |
|
|
RUNNER_SCRIPT_DIR=$(cd ${0%/*} && pwd -P) |
|
|
|
|
|
|
|
|
|
|
|
CALLER_DIR=$PWD |
|
|
|
|
|
|
|
|
RUNNER_BASE_DIR=${RUNNER_SCRIPT_DIR%/*} |
|
|
RUNNER_BASE_DIR=${RUNNER_SCRIPT_DIR%/*} |
|
|
RUNNER_ETC_DIR=$RUNNER_BASE_DIR/etc |
|
|
RUNNER_ETC_DIR=$RUNNER_BASE_DIR/etc |
|
|
RUNNER_LOG_DIR=$RUNNER_BASE_DIR/log |
|
|
|
|
|
# Note the trailing slash on $PIPE_DIR/ |
|
|
# Note the trailing slash on $PIPE_DIR/ |
|
|
PIPE_DIR=/tmp/$RUNNER_BASE_DIR/ |
|
|
PIPE_DIR=/tmp/$RUNNER_BASE_DIR/ |
|
|
RUNNER_USER= |
|
|
RUNNER_USER= |
|
|
|
|
|
WHOAMI=$(whoami) |
|
|
|
|
|
|
|
|
# Make sure this script is running as the appropriate user |
|
|
# Make sure this script is running as the appropriate user |
|
|
if [ ! -z "$RUNNER_USER" ] && [ `whoami` != "$RUNNER_USER" ]; then |
|
|
|
|
|
exec sudo -u $RUNNER_USER -i $0 $@ |
|
|
|
|
|
|
|
|
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 |
|
|
fi |
|
|
|
|
|
|
|
|
# Make sure CWD is set to runner base dir |
|
|
|
|
|
cd $RUNNER_BASE_DIR |
|
|
|
|
|
|
|
|
|
|
|
# Make sure log directory exists |
|
|
|
|
|
mkdir -p $RUNNER_LOG_DIR |
|
|
|
|
|
# Identify the script name |
|
|
# Identify the script name |
|
|
SCRIPT=`basename $0` |
|
|
SCRIPT=`basename $0` |
|
|
|
|
|
|
|
@ -29,22 +45,37 @@ START_ERL=`cat $RUNNER_BASE_DIR/releases/start_erl.data` |
|
|
ERTS_VSN=${START_ERL% *} |
|
|
ERTS_VSN=${START_ERL% *} |
|
|
APP_VSN=${START_ERL#* } |
|
|
APP_VSN=${START_ERL#* } |
|
|
|
|
|
|
|
|
# Use releases/VSN/vm.args if it exists otherwise use etc/vm.args |
|
|
|
|
|
if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args" ]; then |
|
|
|
|
|
VMARGS_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args" |
|
|
|
|
|
|
|
|
# Use $CWD/vm.args if exists, otherwise releases/APP_VSN/vm.args, or |
|
|
|
|
|
# else etc/vm.args |
|
|
|
|
|
if [ -e "$CALLER_DIR/vm.args" ]; then |
|
|
|
|
|
VMARGS_PATH=$CALLER_DIR/vm.args |
|
|
|
|
|
USE_DIR=$CALLER_DIR |
|
|
else |
|
|
else |
|
|
VMARGS_PATH="$RUNNER_ETC_DIR/vm.args" |
|
|
|
|
|
|
|
|
USE_DIR=$RUNNER_BASE_DIR |
|
|
|
|
|
if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args" ]; then |
|
|
|
|
|
VMARGS_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/vm.args" |
|
|
|
|
|
else |
|
|
|
|
|
VMARGS_PATH="$RUNNER_ETC_DIR/vm.args" |
|
|
|
|
|
fi |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
RUNNER_LOG_DIR=$USE_DIR/log |
|
|
|
|
|
# Make sure log directory exists |
|
|
|
|
|
mkdir -p $RUNNER_LOG_DIR |
|
|
|
|
|
|
|
|
# Use releases/VSN/sys.config if it exists otherwise use etc/app.config |
|
|
# Use releases/VSN/sys.config if it exists otherwise use etc/app.config |
|
|
if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config" ]; then |
|
|
|
|
|
CONFIG_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config" |
|
|
|
|
|
|
|
|
if [ -e "$USE_DIR/sys.config" ]; then |
|
|
|
|
|
CONFIG_PATH="$USE_DIR/sys.config" |
|
|
else |
|
|
else |
|
|
CONFIG_PATH="$RUNNER_ETC_DIR/app.config" |
|
|
|
|
|
|
|
|
if [ -e "$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config" ]; then |
|
|
|
|
|
CONFIG_PATH="$RUNNER_BASE_DIR/releases/$APP_VSN/sys.config" |
|
|
|
|
|
else |
|
|
|
|
|
CONFIG_PATH="$RUNNER_ETC_DIR/app.config" |
|
|
|
|
|
fi |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
# Extract the target node name from node.args |
|
|
# Extract the target node name from node.args |
|
|
NAME_ARG=`egrep '^-s?name' $VMARGS_PATH` |
|
|
|
|
|
|
|
|
NAME_ARG=`egrep '^\-s?name' $VMARGS_PATH` |
|
|
if [ -z "$NAME_ARG" ]; then |
|
|
if [ -z "$NAME_ARG" ]; then |
|
|
echo "vm.args needs to have either -name or -sname parameter." |
|
|
echo "vm.args needs to have either -name or -sname parameter." |
|
|
exit 1 |
|
|
exit 1 |
|
@ -54,17 +85,24 @@ fi |
|
|
REMSH_TYPE=`echo $NAME_ARG | awk '{print $1}'` |
|
|
REMSH_TYPE=`echo $NAME_ARG | awk '{print $1}'` |
|
|
REMSH_NAME=`echo $NAME_ARG | awk '{print $2}'` |
|
|
REMSH_NAME=`echo $NAME_ARG | awk '{print $2}'` |
|
|
|
|
|
|
|
|
# Note the `date +%s`, used to allow multiple remsh to the same node transparently |
|
|
|
|
|
REMSH_NAME_ARG="$REMSH_TYPE attach`date +%s`@`echo $REMSH_NAME | awk -F@ '{print $2}'`" |
|
|
|
|
|
|
|
|
# Note the `date +%s`, used to allow multiple remsh to the same node |
|
|
|
|
|
# transparently |
|
|
|
|
|
REMSH_NAME_ARG="$REMSH_TYPE remsh`date +%s`@`echo $REMSH_NAME | awk -F@ '{print $2}'`" |
|
|
REMSH_REMSH_ARG="-remsh $REMSH_NAME" |
|
|
REMSH_REMSH_ARG="-remsh $REMSH_NAME" |
|
|
|
|
|
|
|
|
# Extract the target cookie |
|
|
# Extract the target cookie |
|
|
COOKIE_ARG=`grep '^-setcookie' $VMARGS_PATH` |
|
|
|
|
|
|
|
|
COOKIE_ARG=`grep '^\-setcookie' $VMARGS_PATH` |
|
|
if [ -z "$COOKIE_ARG" ]; then |
|
|
if [ -z "$COOKIE_ARG" ]; then |
|
|
echo "vm.args needs to have a -setcookie parameter." |
|
|
echo "vm.args needs to have a -setcookie parameter." |
|
|
exit 1 |
|
|
exit 1 |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
|
|
|
# Make sure CWD is set to the right dir |
|
|
|
|
|
cd $USE_DIR |
|
|
|
|
|
|
|
|
|
|
|
# Make sure log directory exists |
|
|
|
|
|
mkdir -p $USE_DIR/log |
|
|
|
|
|
|
|
|
# Add ERTS bin dir to our path |
|
|
# Add ERTS bin dir to our path |
|
|
ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin |
|
|
ERTS_PATH=$RUNNER_BASE_DIR/erts-$ERTS_VSN/bin |
|
|
|
|
|
|
|
@ -74,47 +112,83 @@ NODETOOL="$ERTS_PATH/escript $ERTS_PATH/nodetool $NAME_ARG $COOKIE_ARG" |
|
|
# Setup remote shell command to control node |
|
|
# Setup remote shell command to control node |
|
|
REMSH="$ERTS_PATH/erl $REMSH_NAME_ARG $REMSH_REMSH_ARG $COOKIE_ARG" |
|
|
REMSH="$ERTS_PATH/erl $REMSH_NAME_ARG $REMSH_REMSH_ARG $COOKIE_ARG" |
|
|
|
|
|
|
|
|
|
|
|
# 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 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
# Check the first argument for instructions |
|
|
# Check the first argument for instructions |
|
|
case "$1" in |
|
|
case "$1" in |
|
|
start) |
|
|
|
|
|
|
|
|
start|start_boot) |
|
|
# Make sure there is not already a node running |
|
|
# Make sure there is not already a node running |
|
|
RES=`$NODETOOL ping` |
|
|
|
|
|
|
|
|
RES=`ping_node` |
|
|
if [ "$RES" = "pong" ]; then |
|
|
if [ "$RES" = "pong" ]; then |
|
|
echo "Node is already running!" |
|
|
echo "Node is already running!" |
|
|
exit 1 |
|
|
exit 1 |
|
|
fi |
|
|
fi |
|
|
shift # remove $1 |
|
|
|
|
|
|
|
|
case "$1" in |
|
|
|
|
|
start) |
|
|
|
|
|
shift |
|
|
|
|
|
START_OPTION="console" |
|
|
|
|
|
HEART_OPTION="start" |
|
|
|
|
|
;; |
|
|
|
|
|
start_boot) |
|
|
|
|
|
shift |
|
|
|
|
|
START_OPTION="console_boot" |
|
|
|
|
|
HEART_OPTION="start_boot" |
|
|
|
|
|
;; |
|
|
|
|
|
esac |
|
|
RUN_PARAM=$(printf "\'%s\' " "$@") |
|
|
RUN_PARAM=$(printf "\'%s\' " "$@") |
|
|
HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT start $RUN_PARAM" |
|
|
|
|
|
|
|
|
HEART_COMMAND="$RUNNER_BASE_DIR/bin/$SCRIPT $HEART_OPTION $RUN_PARAM" |
|
|
export HEART_COMMAND |
|
|
export HEART_COMMAND |
|
|
mkdir -p $PIPE_DIR |
|
|
mkdir -p $PIPE_DIR |
|
|
$ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT console $RUN_PARAM" 2>&1 |
|
|
|
|
|
|
|
|
$ERTS_PATH/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR "exec $RUNNER_BASE_DIR/bin/$SCRIPT $START_OPTION $RUN_PARAM" 2>&1 |
|
|
;; |
|
|
;; |
|
|
|
|
|
|
|
|
stop) |
|
|
stop) |
|
|
# Wait for the node to completely stop... |
|
|
# Wait for the node to completely stop... |
|
|
case `uname -s` in |
|
|
case `uname -s` in |
|
|
Linux|Darwin|FreeBSD|DragonFly|NetBSD|OpenBSD) |
|
|
|
|
|
# PID COMMAND |
|
|
|
|
|
PID=`ps ax -o pid= -o command=|\ |
|
|
|
|
|
grep "$RUNNER_BASE_DIR/.*/[b]eam"|awk '{print $1}'` |
|
|
|
|
|
;; |
|
|
|
|
|
SunOS) |
|
|
|
|
|
# PID COMMAND |
|
|
|
|
|
PID=`ps -ef -o pid= -o args=|\ |
|
|
|
|
|
grep "$RUNNER_BASE_DIR/.*/[b]eam"|awk '{print $1}'` |
|
|
|
|
|
;; |
|
|
|
|
|
CYGWIN*) |
|
|
|
|
|
# UID PID PPID TTY STIME COMMAND |
|
|
|
|
|
PID=`ps -efW|grep "$RUNNER_BASE_DIR/.*/[b]eam"|awk '{print $2}'` |
|
|
|
|
|
;; |
|
|
|
|
|
|
|
|
Darwin) |
|
|
|
|
|
# Make sure we explicitly set this because iTerm.app doesn't for |
|
|
|
|
|
# some reason. |
|
|
|
|
|
COMMAND_MODE=unix2003 |
|
|
esac |
|
|
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 |
|
|
$NODETOOL stop |
|
|
ES=$? |
|
|
ES=$? |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
exit $ES |
|
|
exit $ES |
|
|
fi |
|
|
fi |
|
|
while `kill -0 $PID 2>/dev/null`; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Wait for the node to completely stop... |
|
|
|
|
|
while `kill -s 0 $PID 2>/dev/null` |
|
|
do |
|
|
do |
|
|
sleep 1 |
|
|
sleep 1 |
|
|
done |
|
|
done |
|
@ -140,7 +214,7 @@ case "$1" in |
|
|
|
|
|
|
|
|
ping) |
|
|
ping) |
|
|
## See if the VM is alive |
|
|
## See if the VM is alive |
|
|
$NODETOOL ping |
|
|
|
|
|
|
|
|
ping_node |
|
|
ES=$? |
|
|
ES=$? |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
exit $ES |
|
|
exit $ES |
|
@ -148,8 +222,8 @@ case "$1" in |
|
|
;; |
|
|
;; |
|
|
|
|
|
|
|
|
attach) |
|
|
attach) |
|
|
# Make sure a node IS running |
|
|
|
|
|
RES=`$NODETOOL ping` |
|
|
|
|
|
|
|
|
# Make sure a node is running |
|
|
|
|
|
ping_node |
|
|
ES=$? |
|
|
ES=$? |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
echo "Node is not running!" |
|
|
echo "Node is not running!" |
|
@ -161,8 +235,8 @@ case "$1" in |
|
|
;; |
|
|
;; |
|
|
|
|
|
|
|
|
remote_console) |
|
|
remote_console) |
|
|
# Make sure a node IS running |
|
|
|
|
|
RES=`$NODETOOL ping` |
|
|
|
|
|
|
|
|
# Make sure a node is running |
|
|
|
|
|
ping_node |
|
|
ES=$? |
|
|
ES=$? |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
echo "Node is not running!" |
|
|
echo "Node is not running!" |
|
@ -182,7 +256,7 @@ case "$1" in |
|
|
fi |
|
|
fi |
|
|
|
|
|
|
|
|
# Make sure a node IS running |
|
|
# Make sure a node IS running |
|
|
RES=`$NODETOOL ping` |
|
|
|
|
|
|
|
|
ping_node |
|
|
ES=$? |
|
|
ES=$? |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
if [ "$ES" -ne 0 ]; then |
|
|
echo "Node is not running!" |
|
|
echo "Node is not running!" |
|
@ -195,12 +269,18 @@ case "$1" in |
|
|
$ERTS_PATH/escript $RUNNER_BASE_DIR/bin/install_upgrade.escript $node_name $erlang_cookie $2 |
|
|
$ERTS_PATH/escript $RUNNER_BASE_DIR/bin/install_upgrade.escript $node_name $erlang_cookie $2 |
|
|
;; |
|
|
;; |
|
|
|
|
|
|
|
|
console|console_clean) |
|
|
|
|
|
|
|
|
console|console_clean|console_boot) |
|
|
# .boot file typically just $SCRIPT (ie, the app name) |
|
|
# .boot file typically just $SCRIPT (ie, the app name) |
|
|
# however, for debugging, sometimes start_clean.boot is useful: |
|
|
|
|
|
|
|
|
# however, for debugging, sometimes start_clean.boot is useful. |
|
|
|
|
|
# For e.g. 'setup', one may even want to name another boot script. |
|
|
case "$1" in |
|
|
case "$1" in |
|
|
console) BOOTFILE=$SCRIPT ;; |
|
|
console) BOOTFILE=$SCRIPT ;; |
|
|
console_clean) BOOTFILE=start_clean ;; |
|
|
console_clean) BOOTFILE=start_clean ;; |
|
|
|
|
|
console_boot) |
|
|
|
|
|
shift |
|
|
|
|
|
BOOTFILE="$1" |
|
|
|
|
|
shift |
|
|
|
|
|
;; |
|
|
esac |
|
|
esac |
|
|
# Setup beam-required vars |
|
|
# Setup beam-required vars |
|
|
ROOTDIR=$RUNNER_BASE_DIR |
|
|
ROOTDIR=$RUNNER_BASE_DIR |
|
@ -249,8 +329,17 @@ case "$1" in |
|
|
# Start the VM |
|
|
# Start the VM |
|
|
exec $CMD -- ${1+"$@"} |
|
|
exec $CMD -- ${1+"$@"} |
|
|
;; |
|
|
;; |
|
|
|
|
|
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|foreground|stop|restart|reboot|ping|console|console_clean|attach|remote_console|upgrade}" |
|
|
|
|
|
|
|
|
echo "Usage: $SCRIPT {start|start_boot <file>|foreground|stop|restart|reboot|ping|console|getpid|console_clean|console_boot <file>|attach|remote_console|upgrade}" |
|
|
exit 1 |
|
|
exit 1 |
|
|
;; |
|
|
;; |
|
|
esac |
|
|
esac |
|
|