diff options
Diffstat (limited to 'priv/templates')
-rw-r--r-- | priv/templates/builtin_hook_pid | 12 | ||||
-rw-r--r-- | priv/templates/builtin_hook_wait_for_process | 17 | ||||
-rw-r--r-- | priv/templates/builtin_hook_wait_for_vm_start | 7 | ||||
-rwxr-xr-x | priv/templates/extended_bin | 81 | ||||
-rw-r--r-- | priv/templates/install_upgrade_escript | 23 |
5 files changed, 105 insertions, 35 deletions
diff --git a/priv/templates/builtin_hook_pid b/priv/templates/builtin_hook_pid new file mode 100644 index 0000000..0151631 --- /dev/null +++ b/priv/templates/builtin_hook_pid @@ -0,0 +1,12 @@ +#!/bin/bash + +# loop until the VM starts responding to pings +while ! $(relx_nodetool "ping">/dev/null) +do + sleep 1 +done + +# get the beam pid and write it to the file passed as +# argument +PID="$(relx_get_pid)" +echo $PID > $1 diff --git a/priv/templates/builtin_hook_wait_for_process b/priv/templates/builtin_hook_wait_for_process new file mode 100644 index 0000000..af5994d --- /dev/null +++ b/priv/templates/builtin_hook_wait_for_process @@ -0,0 +1,17 @@ +#!/bin/bash + +# loop until the VM starts responding to pings +while ! $(relx_nodetool "ping">/dev/null) +do + sleep 1 +done + +# loop until the name provided as argument gets +# registered +while true +do + if [ "$(relx_nodetool eval "whereis($1).")" != "undefined" ] + then + break + fi +done diff --git a/priv/templates/builtin_hook_wait_for_vm_start b/priv/templates/builtin_hook_wait_for_vm_start new file mode 100644 index 0000000..6b9ee12 --- /dev/null +++ b/priv/templates/builtin_hook_wait_for_vm_start @@ -0,0 +1,7 @@ +#!/bin/bash + +# loop until the VM starts responding to pings +while ! $(relx_nodetool "ping">/dev/null) +do + sleep 1 +done diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index acf77b9..c87fcf9 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -30,6 +30,14 @@ REL_DIR="$RELEASE_ROOT_DIR/releases/$REL_VSN" ERL_OPTS="{{ erl_opts }}" RUNNER_LOG_DIR="${RUNNER_LOG_DIR:-$RELEASE_ROOT_DIR/log}" +# start/stop/install/upgrade pre/post hooks +PRE_START_HOOKS="{{ pre_start_hooks }}" +POST_START_HOOKS="{{ post_start_hooks }}" +PRE_STOP_HOOKS="{{ pre_stop_hooks }}" +POST_STOP_HOOKS="{{ post_stop_hooks }}" +PRE_INSTALL_UPGRADE_HOOKS="{{ pre_install_upgrade_hooks }}" +POST_INSTALL_UPGRADE_HOOKS="{{ post_install_upgrade_hooks }}" + relx_usage() { command="$1" @@ -235,6 +243,23 @@ check_replace_os_vars() { echo $OUT_FILE_PATH } +relx_run_hooks() { + HOOKS=$1 + for hook in $HOOKS + do + # the scripts arguments at this point are separated + # from each other by | , we now replace these + # by empty spaces and give them to the `set` + # command in order to be able to extract them + # separately + set `echo "$hook" | sed -e 's/|/ /g'` + HOOK_SCRIPT=$1; shift + # all hook locations are expected to be + # relative to the start script location + [ "$SCRIPT_DIR/$HOOK_SCRIPT" ] && . "$SCRIPT_DIR/$HOOK_SCRIPT" $@ + done +} + VMARGS_PATH=$(add_path vm.args $VMARGS_PATH) # Extract the target node name from node.args NAME_ARG=$(egrep '^-s?name' "$VMARGS_PATH" || true) @@ -330,11 +355,14 @@ case "$1" in mkdir -p "$PIPE_DIR" + relx_run_hooks "$PRE_START_HOOKS" "$BINDIR/run_erl" -daemon "$PIPE_DIR" "$RUNNER_LOG_DIR" \ "$(relx_start_command)" + relx_run_hooks "$POST_START_HOOKS" ;; stop) + relx_run_hooks "$PRE_STOP_HOOKS" # Wait for the node to completely stop... PID="$(relx_get_pid)" if ! relx_nodetool "stop"; then @@ -344,6 +372,7 @@ case "$1" in do sleep 1 done + relx_run_hooks "$POST_STOP_HOOKS" ;; restart) @@ -418,8 +447,12 @@ case "$1" in exit 1 fi + relx_run_hooks "$PRE_INSTALL_UPGRADE_HOOKS" + exec "$BINDIR/escript" "$ROOTDIR/bin/install_upgrade.escript" \ "$COMMAND" "{'$REL_NAME', \"$NAME_TYPE\", '$NAME', '$COOKIE'}" "$@" + + relx_run_hooks "$POST_INSTALL_UPGRADE_HOOKS" ;; versions) @@ -435,8 +468,9 @@ case "$1" in "versions" "{'$REL_NAME', \"$NAME_TYPE\", '$NAME', '$COOKIE'}" "$@" ;; - console|console_clean|console_boot) + console|console_clean|console_boot|foreground) __code_paths="" + FOREGROUNDOPTIONS="" # .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. @@ -448,6 +482,16 @@ case "$1" in BOOTFILE="$REL_DIR/start" fi ;; + foreground) + # start up the release in the foreground for use by runit + # or other supervision services + if [ -f "$REL_DIR/$REL_NAME.boot" ]; then + BOOTFILE="$REL_DIR/$REL_NAME" + else + BOOTFILE="$REL_DIR/start" + fi + FOREGROUNDOPTIONS="-noshell -noinput +Bd" + ;; console_clean) __code_paths=$(relx_get_code_paths) BOOTFILE="$ROOTDIR/bin/start_clean" @@ -470,7 +514,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" -mode "$CODE_LOADING_MODE" \ + set -- "$BINDIR/erlexec" $FOREGROUNDOPTIONS \ + -boot "$BOOTFILE" -mode "$CODE_LOADING_MODE" \ -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ -config "$RELX_CONFIG_PATH" \ -args_file "$VMARGS_PATH" \ @@ -487,38 +532,6 @@ case "$1" in # Start the VM 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 - 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 "$RELX_CONFIG_PATH" \ - -boot_var ERTS_LIB_DIR "$ERTS_LIB_DIR" \ - -args_file "$VMARGS_PATH" - - # 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 diff --git a/priv/templates/install_upgrade_escript b/priv/templates/install_upgrade_escript index dc09f9c..c2aa06c 100644 --- a/priv/templates/install_upgrade_escript +++ b/priv/templates/install_upgrade_escript @@ -79,7 +79,18 @@ install({RelName, NameTypeArg, NodeName, Cookie}, Opts) -> [Version]) end; permanent -> - ?INFO("Release ~s is already installed and set permanent.~n",[Version]); + %% this release is marked permanent, however it might not the + %% one currently running + case current_release_version(TargetNode) of + Version -> + ?INFO("Release ~s is already installed, running and set permanent.~n", + [Version]); + CurrentVersion -> + ?INFO("Release ~s is the currently running version.~n", + [CurrentVersion]), + check_and_install(TargetNode, Version), + maybe_permafy(TargetNode, RelName, Version, Opts) + end; {error, Reason} -> ?INFO("Unpack failed: ~p~n",[Reason]), print_existing_versions(TargetNode), @@ -277,6 +288,16 @@ which_releases(TargetNode) -> R = rpc:call(TargetNode, release_handler, which_releases, [], ?TIMEOUT), [ {V, S} || {_,V,_, S} <- R ]. +%% the running release version is either the only one marked `current´ +%% or, if none exists, the one marked `permanent` +current_release_version(TargetNode) -> + R = rpc:call(TargetNode, release_handler, which_releases, + [], ?TIMEOUT), + Versions = [ {S, V} || {_,V,_, S} <- R ], + %% current version takes priority over the permanent + proplists:get_value(current, Versions, + proplists:get_value(permanent, Versions)). + print_existing_versions(TargetNode) -> VerList = iolist_to_binary([ io_lib:format("* ~s\t~s~n",[V,S]) |