From ad6193884f09d29c7402de45214817dc195f5c6d Mon Sep 17 00:00:00 2001 From: Luis Rascao Date: Sat, 5 Nov 2016 22:11:44 +0000 Subject: Refactor foreground command Move it next to console since it's mostly the same thing but with extra parameters. --- priv/templates/extended_bin | 48 +++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) (limited to 'priv/templates') diff --git a/priv/templates/extended_bin b/priv/templates/extended_bin index acf77b9..bd7342d 100755 --- a/priv/templates/extended_bin +++ b/priv/templates/extended_bin @@ -435,8 +435,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 +449,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 +481,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" \ @@ -484,38 +496,6 @@ case "$1" in echo "$RELEASE_ROOT_DIR" logger -t "$REL_NAME[$$]" "Starting up" - # 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} ;; -- cgit v1.2.3 From 3905d39d180efe125b9ef5351d1c3b27a3f825b0 Mon Sep 17 00:00:00 2001 From: Luis Rascao Date: Sat, 5 Nov 2016 22:22:19 +0000 Subject: Add support for new relx directive that provides start/stop shell script hooks New 'extended_start_script_hooks' directive that allows the developer to define six different hook shell scripts to be invoked at pre/post start/stop/install upgrade phases. Besides these custom defined scripts, other types of builtin scripts are also available, these offer pre-packaged functionality that can be used directly, they are: pid - writes the beam pid to a configurable file location (/var/run/.pid by default). wait_for_vm_start - waits for the vm to start (ie. when it responds to pings) wait_for_process - waits for a configurable name to appear in the erlang process registry The hook scripts are invoked with the 'source' command, therefore they have access to all the variables in the start script. --- priv/templates/builtin_hook_pid | 12 ++++++++++ priv/templates/builtin_hook_wait_for_process | 17 ++++++++++++++ priv/templates/builtin_hook_wait_for_vm_start | 7 ++++++ priv/templates/extended_bin | 33 +++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 priv/templates/builtin_hook_pid create mode 100644 priv/templates/builtin_hook_wait_for_process create mode 100644 priv/templates/builtin_hook_wait_for_vm_start (limited to 'priv/templates') 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 bd7342d..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) -- cgit v1.2.3