Merge pull request #3381 from dokku/3136-release-support
Add support for the Procfile release command
This commit is contained in:
@@ -1,106 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
|
||||
get_phase_script() {
|
||||
declare desc="extracts app.json from app image and returns the appropriate json key/value"
|
||||
local IMAGE="$1"
|
||||
local PHASE_SCRIPT_KEY="$2"
|
||||
local GET_PHASE_SCRIPT_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_get_phase_script.XXXX")
|
||||
local APP_JSON_FILE="$GET_PHASE_SCRIPT_TMP_WORK_DIR/app.json"
|
||||
trap 'rm -rf "$GET_PHASE_SCRIPT_TMP_WORK_DIR" > /dev/null' RETURN INT TERM
|
||||
|
||||
copy_from_image "$IMAGE" "app.json" "$GET_PHASE_SCRIPT_TMP_WORK_DIR" 2>/dev/null || true
|
||||
|
||||
if [[ -f "$APP_JSON_FILE" ]]; then
|
||||
local VALUE=$(get_json_value "scripts.dokku.${PHASE_SCRIPT_KEY}" <"$APP_JSON_FILE")
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "$VALUE"
|
||||
}
|
||||
|
||||
execute_script() {
|
||||
declare desc="executes appropriate phase script key from app.json"
|
||||
local APP="$1"
|
||||
local IMAGE_TAG="$2"
|
||||
local PHASE_SCRIPT_KEY="$3"
|
||||
local IMAGE id
|
||||
|
||||
IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG")
|
||||
local SCRIPT_CMD=$(get_phase_script "$IMAGE" "$PHASE_SCRIPT_KEY" 2>/dev/null)
|
||||
if [[ -n "$SCRIPT_CMD" ]]; then
|
||||
dokku_log_info1 "Running '$SCRIPT_CMD' in app container"
|
||||
local COMMAND
|
||||
COMMAND="set -eo pipefail; [[ \$DOKKU_TRACE ]] && set -x ; "
|
||||
COMMAND+=" if [[ -d '/app' ]]; then "
|
||||
COMMAND+=" export HOME=/app ; "
|
||||
COMMAND+=" cd \$HOME ; "
|
||||
COMMAND+=" fi ; "
|
||||
COMMAND+=" if [[ -d '/app/.profile.d' ]]; then "
|
||||
COMMAND+=" for file in /app/.profile.d/*; do source \$file; done ; "
|
||||
COMMAND+=" fi ; "
|
||||
COMMAND+=" if [[ -d '/cache' ]]; then "
|
||||
COMMAND+=" echo restoring installation cache... ; "
|
||||
COMMAND+=" rm -rf /tmp/cache ; "
|
||||
COMMAND+=" ln -sf /cache /tmp/cache ; "
|
||||
COMMAND+=" fi ; "
|
||||
|
||||
if [[ "$SCRIPT_CMD" == /* ]]; then
|
||||
local SCRIPT_BIN="$(echo "$SCRIPT_CMD" | cut -d' ' -f1)"
|
||||
COMMAND+=" if [[ ! -x \"$SCRIPT_BIN\" ]]; then "
|
||||
COMMAND+=" echo specified binary is not executable ; "
|
||||
COMMAND+=" exit 1 ; "
|
||||
COMMAND+=" fi "
|
||||
fi
|
||||
|
||||
COMMAND+=" $SCRIPT_CMD || exit 1;"
|
||||
COMMAND+=" if [[ -d '/cache' ]]; then "
|
||||
COMMAND+=" echo removing installation cache... ; "
|
||||
COMMAND+=" rm -f /tmp/cache ; "
|
||||
COMMAND+=" fi "
|
||||
|
||||
local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
|
||||
local CACHE_HOST_DIR="$DOKKU_HOST_ROOT/$APP/cache"
|
||||
[[ -d $CACHE_DIR ]] || mkdir -p "$CACHE_DIR"
|
||||
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG")
|
||||
# strip --restart args from DOCKER_ARGS
|
||||
local DOCKER_ARGS=$(sed -e "s/--restart=[[:graph:]]\+[[:blank:]]\?//g" <<<"$DOCKER_ARGS")
|
||||
|
||||
# eval args as array to respect escapes
|
||||
declare -a ARG_ARRAY
|
||||
eval "ARG_ARRAY=($DOCKER_ARGS)"
|
||||
|
||||
local DOKKU_APP_SHELL="/bin/bash"
|
||||
DOKKU_APP_SHELL="$(config_get --global DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")"
|
||||
DOKKU_APP_SHELL="$(config_get "$APP" DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")"
|
||||
[[ -z "$DOKKU_APP_SHELL" ]] && DOKKU_APP_SHELL="/bin/bash"
|
||||
|
||||
id=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" -e DOKKU_TRACE="$DOKKU_TRACE" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_HOST_DIR:/cache" "${ARG_ARRAY[@]}" "$IMAGE" "$DOKKU_APP_SHELL" -c "$COMMAND")
|
||||
if test "$(docker wait "$id")" -eq 0; then
|
||||
dokku_container_log_verbose_quiet "$id"
|
||||
if [[ "$PHASE_SCRIPT_KEY" != "postdeploy" ]]; then
|
||||
if ! is_image_herokuish_based "$IMAGE"; then
|
||||
local DOKKU_DOCKERFILE_ENTRYPOINT=$(config_get "$APP" DOKKU_DOCKERFILE_ENTRYPOINT)
|
||||
local DOKKU_DOCKERFILE_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_CMD)
|
||||
[[ -z "$DOKKU_DOCKERFILE_ENTRYPOINT" ]] && DOKKU_DOCKERFILE_ENTRYPOINT="$(get_entrypoint_from_image "$IMAGE")"
|
||||
[[ -z "$DOKKU_DOCKERFILE_CMD" ]] && DOKKU_DOCKERFILE_CMD="$(get_cmd_from_image "$IMAGE")"
|
||||
|
||||
[[ -n "$DOKKU_DOCKERFILE_ENTRYPOINT" ]] && local DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG="--change='$DOKKU_DOCKERFILE_ENTRYPOINT'"
|
||||
[[ -n "$DOKKU_DOCKERFILE_CMD" ]] && local DOCKER_COMMIT_CMD_CHANGE_ARG="--change='$DOKKU_DOCKERFILE_CMD'"
|
||||
|
||||
local DOCKER_COMMIT_ARGS="$DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG $DOCKER_COMMIT_CMD_CHANGE_ARG"
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
eval docker commit $DOCKER_COMMIT_ARGS "$id" "$IMAGE" >/dev/null
|
||||
fi
|
||||
else
|
||||
dokku_container_log_verbose_quiet "$id"
|
||||
dokku_log_fail "execution of '$SCRIPT_CMD' failed!"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/00_dokku-standard/exec-app-json-scripts"
|
||||
|
||||
exec_app_json_scripts() {
|
||||
declare desc="core app.json scripts execution"
|
||||
local trigger="post-deploy app_json_scripts"
|
||||
local APP="$1"
|
||||
local IMAGE_TAG="$4"
|
||||
local PHASE_SCRIPT_KEY="postdeploy"
|
||||
|
||||
dokku_log_info1 "Attempting to run scripts.dokku.$PHASE_SCRIPT_KEY from app.json (if defined)"
|
||||
execute_script "$APP" "$IMAGE_TAG" "$PHASE_SCRIPT_KEY"
|
||||
}
|
||||
|
||||
exec_app_json_scripts "$@"
|
||||
@@ -1,18 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/00_dokku-standard/exec-app-json-scripts"
|
||||
|
||||
exec_app_json_scripts() {
|
||||
declare desc="core app.json scripts execution"
|
||||
local trigger="pre-deploy app_json_scripts"
|
||||
local APP="$1"
|
||||
local IMAGE_TAG="$2"
|
||||
local PHASE_SCRIPT_KEY="predeploy"
|
||||
|
||||
dokku_log_info1 "Attempting to run scripts.dokku.$PHASE_SCRIPT_KEY from app.json (if defined)"
|
||||
execute_script "$APP" "$IMAGE_TAG" "$PHASE_SCRIPT_KEY"
|
||||
}
|
||||
|
||||
exec_app_json_scripts "$@"
|
||||
122
plugins/app-json/internal-functions
Executable file
122
plugins/app-json/internal-functions
Executable file
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
||||
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
|
||||
|
||||
get_phase_script() {
|
||||
declare desc="extracts app.json from app image and returns the appropriate json key/value"
|
||||
declare IMAGE_TAG="$1" PHASE_SCRIPT_KEY="$2"
|
||||
local GET_PHASE_SCRIPT_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku_get_phase_script.XXXX")
|
||||
local APP_JSON_FILE="$GET_PHASE_SCRIPT_TMP_WORK_DIR/app.json"
|
||||
trap 'rm -rf "$GET_PHASE_SCRIPT_TMP_WORK_DIR" > /dev/null' RETURN INT TERM
|
||||
|
||||
copy_from_image "$IMAGE" "app.json" "$GET_PHASE_SCRIPT_TMP_WORK_DIR" 2>/dev/null || true
|
||||
|
||||
if [[ ! -f "$APP_JSON_FILE" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
get_json_value "scripts.dokku.${PHASE_SCRIPT_KEY}" <"$APP_JSON_FILE"
|
||||
}
|
||||
|
||||
get_release_cmd() {
|
||||
declare desc="extracts the release command from a given app's procfile"
|
||||
declare APP="$1" IMAGE_TAG="$2"
|
||||
|
||||
extract_procfile "$APP" "$IMAGE_TAG" >/dev/null
|
||||
trap 'remove_procfile $APP' RETURN INT TERM EXIT
|
||||
|
||||
get_cmd_from_procfile "$APP" "release" "5000" || true
|
||||
}
|
||||
|
||||
execute_script() {
|
||||
declare desc="executes appropriate phase script key from app.json"
|
||||
declare APP="$1" IMAGE_TAG="$2" PHASE_SCRIPT_KEY="$3"
|
||||
local IMAGE id SCRIPT_CMD
|
||||
|
||||
IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG")
|
||||
if [[ "$PHASE_SCRIPT_KEY" == "release" ]]; then
|
||||
SCRIPT_CMD=$(get_release_cmd "$APP" "$IMAGE" 2>/dev/null)
|
||||
else
|
||||
SCRIPT_CMD=$(get_phase_script "$IMAGE" "$PHASE_SCRIPT_KEY" 2>/dev/null)
|
||||
fi
|
||||
|
||||
if [[ -z "$SCRIPT_CMD" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
dokku_log_info1 "Running '$SCRIPT_CMD' in app container"
|
||||
local COMMAND
|
||||
COMMAND="set -eo pipefail; [[ \$DOKKU_TRACE ]] && set -x ; "
|
||||
COMMAND+=" if [[ -d '/app' ]]; then "
|
||||
COMMAND+=" export HOME=/app ; "
|
||||
COMMAND+=" cd \$HOME ; "
|
||||
COMMAND+=" fi ; "
|
||||
COMMAND+=" if [[ -d '/app/.profile.d' ]]; then "
|
||||
COMMAND+=" for file in /app/.profile.d/*; do source \$file; done ; "
|
||||
COMMAND+=" fi ; "
|
||||
COMMAND+=" if [[ -d '/cache' ]]; then "
|
||||
COMMAND+=" echo restoring installation cache... ; "
|
||||
COMMAND+=" rm -rf /tmp/cache ; "
|
||||
COMMAND+=" ln -sf /cache /tmp/cache ; "
|
||||
COMMAND+=" fi ; "
|
||||
|
||||
if [[ "$SCRIPT_CMD" == /* ]]; then
|
||||
local SCRIPT_BIN="$(echo "$SCRIPT_CMD" | cut -d' ' -f1)"
|
||||
COMMAND+=" if [[ ! -x \"$SCRIPT_BIN\" ]]; then "
|
||||
COMMAND+=" echo specified binary is not executable ; "
|
||||
COMMAND+=" exit 1 ; "
|
||||
COMMAND+=" fi "
|
||||
fi
|
||||
|
||||
COMMAND+=" $SCRIPT_CMD || exit 1;"
|
||||
COMMAND+=" if [[ -d '/cache' ]]; then "
|
||||
COMMAND+=" echo removing installation cache... ; "
|
||||
COMMAND+=" rm -f /tmp/cache ; "
|
||||
COMMAND+=" fi "
|
||||
|
||||
local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
|
||||
local CACHE_HOST_DIR="$DOKKU_HOST_ROOT/$APP/cache"
|
||||
[[ -d $CACHE_DIR ]] || mkdir -p "$CACHE_DIR"
|
||||
|
||||
local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG")
|
||||
# strip --restart args from DOCKER_ARGS
|
||||
local DOCKER_ARGS=$(sed -e "s/--restart=[[:graph:]]\+[[:blank:]]\?//g" <<<"$DOCKER_ARGS")
|
||||
|
||||
# eval args as array to respect escapes
|
||||
declare -a ARG_ARRAY
|
||||
eval "ARG_ARRAY=($DOCKER_ARGS)"
|
||||
|
||||
local DOKKU_APP_SHELL="/bin/bash"
|
||||
DOKKU_APP_SHELL="$(config_get --global DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")"
|
||||
DOKKU_APP_SHELL="$(config_get "$APP" DOKKU_APP_SHELL || echo "$DOKKU_APP_SHELL")"
|
||||
[[ -z "$DOKKU_APP_SHELL" ]] && DOKKU_APP_SHELL="/bin/bash"
|
||||
|
||||
id=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" -e DOKKU_TRACE="$DOKKU_TRACE" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_HOST_DIR:/cache" "${ARG_ARRAY[@]}" "$IMAGE" "$DOKKU_APP_SHELL" -c "$COMMAND")
|
||||
if test "$(docker wait "$id")" -ne 0; then
|
||||
dokku_container_log_verbose_quiet "$id"
|
||||
dokku_log_fail "execution of '$SCRIPT_CMD' failed!"
|
||||
fi
|
||||
|
||||
dokku_container_log_verbose_quiet "$id"
|
||||
if [[ "$PHASE_SCRIPT_KEY" != "predeploy" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
if ! is_image_herokuish_based "$IMAGE"; then
|
||||
local DOKKU_DOCKERFILE_ENTRYPOINT=$(config_get "$APP" DOKKU_DOCKERFILE_ENTRYPOINT)
|
||||
local DOKKU_DOCKERFILE_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_CMD)
|
||||
[[ -z "$DOKKU_DOCKERFILE_ENTRYPOINT" ]] && DOKKU_DOCKERFILE_ENTRYPOINT="$(get_entrypoint_from_image "$IMAGE")"
|
||||
[[ -z "$DOKKU_DOCKERFILE_CMD" ]] && DOKKU_DOCKERFILE_CMD="$(get_cmd_from_image "$IMAGE")"
|
||||
|
||||
[[ -n "$DOKKU_DOCKERFILE_ENTRYPOINT" ]] && local DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG="--change='$DOKKU_DOCKERFILE_ENTRYPOINT'"
|
||||
[[ -n "$DOKKU_DOCKERFILE_CMD" ]] && local DOCKER_COMMIT_CMD_CHANGE_ARG="--change='$DOKKU_DOCKERFILE_CMD'"
|
||||
|
||||
local DOCKER_COMMIT_ARGS="$DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG $DOCKER_COMMIT_CMD_CHANGE_ARG"
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
eval docker commit $DOCKER_COMMIT_ARGS "$id" "$IMAGE" >/dev/null
|
||||
}
|
||||
4
plugins/app-json/plugin.toml
Normal file
4
plugins/app-json/plugin.toml
Normal file
@@ -0,0 +1,4 @@
|
||||
[plugin]
|
||||
description = "dokku core app-json plugin"
|
||||
version = "0.13.4"
|
||||
[plugin.config]
|
||||
17
plugins/app-json/post-deploy
Executable file
17
plugins/app-json/post-deploy
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/app-json/internal-functions"
|
||||
|
||||
app_json_post_deploy() {
|
||||
declare desc="app-json scripts execution"
|
||||
local trigger="app_json_post_deploy"
|
||||
local APP="$1"
|
||||
local IMAGE_TAG="$4"
|
||||
local PHASE_SCRIPT_KEY="postdeploy"
|
||||
|
||||
execute_script "$APP" "$IMAGE_TAG" "$PHASE_SCRIPT_KEY"
|
||||
}
|
||||
|
||||
app_json_post_deploy "$@"
|
||||
18
plugins/app-json/pre-deploy
Executable file
18
plugins/app-json/pre-deploy
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
[[ $DOKKU_TRACE ]] && set -x
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
||||
source "$PLUGIN_CORE_AVAILABLE_PATH/app-json/internal-functions"
|
||||
|
||||
app_json_pre_deploy() {
|
||||
declare desc="app-json scripts execution"
|
||||
local trigger="app_json_pre_deploy"
|
||||
local APP="$1"
|
||||
local IMAGE_TAG="$2"
|
||||
local PHASE_SCRIPT_KEY="predeploy"
|
||||
|
||||
execute_script "$APP" "$IMAGE_TAG" "$PHASE_SCRIPT_KEY"
|
||||
execute_script "$APP" "$IMAGE_TAG" "release"
|
||||
}
|
||||
|
||||
app_json_pre_deploy "$@"
|
||||
Reference in New Issue
Block a user