Packages
exrm
0.12.11
1.0.8
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
1.0.0-rc8
1.0.0-rc7
1.0.0-rc6
1.0.0-rc5
1.0.0-rc4
1.0.0-rc3
0.19.9
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.8
0.18.7
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.15.3
0.15.2
0.15.1
0.15.0
0.14.17
0.14.16
0.14.15
0.14.14
0.14.13
0.14.12
0.14.11
0.14.10
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.3
0.14.2
0.14.1
0.14.0
0.12.12
0.12.11
0.12.10
0.12.9
0.12.8
0.12.7
0.12.6
0.12.5
0.12.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.1
0.10.0
0.9.2
0.9.1
0.8.1
0.8.0
0.7.3
0.7.2
0.7.1
0.7.0
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.0
0.4.7
Exrm, or Elixir Release Manager, provides mix tasks for building, upgrading, and controlling release packages for your application.
Current section
Files
Jump to
Current section
Files
priv/rel/files/boot
#!/bin/sh
set -e
SCRIPT_DIR="$(dirname "$0")"
RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
REL_NAME="{{{PROJECT_NAME}}}"
REL_VSN="{{{PROJECT_VERSION}}}"
ERTS_VSN="{{{ERTS_VERSION}}}"
REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN"
REL_LIB_DIR="$RELEASE_ROOT_DIR/lib"
ERL_OPTS="{{{ERL_OPTS}}}"
PIPE_DIR="/tmp/erl_pipes/{{{PROJECT_NAME}}}/"
RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}"
find_erts_dir() {
local erts_dir="$RELEASE_ROOT_DIR/erts-$ERTS_VSN"
if [ -d "$erts_dir" ]; then
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"
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$(relx_gen_id)-${NAME}"
# Setup Erlang remote shell command to control node
#exec "$BINDIR/erl" "$NAME_TYPE" "$id" -remsh "$NAME" -boot start_clean \
#-setcookie "$COOKIE"
# Setup Elixir remote shell command to control node
exec "$BINDIR/erl" -pa "$ROOTDIR/lib/*/ebin" -pa "$ROOTDIR/lib/consolidated" -noshell -boot start_clean \
-user Elixir.IEx.CLI "$NAME_TYPE" "$id" -setcookie "$COOKIE" \
-extra --no-halt +iex -"$NAME_TYPE" "$id" --cookie "$COOKIE" --remsh "$NAME"
}
# Generate a random id
relx_gen_id() {
od -X /dev/urandom | head -n1 | cut -d ' ' -f2
}
# 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"
}
# Convert .conf to sys.config using conform escript
generate_config() {
local conf_file="$REL_DIR/$REL_NAME.conf"
local schema_file="$REL_DIR/$REL_NAME.schema.exs"
local sys_config="$REL_DIR/sys.config"
if [ -f "$schema_file" ]; then
result="$("erts-$ERTS_VSN/bin/escript" "$ROOTDIR"/bin/conform --conf "$conf_file" --schema "$schema_file" --config "$sys_config" --output-dir "$REL_DIR")"
exit_status="$?"
if [ "$exit_status" -ne 0 ]; then
exit "$exit_status"
fi
fi
}
# Use $CWD/vm.args if exists, otherwise releases/VSN/vm.args
if [ -z "$VMARGS_PATH" ]; then
if [ -f "$RELEASE_ROOT_DIR/vm.args" ]; then
VMARGS_PATH="$RELEASE_ROOT_DIR/vm.args"
USE_DIR="$RELEASE_ROOT_DIR"
else
USE_DIR="$REL_DIR"
VMARGS_PATH="$REL_DIR/vm.args"
fi
fi
if [ $RELX_REPLACE_OS_VARS ]; then
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < $VMARGS_PATH > $VMARGS_PATH.2.config
VMARGS_PATH=$VMARGS_PATH.2.config
fi
# Make sure log directory exists
mkdir -p "$RUNNER_LOG_DIR"
if [ -z "$CONFIG_PATH" ]; then
if [ -f "$USE_DIR/sys.config" ]; then
CONFIG_PATH="$USE_DIR/sys.config"
else
CONFIG_PATH="$REL_DIR/sys.config"
fi
fi
if [ $RELX_REPLACE_OS_VARS ]; then
awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < $CONFIG_PATH > $CONFIG_PATH.2.config
CONFIG_PATH=$CONFIG_PATH.2.config
fi
# Extract the target node name from node.args
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
NAME_TYPE="$(echo "$NAME_ARG" | awk '{print $1}')"
NAME="$(echo "$NAME_ARG" | awk '{print $2}')"
# 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
NAME=$NAME@`hostname`
;;
esac
# Extract the target cookie
COOKIE_ARG="$(grep '^-setcookie' "$VMARGS_PATH")"
if [ -z "$COOKIE_ARG" ]; then
echo "vm.args needs to have a -setcookie parameter."
exit 1
fi
# Extract cookie name from COOKIE_ARG
COOKIE="$(echo "$COOKIE_ARG" | awk '{print $2}')"
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"
cd "$ROOTDIR"
# Check the first argument for instructions
case "$1" in
start|start_boot)
# Make sure the config is generated first
generate_config
# Make sure there is not already a node running
#RES=`$NODETOOL ping`
#if [ "$RES" = "pong" ]; then
# echo "Node is already running!"
# exit 1
#fi
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="$@"
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...
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}')
;;
SunOS)
# PID COMMAND
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}')
;;
esac
relx_nodetool "stop"
ES="$?"
if [ "$ES" -ne 0 ]; then
exit "$ES"
fi
while $(kill -0 "$PID" 2>/dev/null);
do
sleep 1
done
;;
restart)
# Make sure the config is generated first
generate_config
## Restart the VM without exiting the process
relx_nodetool "restart"
ES="$?"
if [ "$ES" -ne 0 ]; then
exit "$ES"
fi
;;
reboot)
# Make sure the config is generated first
generate_config
## Restart the VM completely (uses heart to restart it)
relx_nodetool "reboot"
ES="$?"
if [ "$ES" -ne 0 ]; then
exit "$ES"
fi
;;
ping)
## See if the VM is alive
relx_nodetool "ping"
ES="$?"
if [ "$ES" -ne 0 ]; then
exit "$ES"
fi
;;
rpc)
## Execute a command in MFA format on the remote node
if [ -z "$3" ]; then
echo "RPC requires module, function, and a string of the arguments to be evaluated."
echo "The argument string must evaluate to a valid Erlang term."
echo "Examples: rpc calendar valid_date \"{2013,3,12}.\""
echo " rpc erlang now"
exit 1
fi
if [ -z "$4" ]; then
relx_nodetool "rpcterms" "$2" "$3"
else
relx_nodetool "rpcterms" "$2" "$3" "$4"
fi
ES="$?"
if [ "$ES" -ne 0 ]; then
exit "$ES"
fi
;;
attach)
# Make sure a node IS running
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"
;;
remote_console)
# Make sure a node IS running
RES="$(relx_nodetool "ping")"
ES="$?"
if [ "$ES" -ne 0 ]; then
echo "Node is not running!"
exit "$ES"
fi
shift
relx_rem_sh
;;
upgrade|downgrade|install)
# Make sure the config is generated first
generate_config
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
RES="$(relx_nodetool "ping")"
ES="$?"
if [ "$ES" -ne 0 ]; then
echo "Node is not running!"
exit "$ES"
fi
exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \
"$REL_NAME" "$NAME" "$COOKIE" "$2"
;;
console|console_clean|console_boot)
# Make sure the config is generated first
generate_config
# .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 [ "$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
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_LIB_DIR" -config "$CONFIG_PATH" \
-pa "$REL_LIB_DIR/consolidated" \
-args_file "$VMARGS_PATH" \
-user Elixir.IEx.CLI -extra --no-halt +iex
# Dump environment info for logging purposes
echo "Exec: $@ -- ${1+$ARGS}"
echo "Root: $ROOTDIR"
# Log the startup
echo "$RELEASE_ROOT_DIR"
logger -t "$REL_NAME[$$]" "Starting up"
# Start the VM
exec "$@" -- "${1+$ARGS}"
;;
foreground)
# Make sure the config is generated first
generate_config
# 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 embedded -config "$CONFIG_PATH" \
-args_file "$VMARGS_PATH" \
-user Elixir.IEx.CLI -extra --no-halt +iex
# Dump environment info for logging purposes
echo "Exec: $@" -- "${1+$ARGS}"
echo "Root: $ROOTDIR"
# Start the VM
exec "$@" -- "${1+$ARGS}"
;;
*)
echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|ping|rpc <m> <f> [<a>]|console|console_clean|console_boot <file>|attach|remote_console|upgrade}"
exit 1
;;
esac
exit 0