-
-
Save Licenser/31d4587900fd37d65f132e8d0b9d2fd3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -e | |
SCRIPT=$(readlink $0 || true) | |
if [ -z $SCRIPT ]; then | |
SCRIPT=$0 | |
fi; | |
SCRIPT_DIR="$(cd `dirname "$SCRIPT"` && pwd -P)" | |
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd -P)" | |
REL_NAME="dalmatinerpx" | |
CUTTLEFISH_CONF="dalmatinerpx.conf" | |
REL_VSN="0.3.2p5" | |
ERTS_VSN="8.3" | |
CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}" | |
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN" | |
ERL_OPTS="" | |
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-/data/dalmatinerpx/log }" | |
RUNNER_BASE_DIR=$RELEASE_ROOT_DIR | |
RUNNER_ETC_DIR="${RUNNER_ETC_DIR:-/data/dalmatinerpx/etc}" | |
RUNNER_DB_DIR="${RUNNER_ETC_DIR:-/data/dalmatinerpx/db}" | |
if [ "$RUNNER_ETC_DIR" = "${RUNNER_ETC_DIR#/}" ] | |
then | |
# if relative, make it relative to RELEASE_ROOT_DIR | |
RUNNER_ETC_DIR=$RELEASE_ROOT_DIR/$RUNNER_ETC_DIR | |
fi # else absolute, keep it as it is | |
find_erts_dir() { | |
__erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN" | |
if [ -d "$__erts_dir" ]; then | |
ERTS_DIR="$__erts_dir"; | |
ROOTDIR="$RELEASE_ROOT_DIR" | |
else | |
__erl="$(which erl)" | |
code="io:format(\"~s\", [code:root_dir()]), halt()." | |
__erl_root="$("$__erl" -noshell -eval "$code")" | |
ERTS_DIR="$__erl_root/erts-$ERTS_VSN" | |
ROOTDIR="$__erl_root" | |
fi | |
} | |
# Get node pid | |
relx_get_pid() { | |
if output="$(relx_nodetool rpcterms os getpid)" | |
then | |
echo "$output" | sed -e 's/"//g' | |
return 0 | |
else | |
echo "$output" | |
return 1 | |
fi | |
} | |
relx_get_longname() { | |
id="longname$(relx_gen_id)-${NAME}" | |
"$BINDIR/erl" -boot start_clean -eval 'io:format("~s~n", [node()]), halt()' -noshell -name $id | sed -e 's/.*@//g' | |
} | |
# Connect to a remote node | |
relx_rem_sh() { | |
# Generate a unique id used to allow multiple remsh to the same node | |
# transparently | |
id="remsh$(relx_gen_id)-${NAME}" | |
# Get the node's ticktime so that we use the same thing. | |
TICKTIME="$(relx_nodetool rpcterms net_kernel get_net_ticktime)" | |
# Setup remote shell command to control node | |
exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \ | |
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ | |
-setcookie "$COOKIE" -hidden -kernel net_ticktime $TICKTIME | |
} | |
# Generate a random id | |
relx_gen_id() { | |
od -X -N 4 /dev/urandom | head -n1 | awk '{print $2}' | |
} | |
# Control a node | |
relx_nodetool() { | |
command="$1"; shift | |
"$ERTS_DIR/bin/escript" "$ROOTDIR/bin/nodetool" "$NAME_TYPE" "$NAME" \ | |
-setcookie "$COOKIE" "$command" $@ | |
} | |
# Run an escript in the node's environment | |
relx_escript() { | |
shift; scriptpath="$1"; shift | |
export RELEASE_ROOT_DIR | |
"$ERTS_DIR/bin/escript" "$ROOTDIR/$scriptpath" $@ | |
} | |
# 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" | |
} | |
if [ $RELX_REPLACE_OS_VARS ]; then | |
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < "$RUNNER_ETC_DIR/$CUTTLEFISH_CONF" > "$RUNNER_ETC_DIR/$CUTTLEFISH_CONF.new" | |
else | |
cp "$RUNNER_ETC_DIR/$CUTTLEFISH_CONF" "$RUNNER_ETC_DIR/$CUTTLEFISH_CONF.new" | |
fi | |
# Make sure log directory exists | |
mkdir -p "$RUNNER_LOG_DIR" | |
# Use $CWD/sys.config if exists, otherwise releases/VSN/sys.config | |
if [ -z "$NAME_ARG" ]; then | |
NODENAME=`egrep '^[ \t]*nodename[ \t]*=[ \t]*' $RUNNER_ETC_DIR/$CUTTLEFISH_CONF.new 2> /dev/null | tail -n 1 | cut -d = -f 2` | |
if [ -z "$NODENAME" ]; then | |
echo "vm.args needs to have a -name parameter." | |
echo " -sname is not supported." | |
echo " couldn't find 'nodename' in $RUNNER_ETC_DIR/$CUTTLEFISH_CONF.new" | |
echo " \$PWD is $PWD" | |
exit 1 | |
else | |
NAME_TYPE="-name" | |
NAME="${NODENAME# *}" | |
fi | |
fi | |
PIPE_DIR="${PIPE_DIR:-/tmp/erl_pipes/$NAME/}" | |
# Extract the target cookie | |
#COOKIE_ARG=`grep -e '-setcookie' $RUNNER_ETC_DIR/vm.args` | |
if [ -z "$COOKIE_ARG" ]; then | |
COOKIE=`egrep '^[ \t]*distributed_cookie[ \t]*=[ \t]*' $RUNNER_ETC_DIR/$CUTTLEFISH_CONF.new 2> /dev/null | cut -d = -f 2 | tr -d ' '` | |
if [ -z "$COOKIE" ]; then | |
echo "vm.args needs to have a -setcookie parameter." | |
echo " couldn't find 'distributed_cookie' in $RUNNER_ETC_DIR/$CUTTLEFISH_CONF.new" | |
echo " \$PWD is $PWD" | |
exit 1 | |
else | |
COOKIE_ARG="-setcookie $COOKIE" | |
fi | |
fi | |
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" | |
ERTS_LIB_DIR="$ERTS_DIR/../lib" | |
CUTTLEFISHCMD="$ERTS_DIR/bin/escript $RUNNER_BASE_DIR/bin/cuttlefish" | |
cd "$ROOTDIR" | |
if CUTTLEFISH_CONFIG=$($CUTTLEFISHCMD -e $RUNNER_ETC_DIR -d ${RUNNER_DB_DIR}/generated.conf -s $RUNNER_BASE_DIR/share/schema/ -c $RUNNER_ETC_DIR/$CUTTLEFISH_CONF.new) | |
then | |
CONFIG_FILES="$CUTTLEFISH_CONFIG" | |
else | |
echo "Cuttlefish failed! Oh no!" | |
exit 1 | |
fi | |
# User can specify an sname without @hostname | |
# This will fail when creating remote shell | |
# So here we check for @ and add @hostname if missing | |
case $NAME in | |
*@*) | |
# Nothing to do | |
;; | |
*) | |
# Add @hostname | |
case $NAME_TYPE in | |
-sname) | |
NAME=$NAME@`hostname -s` | |
;; | |
-name) | |
NAME=$NAME@$(relx_get_longname) | |
;; | |
esac | |
;; | |
esac | |
# Check the first argument for instructions | |
case "$1" in | |
start|start_boot) | |
CMD=$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="$@" | |
# Set arguments for the heart command | |
set -- "$SCRIPT_DIR/$REL_NAME" "$HEART_OPTION" | |
[ "$RUN_PARAM" ] && set -- "$@" "$RUN_PARAM" | |
# Export the HEART_COMMAND | |
HEART_COMMAND="$RELEASE_ROOT_DIR/bin/$REL_NAME $CMD" | |
export HEART_COMMAND | |
mkdir -p "$PIPE_DIR" | |
"$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ | |
"$(relx_start_command)" | |
;; | |
stop) | |
# Wait for the node to completely stop... | |
PID="$(relx_get_pid)" | |
if ! relx_nodetool "stop"; then | |
exit 1 | |
fi | |
while $(kill -s 0 "$PID" 2>/dev/null); | |
do | |
sleep 1 | |
done | |
;; | |
restart) | |
## Restart the VM without exiting the process | |
if ! relx_nodetool "restart"; then | |
exit 1 | |
fi | |
;; | |
reboot) | |
## Restart the VM completely (uses heart to restart it) | |
if ! relx_nodetool "reboot"; then | |
exit 1 | |
fi | |
;; | |
pid) | |
## Get the VM's pid | |
if ! relx_get_pid; then | |
exit 1 | |
fi | |
;; | |
ping) | |
## See if the VM is alive | |
if ! relx_nodetool "ping"; then | |
exit 1 | |
fi | |
;; | |
config) | |
shift | |
case "$1" in | |
effective) ## Great, pass through! | |
;; | |
describe) | |
if [ $# -lt 2 ] || [ "$2" = "-l" ]; then | |
echo "$RUNNER_SCRIPT config describe requires a variable name to query" | |
echo " Try \`$RUNNER_SCRIPT config describe setting.name\`" | |
exit 1 | |
fi | |
;; | |
generate) ## Great, pass through! | |
;; | |
*) | |
echo "Valid commands for$RUNNER_SCRIPT config are:" | |
echo " $RUNNER_SCRIPT config effective" | |
echo " $RUNNER_SCRIPT config describe VARIABLE" | |
exit 1 | |
;; | |
esac | |
CUTTLEFISH_COMMAND_PREFIX="$RUNNER_BASE_DIR/bin/cuttlefish -e $RUNNER_ETC_DIR -s $RUNNER_BASE_DIR/share/schema -d $RUNNER_BASE_DIR/generated.configs -c $RUNNER_ETC_DIR/cse_spooler.conf" | |
printf '%s \n' "`$CUTTLEFISH_COMMAND_PREFIX $@`" | |
;; | |
escript) | |
## Run an escript under the node's environment | |
if ! relx_escript $@; then | |
exit 1 | |
fi | |
;; | |
attach) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
exec "$BINDIR/to_erl" "$PIPE_DIR" | |
;; | |
remote_console) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_rem_sh | |
;; | |
upgrade|downgrade|install) | |
if [ -z "$2" ]; then | |
echo "Missing package argument" | |
echo "Usage: $REL_NAME $1 {package base name}" | |
echo "NOTE {package base name} MUST NOT include the .tar.gz suffix" | |
exit 1 | |
fi | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ | |
"install" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2" | |
;; | |
unpack) | |
if [ -z "$2" ]; then | |
echo "Missing package argument" | |
echo "Usage: $REL_NAME $1 {package base name}" | |
echo "NOTE {package base name} MUST NOT include the .tar.gz suffix" | |
exit 1 | |
fi | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ | |
"unpack" "$REL_NAME" "$NAME_TYPE" "$NAME" "$COOKIE" "$2" | |
;; | |
console|console_clean|console_boot) | |
# .boot file typically just $REL_NAME (ie, the app name) | |
# 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) | |
if [ -f "$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" | |
shift | |
;; | |
esac | |
# Setup beam-required vars | |
ROOTDIR=$RUNNER_BASE_DIR | |
EMU=beam | |
PROGNAME=`echo $0 | sed 's/.*\\///'` | |
CMD="$BINDIR/erlexec -boot $BOOTFILE -boot_var ERTS_LIB_DIR $ERTS_LIB_DIR -mode $CODE_LOADING_MODE $CONFIG_FILES -- ${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 | |
;; | |
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 | |
FOREGROUNDOPTIONS="-noshell -noinput +Bd" | |
# Setup beam-required vars | |
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" $FOREGROUNDOPTIONS \ | |
-boot "$REL_DIR/$BOOTFILE" -mode "$CODE_LOADING_MODE" $CONFIG_FILES \ | |
-boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" | |
# Dump environment info for logging purposes | |
echo "Exec: $@" -- ${1+$ARGS} | |
echo "Root: $ROOTDIR" | |
# Start the VM | |
exec "$@" -- ${1+$ARGS} | |
;; | |
rpc) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_nodetool rpc $@ | |
;; | |
rpcterms) | |
# Make sure a node IS running | |
if ! relx_nodetool "ping" > /dev/null; then | |
echo "Node is not running!" | |
exit 1 | |
fi | |
shift | |
relx_nodetool rpcterms $@ | |
;; | |
*) | |
echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|config|escript|rpc|rpcterms}" | |
exit 1 | |
;; | |
esac | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment