diff options
Diffstat (limited to 'priv')
-rwxr-xr-x | priv/templates/bin.dtl | 10 | ||||
-rw-r--r-- | priv/templates/extended_bin.dtl | 129 | ||||
-rw-r--r-- | priv/templates/install_upgrade_escript.dtl | 32 | ||||
-rw-r--r-- | priv/templates/nodetool.dtl | 2 |
4 files changed, 128 insertions, 45 deletions
diff --git a/priv/templates/bin.dtl b/priv/templates/bin.dtl index bb83434..3398d63 100755 --- a/priv/templates/bin.dtl +++ b/priv/templates/bin.dtl @@ -17,12 +17,11 @@ find_erts_dir() { ROOTDIR="$RELEASE_ROOT_DIR" else local erl="$(which erl)" - code="io:format(\"~s\", [code:root_dir()]), halt()." - local erl_root="$("$erl" -noshell -eval "$code")" + code="io:format(\"~s\", [code:root_dir()])." + local erl_root="$("$erl" -noshell -eval "$code" -s init stop)" ERTS_DIR="$erl_root/erts-$ERTS_VSN" ROOTDIR="$erl_root" fi - } find_sys_config() { @@ -47,7 +46,8 @@ 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" +[ -f "$REL_DIR/$REL_NAME.boot" ] && BOOTFILE="$REL_NAME" || BOOTFILE=start cd "$ROOTDIR" # Save extra arguments @@ -57,7 +57,7 @@ ARGS="$@" set -- "$ERL_OPTS" [ "$SYS_CONFIG" ] && set -- "$@" -config "$SYS_CONFIG" [ "$VM_ARGS" ] && set -- "$@" -args_file "$VM_ARGS" -set -- "$@" -boot "$REL_DIR/$REL_NAME" "$ARGS" +set -- "$@" -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" -boot "$REL_DIR/$BOOTFILE" "$ARGS" # Boot the release $BINDIR/erlexec $@ diff --git a/priv/templates/extended_bin.dtl b/priv/templates/extended_bin.dtl index ec4a8f3..ffff615 100644 --- a/priv/templates/extended_bin.dtl +++ b/priv/templates/extended_bin.dtl @@ -7,6 +7,7 @@ RELEASE_ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" REL_NAME="{{ rel_name }}" REL_VSN="{{ rel_vsn }}" ERTS_VSN="{{ erts_vsn }}" +CODE_LOADING_MODE="${CODE_LOADING_MODE:-embedded}" REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN" ERL_OPTS="{{ erl_opts }}" RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}" @@ -25,6 +26,18 @@ find_erts_dir() { 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 +} + # Connect to a remote node relx_rem_sh() { # Generate a unique id used to allow multiple remsh to the same node @@ -36,6 +49,7 @@ relx_rem_sh() { # 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" -kernel net_ticktime $TICKTIME } @@ -59,6 +73,7 @@ relx_escript() { "$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" \ @@ -84,17 +99,17 @@ fi # Make sure log directory exists mkdir -p "$RUNNER_LOG_DIR" -if [ -z "$CONFIG_PATH" ]; then +if [ -z "$RELX_CONFIG_PATH" ]; then if [ -f "$USE_DIR/sys.config" ]; then - CONFIG_PATH="$USE_DIR/sys.config" + RELX_CONFIG_PATH="$USE_DIR/sys.config" else - CONFIG_PATH="$REL_DIR/sys.config" + RELX_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 + awk '{while(match($0,"[$]{[^}]*}")) {var=substr($0,RSTART+2,RLENGTH -3);gsub("[$]{"var"}",ENVIRON[var])}}1' < $RELX_CONFIG_PATH > $RELX_CONFIG_PATH.2.config + RELX_CONFIG_PATH=$RELX_CONFIG_PATH.2.config fi # Extract the target node name from node.args @@ -117,7 +132,14 @@ case $NAME in ;; *) # Add @hostname - NAME=$NAME@`hostname -f` + case $NAME_TYPE in + -sname) + NAME=$NAME@`hostname -s` + ;; + -name) + NAME=$NAME@`hostname -f` + ;; + esac ;; esac @@ -139,6 +161,7 @@ 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" cd "$ROOTDIR" @@ -184,24 +207,9 @@ case "$1" in 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 "$RELEASE_ROOT_DIR/.*/[b]eam"|awk '{print $1}') - ;; - SunOS) - # PID COMMAND - PID=$(ps -ef -o pid= -o args=| - grep "$RELEASE_ROOT_DIR/.*/[b]eam"|awk '{print $1}') - ;; - CYGWIN*) - # UID PID PPID TTY STIME COMMAND - PID=$(ps -efw|grep "$RELEASE_ROOT_DIR/.*/[b]eam"|awk '{print $2}') - ;; - esac + PID="$(relx_get_pid)" if ! relx_nodetool "stop"; then - exit $? + exit 1 fi while $(kill -0 "$PID" 2>/dev/null); do @@ -212,37 +220,43 @@ case "$1" in restart) ## Restart the VM without exiting the process if ! relx_nodetool "restart"; then - exit $? + exit 1 fi ;; reboot) ## Restart the VM completely (uses heart to restart it) if ! relx_nodetool "reboot"; then - exit $? + 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 $? + exit 1 fi ;; escript) ## Run an escript under the node's environment if ! relx_escript $@; then - exit $? + exit 1 fi ;; attach) # Make sure a node IS running if ! relx_nodetool "ping" > /dev/null; then - ES="$?" echo "Node is not running!" - exit $ES + exit 1 fi shift @@ -252,9 +266,8 @@ case "$1" in remote_console) # Make sure a node IS running if ! relx_nodetool "ping" > /dev/null; then - ES="$?" echo "Node is not running!" - exit $ES + exit 1 fi shift @@ -271,13 +284,30 @@ case "$1" in # Make sure a node IS running if ! relx_nodetool "ping" > /dev/null; then - ES="$?" echo "Node is not running!" - exit $ES + exit 1 fi exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ - "$REL_NAME" "$NAME" "$COOKIE" "$2" + "install" "$REL_NAME" "$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" "$COOKIE" "$2" ;; console|console_clean|console_boot) @@ -314,7 +344,8 @@ case "$1" in # 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" \ + -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ + -env ERL_LIBS "$REL_DIR/lib" -config "$RELX_CONFIG_PATH" \ -args_file "$VMARGS_PATH" # Dump environment info for logging purposes @@ -349,7 +380,8 @@ case "$1" in # 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" \ + -boot "$REL_DIR/$BOOTFILE" -mode "$CODE_LOADING_MODE" -config "$RELX_CONFIG_PATH" \ + -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ -args_file "$VMARGS_PATH" # Dump environment info for logging purposes @@ -359,8 +391,31 @@ case "$1" in # 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|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|escript}" + echo "Usage: $REL_NAME {start|start_boot <file>|foreground|stop|restart|reboot|pid|ping|console|console_clean|console_boot <file>|attach|remote_console|upgrade|escript|rpc|rpcterms}" exit 1 ;; esac diff --git a/priv/templates/install_upgrade_escript.dtl b/priv/templates/install_upgrade_escript.dtl index dce2e11..3fb9d04 100644 --- a/priv/templates/install_upgrade_escript.dtl +++ b/priv/templates/install_upgrade_escript.dtl @@ -6,8 +6,36 @@ -define(TIMEOUT, 300000). -define(INFO(Fmt,Args), io:format(Fmt,Args)). -%% Upgrades, to a new tar.gz release -main([RelName, NodeName, Cookie, VersionArg]) -> +%% Unpack or upgrade to a new tar.gz release +main(["unpack", RelName, NodeName, Cookie, VersionArg]) -> + TargetNode = start_distribution(NodeName, Cookie), + WhichReleases = which_releases(TargetNode), + Version = parse_version(VersionArg), + case proplists:get_value(Version, WhichReleases) of + undefined -> + %% not installed, so unpack tarball: + ?INFO("Release ~s not found, attempting to unpack releases/~s/~s.tar.gz~n",[Version,Version,RelName]), + ReleasePackage = Version ++ "/" ++ RelName, + case rpc:call(TargetNode, release_handler, unpack_release, + [ReleasePackage], ?TIMEOUT) of + {ok, Vsn} -> + ?INFO("Unpacked successfully: ~p~n", [Vsn]); + {error, UnpackReason} -> + print_existing_versions(TargetNode), + ?INFO("Unpack failed: ~p~n",[UnpackReason]), + erlang:halt(2) + end; + old -> + %% no need to unpack, has been installed previously + ?INFO("Release ~s is marked old, switching to it.~n",[Version]); + unpacked -> + ?INFO("Release ~s is already unpacked, now installing.~n",[Version]); + current -> + ?INFO("Release ~s is already installed and current. Making permanent.~n",[Version]); + permanent -> + ?INFO("Release ~s is already installed, and set permanent.~n",[Version]) + end; +main(["install", RelName, NodeName, Cookie, VersionArg]) -> TargetNode = start_distribution(NodeName, Cookie), WhichReleases = which_releases(TargetNode), Version = parse_version(VersionArg), diff --git a/priv/templates/nodetool.dtl b/priv/templates/nodetool.dtl index 2f46395..dee14b4 100644 --- a/priv/templates/nodetool.dtl +++ b/priv/templates/nodetool.dtl @@ -44,7 +44,7 @@ main(Args) -> end; ["rpcterms", Module, Function | ArgsAsString] -> case rpc:call(TargetNode, list_to_atom(Module), list_to_atom(Function), - consult(ArgsAsString), 60000) of + consult(lists:flatten(ArgsAsString)), 60000) of {badrpc, Reason} -> io:format("RPC to ~p failed: ~p\n", [TargetNode, Reason]), halt(1); |