aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Wilberding <[email protected]>2014-03-29 09:10:08 +0100
committerJordan Wilberding <[email protected]>2014-03-29 09:10:08 +0100
commit0d292ff4c1be173a775628c09d1ac9991fdd8e67 (patch)
tree604625aea65acdc6fd87addb76399317f26f98c0
parenta3508b03be8aff8ffafb1a48172d8dd0c8b1be24 (diff)
parent42c0d49c3e4c0fc55a498bc63d0db78308271883 (diff)
downloadrelx-0d292ff4c1be173a775628c09d1ac9991fdd8e67.tar.gz
relx-0d292ff4c1be173a775628c09d1ac9991fdd8e67.tar.bz2
relx-0d292ff4c1be173a775628c09d1ac9991fdd8e67.zip
Merge pull request #154 from nuex/quote_vars
Give release scripts ability to handle directories with spaces
-rwxr-xr-xpriv/templates/bin.dtl60
-rw-r--r--priv/templates/extended_bin.dtl222
-rw-r--r--priv/templates/nodetool.dtl2
3 files changed, 168 insertions, 116 deletions
diff --git a/priv/templates/bin.dtl b/priv/templates/bin.dtl
index 8f8b048..4434552 100755
--- a/priv/templates/bin.dtl
+++ b/priv/templates/bin.dtl
@@ -2,51 +2,61 @@
set -e
-SCRIPT_DIR=`dirname $0`
-RELEASE_ROOT_DIR=`cd $SCRIPT_DIR/.. && pwd`
-REL_NAME={{ rel_name }}
-REL_VSN={{ rel_vsn }}
-ERTS_VSN={{ erts_vsn }}
-REL_DIR=$RELEASE_ROOT_DIR/releases/$REL_VSN
-ERL_OPTS={{ erl_opts }}
+SCRIPT_DIR="$(dirname "$0")"
+RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
+REL_NAME="{{ rel_name }}"
+REL_VSN="{{ rel_vsn }}"
+ERTS_VSN="{{ erts_vsn }}"
+REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
+ERL_OPTS="{{ erl_opts }}"
find_erts_dir() {
- local erts_dir=$RELEASE_ROOT_DIR/erts-$ERTS_VSN
+ local erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
if [ -d "$erts_dir" ]; then
- ERTS_DIR=$erts_dir;
- ROOTDIR=$RELEASE_ROOT_DIR
+ ERTS_DIR="$erts_dir";
+ ROOTDIR="$RELEASE_ROOT_DIR"
else
- local erl=`which erl`
- local erl_root=`$erl -noshell -eval "io:format(\\"~s\\", [code:root_dir()])." -s init stop`
- ERTS_DIR=$erl_root/erts-$ERTS_VSN
- ROOTDIR=$erl_root
+ local erl="$(which erl)"
+ local erl_root="$("$erl" -noshell -eval "io:format(\\"~s\\", [code:root_dir()])." -s init stop)"
+ ERTS_DIR="$erl_root/erts-$ERTS_VSN"
+ ROOTDIR="$erl_root"
fi
}
find_sys_config() {
- local possible_sys=$REL_DIR/sys.config
+ local possible_sys="$REL_DIR/sys.config"
if [ -f "$possible_sys" ]; then
- SYS_CONFIG="-config $possible_sys"
+ SYS_CONFIG="$possible_sys"
fi
}
find_vm_args() {
- local possible_vm_args=$REL_DIR/vm.args
+ local possible_vm_args="$REL_DIR/vm.args"
if [ -f "$possible_vm_args" ]; then
- VM_ARGS="-args_file $possible_vm_args"
+ VM_ARGS="$possible_vm_args"
fi
}
find_erts_dir
find_sys_config
find_vm_args
-export ROOTDIR=$RELEASE_ROOT_DIR
-export BINDIR=$ERTS_DIR/bin
-export EMU=beam
-export PROGNAME=erl
-export LD_LIBRARY_PATH=$ERTS_DIR/lib:$LD_LIBRARY_PATH
+export ROOTDIR="$RELEASE_ROOT_DIR"
+export BINDIR="$ERTS_DIR/bin"
+export EMU="beam"
+export PROGNAME="erl"
+export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
-cd $ROOTDIR
+cd "$ROOTDIR"
-$BINDIR/erlexec $ERL_OPTS $SYS_CONFIG $VM_ARGS -boot $REL_DIR/$REL_NAME $@
+# Save extra arguments
+ARGS="$@"
+
+# Build arguments for erlexec
+set -- "$ERL_OPTS"
+[ "$SYS_CONFIG" ] && set -- "$@" -config "$SYS_CONFIG"
+[ "$VM_ARGS" ] && set -- "$@" -args_file "$VM_ARGS"
+set -- "$@" -boot "$REL_DIR/$REL_NAME" "$ARGS"
+
+# Boot the release
+"$BINDIR/erlexec" "$@"
diff --git a/priv/templates/extended_bin.dtl b/priv/templates/extended_bin.dtl
index 75f3859..59cf692 100644
--- a/priv/templates/extended_bin.dtl
+++ b/priv/templates/extended_bin.dtl
@@ -2,44 +2,60 @@
set -e
-SCRIPT_DIR=`dirname $0`
-RELEASE_ROOT_DIR=`cd $SCRIPT_DIR/.. && pwd`
-REL_NAME={{ rel_name }}
-REL_VSN={{ rel_vsn }}
-ERTS_VSN={{ erts_vsn }}
-REL_DIR=$RELEASE_ROOT_DIR/releases/$REL_VSN
-ERL_OPTS={{ erl_opts }}
-PIPE_DIR=/tmp/erl_pipes/{{ rel_name }}/
-RUNNER_LOG_DIR=${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}
+SCRIPT_DIR="$(dirname "$0")"
+RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
+REL_NAME="{{ rel_name }}"
+REL_VSN="{{ rel_vsn }}"
+ERTS_VSN="{{ erts_vsn }}"
+REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
+ERL_OPTS="{{ erl_opts }}"
+PIPE_DIR="/tmp/erl_pipes/{{ rel_name }}/"
+RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}"
find_erts_dir() {
- local erts_dir=$RELEASE_ROOT_DIR/erts-$ERTS_VSN
+ local erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
if [ -d "$erts_dir" ]; then
- ERTS_DIR=$erts_dir;
- ROOTDIR=$RELEASE_ROOT_DIR
+ ERTS_DIR="$erts_dir";
+ ROOTDIR="$RELEASE_ROOT_DIR"
else
- local erl=`which erl`
- local erl_root=`$erl -noshell -eval "io:format(\\"~s\\", [code:root_dir()])." -s init stop`
- ERTS_DIR=$erl_root/erts-$ERTS_VSN
- ROOTDIR=$erl_root
+ local erl="$(which erl)"
+ local erl_root="$("$erl" -noshell -eval "io:format(\\"~s\\", [code:root_dir()])." -s init stop)"
+ ERTS_DIR="$erl_root/erts-$ERTS_VSN"
+ ROOTDIR="$erl_root"
fi
+}
+
+# Connect to a remote node
+relx_rem_sh() {
+ # Generate a unique id used to allow multiple remsh to the same node
+ # transparently
+ id="remsh$(date +%s`@`echo "$NAME" | awk -F@ '{print $2}')"
+ # Setup remote shell command to control node
+ exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \
+ -setcookie "$COOKIE"
}
-find_sys_config() {
- local possible_sys=$REL_DIR/sys.config
- if [ -f "$possible_sys" ]; then
- SYS_CONFIG="-config $possible_sys"
- fi
+# Control a node
+relx_nodetool() {
+ command="$1"; shift
+ "erts-$ERTS_VSN/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \
+ -setcookie "$COOKIE" "$command"
+}
+
+# Output a start command for the last argument of run_erl
+relx_start_command() {
+ printf "exec \"%s\" \"%s\"" "$RELEASE_ROOT_DIR/bin/$REL_NAME" \
+ "$START_OPTION"
}
# Use $CWD/vm.args if exists, otherwise releases/APP_VSN/vm.args, or else etc/vm.args
if [ -z "$VMARGS_PATH" ]; then
if [ -e "$RELEASE_ROOT_DIR/vm.args" ]; then
- VMARGS_PATH=$RELEASE_ROOT_DIR/vm.args
- USE_DIR=$RELEASE_ROOT_DIR
+ VMARGS_PATH="$RELEASE_ROOT_DIR/vm.args"
+ USE_DIR="$RELEASE_ROOT_DIR"
else
- USE_DIR=$REL_DIR
+ USE_DIR="$REL_DIR"
if [ -e "$REL_DIR/vm.args" ]; then
VMARGS_PATH="$REL_DIR/vm.args"
else
@@ -49,7 +65,7 @@ if [ -z "$VMARGS_PATH" ]; then
fi
# Make sure log directory exists
-mkdir -p $RUNNER_LOG_DIR
+mkdir -p "$RUNNER_LOG_DIR"
# Use releases/VSN/sys.config if it exists otherwise use etc/app.config
if [ -z "$CONFIG_PATH" ]; then
@@ -65,42 +81,34 @@ if [ -z "$CONFIG_PATH" ]; then
fi
# 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
echo "vm.args needs to have either -name or -sname parameter."
exit 1
fi
# Extract the name type and name from the NAME_ARG for REMSH
-REMSH_TYPE=`echo $NAME_ARG | awk '{print $1}'`
-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 remsh`date +%s`@`echo $REMSH_NAME | awk -F@ '{print $2}'`"
-REMSH_REMSH_ARG="-remsh $REMSH_NAME -boot start_clean"
+NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
+NAME="$(echo "$NAME_ARG" | awk '{print $2}')"
# Extract the target cookie
-COOKIE_ARG=`grep '^-setcookie' $VMARGS_PATH`
+COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH")"
if [ -z "$COOKIE_ARG" ]; then
echo "vm.args needs to have a -setcookie parameter."
exit 1
fi
-find_erts_dir
-find_sys_config
-export ROOTDIR=$RELEASE_ROOT_DIR
-export BINDIR=$ERTS_DIR/bin
-export EMU=beam
-export PROGNAME=erl
-export LD_LIBRARY_PATH=$ERTS_DIR/lib:$LD_LIBRARY_PATH
-
-cd $ROOTDIR
+# Extract cookie name from COOKIE_ARG
+COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
-# Setup remote shell command to control node
-REMSH="$BINDIR/erl $REMSH_NAME_ARG $REMSH_REMSH_ARG $COOKIE_ARG"
+find_erts_dir
+export ROOTDIR="$RELEASE_ROOT_DIR"
+export BINDIR="$ERTS_DIR/bin"
+export EMU="beam"
+export PROGNAME="erl"
+export LD_LIBRARY_PATH="$ERTS_DIR/lib:$LD_LIBRARY_PATH"
-# Setup command to control the node
-NODETOOL="$BINDIR/escript $ROOTDIR/bin/nodetool $NAME_ARG $COOKIE_ARG"
+cd "$ROOTDIR"
# Check the first argument for instructions
case "$1" in
@@ -124,37 +132,46 @@ case "$1" in
HEART_OPTION="start_boot"
;;
esac
- RUN_PARAM=$(printf "'%s' " "$@")
- HEART_COMMAND="$SCRIPT_DIR/bin/$REL_NAME $HEART_OPTION $RUN_PARAM"
+ RUN_PARAM="$@"
+
+ # Set arguments for the heart command
+ set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION"
+ [ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM"
+
+ # Export the HEART_COMMAND
+ HEART_COMMAND="$@"
export HEART_COMMAND
- mkdir -p $PIPE_DIR
- $BINDIR/run_erl -daemon $PIPE_DIR $RUNNER_LOG_DIR "exec $RELEASE_ROOT_DIR/bin/$REL_NAME $START_OPTION $RUN_PARAM" 2>&1
+
+ mkdir -p "$PIPE_DIR"
+
+ "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \
+ "$(relx_start_command)"
;;
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 "$SCRIPT_DIR/.*/[b]eam"|awk '{print $1}'`
+ PID=$(ps ax -o pid= -o command=|
+ grep "$SCRIPT_DIR/.*/[b]eam"|awk '{print $1}')
;;
SunOS)
# PID COMMAND
- PID=`ps -ef -o pid= -o args=|
- grep "$SCRIPT_DIR/.*/[b]eam"|awk '{print $1}'`
+ PID=$(ps -ef -o pid= -o args=|
+ grep "$SCRIPT_DIR/.*/[b]eam"|awk '{print $1}')
;;
CYGWIN*)
# UID PID PPID TTY STIME COMMAND
- PID=`ps -efW|grep "$SCRIPT_DIR/.*/[b]eam"|awk '{print $2}'`
+ PID=$(ps -efw|grep "$SCRIPT_DIR/.*/[b]eam"|awk '{print $2}')
;;
esac
- $NODETOOL stop
- ES=$?
+ relx_nodetool "stop"
+ ES="$?"
if [ "$ES" -ne 0 ]; then
- exit $ES
+ exit "$ES"
fi
- while `kill -0 $PID 2>/dev/null`;
+ while $(kill -0 "$PID" 2>/dev/null);
do
sleep 1
done
@@ -162,8 +179,8 @@ case "$1" in
restart)
## Restart the VM without exiting the process
- $NODETOOL restart
- ES=$?
+ relx_nodetool "restart"
+ ES="$?"
if [ "$ES" -ne 0 ]; then
exit $ES
fi
@@ -171,8 +188,8 @@ case "$1" in
reboot)
## Restart the VM completely (uses heart to restart it)
- $NODETOOL reboot
- ES=$?
+ relx_nodetool "reboot"
+ ES="$?"
if [ "$ES" -ne 0 ]; then
exit $ES
fi
@@ -180,8 +197,8 @@ case "$1" in
ping)
## See if the VM is alive
- $NODETOOL ping
- ES=$?
+ relx_nodetool "ping"
+ ES="$?"
if [ "$ES" -ne 0 ]; then
exit $ES
fi
@@ -189,28 +206,28 @@ case "$1" in
attach)
# Make sure a node IS running
- RES=`$NODETOOL ping`
- ES=$?
+ RES="$(relx_nodetool "ping")"
+ ES="$?"
if [ "$ES" -ne 0 ]; then
echo "Node is not running!"
exit $ES
fi
shift
- exec $BINDIR/to_erl $PIPE_DIR
+ exec "$BINDIR/to_erl" "$PIPE_DIR"
;;
remote_console)
# Make sure a node IS running
- RES=`$NODETOOL ping`
- ES=$?
+ RES="$(relx_nodetool "ping")"
+ ES="$?"
if [ "$ES" -ne 0 ]; then
echo "Node is not running!"
exit $ES
fi
shift
- exec $REMSH
+ relx_rem_sh
;;
upgrade|downgrade|install)
@@ -222,17 +239,15 @@ case "$1" in
fi
# Make sure a node IS running
- RES=`$NODETOOL ping`
- ES=$?
+ RES="$(relx_nodetool "ping")"
+ ES="$?"
if [ "$ES" -ne 0 ]; then
echo "Node is not running!"
exit $ES
fi
- node_name=`echo $NAME_ARG | awk '{print $2}'`
- erlang_cookie=`echo $COOKIE_ARG | awk '{print $2}'`
-
- exec $BINDIR/escript $ROOTDIR/bin/install_upgrade.escript $REL_NAME $node_name $erlang_cookie $2
+ exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
+ "$REL_NAME" "$NAME" "$COOKIE" "$2"
;;
console|console_clean|console_boot)
@@ -240,8 +255,16 @@ case "$1" in
# 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
- console) [ -f $REL_DIR/$REL_NAME.boot ] && BOOTFILE=$REL_DIR/$REL_NAME || BOOTFILE=$REL_DIR/start ;;
- console_clean) BOOTFILE=$ROOTDIR/bin/start_clean ;;
+ console)
+ if [ "$REL_DIR/$REL_NAME.boot" ]; then
+ BOOTFILE="$REL_DIR/$REL_NAME"
+ else
+ BOOTFILE="$REL_DIR/start"
+ fi
+ ;;
+ console_clean)
+ BOOTFILE="$ROOTDIR/bin/start_clean"
+ ;;
console_boot)
shift
BOOTFILE="$1"
@@ -249,43 +272,62 @@ case "$1" in
;;
esac
# Setup beam-required vars
- EMU=beam
- PROGNAME=`echo $0 | sed 's/.*\\///'`
- CMD="$BINDIR/erlexec -boot $BOOTFILE -env ERL_LIBS $REL_DIR/lib -config $CONFIG_PATH -args_file $VMARGS_PATH"
+ EMU="beam"
+ PROGNAME="${0#*/}"
+
export EMU
export PROGNAME
+ # Store passed arguments since they will be erased by `set`
+ ARGS="$@"
+
+ # Build an array of arguments to pass to exec later on
+ # Build it here because this command will be used for logging.
+ set -- "$BINDIR/erlexec" -boot "$BOOTFILE" \
+ -env ERL_LIBS "$REL_DIR/lib" -config "$CONFIG_PATH" \
+ -args_file "$VMARGS_PATH"
+
# Dump environment info for logging purposes
- echo "Exec: $CMD" -- ${1+"$@"}
+ echo "Exec: $@ -- ${1+$ARGS}"
echo "Root: $ROOTDIR"
# Log the startup
+ echo "$RELEASE_ROOT_DIR"
logger -t "$REL_NAME[$$]" "Starting up"
# Start the VM
- exec $CMD -- ${1+"$@"}
+ exec "$@" -- "${1+$ARGS}"
;;
foreground)
# start up the release in the foreground for use by runit
# or other supervision services
- [ -f $REL_DIR/$REL_NAME.boot ] && BOOTFILE=$REL_NAME || BOOTFILE=start
+ [ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start
FOREGROUNDOPTIONS="-noinput +Bd"
# Setup beam-required vars
EMU=beam
- PROGNAME=`echo $0 | sed 's/.*\\///'`
- CMD="$BINDIR/erlexec $FOREGROUNDOPTIONS -boot $REL_DIR/$BOOTFILE -mode embedded -config $CONFIG_PATH -args_file $VMARGS_PATH"
+ PROGNAME="${0#*/}"
+
export EMU
export PROGNAME
+ # Store passed arguments since they will be erased by `set`
+ ARGS="$@"
+
+ # Build an array of arguments to pass to exec later on
+ # Build it here because this command will be used for logging.
+ set -- "$BINDIR/erlexec" "$FOREGROUNDOPTIONS" \
+ -boot "$REL_DIR/$BOOTFILE" -mode embedded -config "$CONFIG_PATH" \
+ -args_file "$VMARGS_PATH"
+
# Dump environment info for logging purposes
- echo "Exec: $CMD" -- ${1+"$@"}
+ echo "Exec: $@" -- "${1+$ARGS}"
echo "Root: $ROOTDIR"
# Start the VM
- exec $CMD -- ${1+"$@"}
+ exec "$@" -- "${1+$ARGS}"
;;
*)
echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade}"
diff --git a/priv/templates/nodetool.dtl b/priv/templates/nodetool.dtl
index a6faad5..80f1965 100644
--- a/priv/templates/nodetool.dtl
+++ b/priv/templates/nodetool.dtl
@@ -75,7 +75,7 @@ process_args([Arg | Rest], Acc, Opts) ->
start_epmd() ->
- [] = os:cmd(epmd_path() ++ " -daemon"),
+ [] = os:cmd("\"" ++ epmd_path() ++ "\" -daemon"),
ok.
epmd_path() ->