#!/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 APP_JSON_FILE=$(mktemp "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX") trap "rm -rf '$APP_JSON_FILE' >/dev/null" RETURN INT TERM copy_from_image "$IMAGE" "app.json" "$APP_JSON_FILE" 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" } 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 local DOCKER_COMMIT_LABEL_ARGS=("--change" "\"LABEL org.label-schema.schema-version=1.0\"" "--change" "\"LABEL org.label-schema.vendor=dokku\"" "--change" "\"LABEL com.dokku.app-name=$APP\"") local DOCKER_RUN_LABEL_ARGS="--label=com.dokku.app-name=$APP" IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG") if [[ "$PHASE_SCRIPT_KEY" == "release" ]]; then SCRIPT_CMD=$(get_release_cmd "$APP" "$IMAGE_TAG" 2>/dev/null || true) else SCRIPT_CMD=$(get_phase_script "$IMAGE" "$PHASE_SCRIPT_KEY" 2>/dev/null || true) fi if [[ -z "$SCRIPT_CMD" ]]; then return fi dokku_log_exclaim "${PHASE_SCRIPT_KEY^} command declared: '$SCRIPT_CMD'" 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+=" 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+=" 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") local IMAGE_SOURCE_TYPE="dockerfile" is_image_herokuish_based "$IMAGE" && IMAGE_SOURCE_TYPE="herokuish" DOCKER_ARGS+=$(: | plugn trigger docker-args-process-deploy "$APP" "$IMAGE_TAG" "$IMAGE_SOURCE_TYPE") # 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_BIN" run "${DOCKER_RUN_LABEL_ARGS[@]}" $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_BIN" 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 eval "$DOCKER_BIN" commit "${DOCKER_COMMIT_LABEL_ARGS[@]}" "${DOCKER_COMMIT_ARGS[@]}" "$id" "$IMAGE" >/dev/null }