more style/function tweaks

This commit is contained in:
Michael Hobbs
2016-03-02 10:50:09 -08:00
committed by Michael Hobbs
parent 89f289b433
commit aa2415eeb8
40 changed files with 702 additions and 531 deletions

View File

@@ -8,6 +8,8 @@ source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
dokku_receive() { dokku_receive() {
local desc="receives an app kicks off deploy process"
local cmd="receive"
local APP="$2"; local IMAGE=$(get_app_image_name "$APP"); local IMAGE_SOURCE_TYPE="$3"; local TMP_WORK_DIR="$4" local APP="$2"; local IMAGE=$(get_app_image_name "$APP"); local IMAGE_SOURCE_TYPE="$3"; local TMP_WORK_DIR="$4"
if [[ -z "$DOKKU_SKIP_CLEANUP" ]]; then if [[ -z "$DOKKU_SKIP_CLEANUP" ]]; then
dokku_log_info1 "Cleaning up..." dokku_log_info1 "Cleaning up..."
@@ -21,6 +23,8 @@ dokku_receive() {
} }
dokku_deploy() { dokku_deploy() {
local desc="deploy phase"
local cmd="deploy"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to deploy" [[ -z $2 ]] && dokku_log_fail "Please specify an app to deploy"
local APP="$2"; local IMAGE_TAG="$3"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG") local APP="$2"; local IMAGE_TAG="$3"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP" verify_app_name "$APP"
@@ -55,9 +59,9 @@ dokku_deploy() {
[[ -n "$DOKKU_HEROKUISH" ]] && local START_CMD="/start $PROC_TYPE" [[ -n "$DOKKU_HEROKUISH" ]] && local START_CMD="/start $PROC_TYPE"
if [[ -z "$DOKKU_HEROKUISH" ]]; then if [[ -z "$DOKKU_HEROKUISH" ]]; then
local DOKKU_DOCKERFILE_PORTS=($(dokku config:get "$APP" DOKKU_DOCKERFILE_PORTS || true)) local DOKKU_DOCKERFILE_PORTS=($(config_get "$APP" DOKKU_DOCKERFILE_PORTS || true))
local DOKKU_DOCKERFILE_PORT=$(dokku config:get "$APP" DOKKU_DOCKERFILE_PORT || true) local DOKKU_DOCKERFILE_PORT=$(config_get "$APP" DOKKU_DOCKERFILE_PORT || true)
local DOKKU_DOCKERFILE_START_CMD=$(dokku config:get "$APP" DOKKU_DOCKERFILE_START_CMD || true) local DOKKU_DOCKERFILE_START_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_START_CMD || true)
local DOKKU_PROCFILE_START_CMD=$(get_cmd_from_procfile "$APP" "$PROC_TYPE") local DOKKU_PROCFILE_START_CMD=$(get_cmd_from_procfile "$APP" "$PROC_TYPE")
local START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD} local START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD}
fi fi
@@ -77,7 +81,7 @@ dokku_deploy() {
local DOKKU_DOCKER_PORT_ARGS+=" -p $p " local DOKKU_DOCKER_PORT_ARGS+=" -p $p "
done done
fi fi
if [[ "$DOKKU_IS_APP_PROXY_ENABLED" = "true" ]]; then if [[ "$DOKKU_IS_APP_PROXY_ENABLED" == "true" ]]; then
# shellcheck disable=SC2086 # shellcheck disable=SC2086
local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD) local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD)
local ipaddr=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$id") local ipaddr=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$id")
@@ -99,7 +103,8 @@ dokku_deploy() {
# if we can't post-deploy successfully, kill new container # if we can't post-deploy successfully, kill new container
kill_new() { kill_new() {
local desc="wrapper function to kill newly started app container" local desc="wrapper function to kill newly started app container"
docker inspect "$id" &> /dev/null && docker stop "$id" > /dev/null && docker kill "$id" > /dev/null local id="$1"
docker inspect "$id" &> /dev/null && docker stop "$id" > /dev/null && docker kill "$id" &> /dev/null
trap - INT TERM EXIT trap - INT TERM EXIT
kill -9 $$ kill -9 $$
} }
@@ -108,7 +113,7 @@ dokku_deploy() {
if [[ "$(is_app_checks_enabled "$APP")" == "false" ]]; then if [[ "$(is_app_checks_enabled "$APP")" == "false" ]]; then
dokku_log_info1 "zero downtime is disabled for app ($APP). skipping pre-flight checks" dokku_log_info1 "zero downtime is disabled for app ($APP). skipping pre-flight checks"
else else
trap kill_new INT TERM EXIT trap 'kill_new $id' INT TERM EXIT
dokku_log_info1 "Running pre-flight checks" dokku_log_info1 "Running pre-flight checks"
plugn trigger check-deploy "$APP" "$id" "$PROC_TYPE" "$port" "$ipaddr" plugn trigger check-deploy "$APP" "$id" "$PROC_TYPE" "$port" "$ipaddr"
trap - INT TERM EXIT trap - INT TERM EXIT
@@ -144,8 +149,8 @@ dokku_deploy() {
if [[ -n "$oldids" ]]; then if [[ -n "$oldids" ]]; then
if [[ -z "$DOKKU_WAIT_TO_RETIRE" ]]; then if [[ -z "$DOKKU_WAIT_TO_RETIRE" ]]; then
local DOKKU_APP_DOKKU_WAIT_TO_RETIRE=$(dokku config:get "$APP" DOKKU_WAIT_TO_RETIRE || true) local DOKKU_APP_DOKKU_WAIT_TO_RETIRE=$(config_get "$APP" DOKKU_WAIT_TO_RETIRE || true)
local DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE=$(dokku config:get --global DOKKU_WAIT_TO_RETIRE || true) local DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE=$(config_get --global DOKKU_WAIT_TO_RETIRE || true)
local DOKKU_WAIT_TO_RETIRE=${DOKKU_APP_DOKKU_WAIT_TO_RETIRE:="$DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE"} local DOKKU_WAIT_TO_RETIRE=${DOKKU_APP_DOKKU_WAIT_TO_RETIRE:="$DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE"}
fi fi
@@ -176,6 +181,8 @@ dokku_deploy() {
} }
dokku_build() { dokku_build() {
local desc="build phase"
local cmd="build"
local APP="$2"; local IMAGE_SOURCE_TYPE="$3"; local TMP_WORK_DIR="$4"; local IMAGE=$(get_app_image_name "$APP") local APP="$2"; local IMAGE_SOURCE_TYPE="$3"; local TMP_WORK_DIR="$4"; local IMAGE=$(get_app_image_name "$APP")
verify_app_name "$APP" verify_app_name "$APP"
@@ -224,6 +231,8 @@ dokku_build() {
} }
dokku_release() { dokku_release() {
local desc="release phase"
local cmd="release"
local APP="$2"; local IMAGE_SOURCE_TYPE="$3"; local IMAGE_TAG="$4"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG") local APP="$2"; local IMAGE_SOURCE_TYPE="$3"; local IMAGE_TAG="$4"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP" verify_app_name "$APP"
@@ -256,6 +265,8 @@ dokku_release() {
} }
dokku_trace() { dokku_trace() {
local desc="enables/disables DOKKU_TRACE"
local cmd="trace"
[[ -d $DOKKU_ROOT/.dokkurc ]] || mkdir -p "$DOKKU_ROOT/.dokkurc" [[ -d $DOKKU_ROOT/.dokkurc ]] || mkdir -p "$DOKKU_ROOT/.dokkurc"
[[ "$2" == "on" ]] || [[ "$2" == "off" ]] || { [[ "$2" == "on" ]] || [[ "$2" == "off" ]] || {
dokku_log_fail "Valid trace options are [on/off]" dokku_log_fail "Valid trace options are [on/off]"
@@ -273,6 +284,8 @@ dokku_trace() {
} }
dokku_ls() { dokku_ls() {
local desc="lists installed apps with status"
local cmd="ls"
local installed_apps=$(dokku_apps) local installed_apps=$(dokku_apps)
local dokku_app local dokku_app
@@ -297,6 +310,8 @@ dokku_ls() {
} }
dokku_run() { dokku_run() {
local desc="runs command in container based on app image"
local cmd="run"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on" [[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
local APP="$2"; local IMAGE_TAG=$(get_running_image_tag "$APP"); local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG") local APP="$2"; local IMAGE_TAG=$(get_running_image_tag "$APP"); local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP" verify_app_name "$APP"
@@ -304,8 +319,8 @@ dokku_run() {
shift 2 shift 2
if [[ -z "$DOKKU_RM_CONTAINER" ]]; then if [[ -z "$DOKKU_RM_CONTAINER" ]]; then
local DOKKU_APP_RM_CONTAINER=$(dokku config:get "$APP" DOKKU_RM_CONTAINER || true) local DOKKU_APP_RM_CONTAINER=$(config_get "$APP" DOKKU_RM_CONTAINER || true)
local DOKKU_GLOBAL_RM_CONTAINER=$(dokku config:get --global DOKKU_RM_CONTAINER || true) local DOKKU_GLOBAL_RM_CONTAINER=$(config_get --global DOKKU_RM_CONTAINER || true)
local DOKKU_RM_CONTAINER=${DOKKU_APP_RM_CONTAINER:="$DOKKU_GLOBAL_RM_CONTAINER"} local DOKKU_RM_CONTAINER=${DOKKU_APP_RM_CONTAINER:="$DOKKU_GLOBAL_RM_CONTAINER"}
fi fi
@@ -313,7 +328,7 @@ dokku_run() {
[[ "$DOKKU_TRACE" ]] && local DOCKER_ARGS+=" -e TRACE=true " [[ "$DOKKU_TRACE" ]] && local DOCKER_ARGS+=" -e TRACE=true "
[[ "$DOKKU_RM_CONTAINER" ]] && local DOKKU_RUN_OPTS="--rm" [[ "$DOKKU_RM_CONTAINER" ]] && local DOKKU_RUN_OPTS="--rm"
has_tty && local DOKKU_RUN_OPTS+=" -i -t" has_tty && local DOKKU_RUN_OPTS+=" -i -t"
is_image_herokuish_based "$IMAGE" && EXEC_CMD="/exec" is_image_herokuish_based "$IMAGE" && local EXEC_CMD="/exec"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
docker run $DOKKU_GLOBAL_RUN_ARGS $DOKKU_RUN_OPTS $DOCKER_ARGS $IMAGE $EXEC_CMD "$@" docker run $DOKKU_GLOBAL_RUN_ARGS $DOKKU_RUN_OPTS $DOCKER_ARGS $IMAGE $EXEC_CMD "$@"
} }

View File

@@ -1,27 +1,13 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"
case "$0" in
*pre-deploy)
IMAGE_TAG="$2"
IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
PHASE_SCRIPT_KEY="predeploy"
;;
*post-deploy)
IMAGE_TAG="$4"
IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
PHASE_SCRIPT_KEY="postdeploy"
;;
esac
get_phase_script() { get_phase_script() {
local desc="extracts app.json from app image and returns the appropriate json key/value" local desc="extracts app.json from app image and returns the appropriate json key/value"
local PHASE_SCRIPT_KEY="$1" local IMAGE="$1"; local PHASE_SCRIPT_KEY="$2"
local TMP_WORK_DIR=$(mktemp -d -t "dokku_get_phase_script.XXXX") local TMP_WORK_DIR=$(mktemp -d -t "dokku_get_phase_script.XXXX")
local APP_JSON_FILE="$TMP_WORK_DIR/app.json" local APP_JSON_FILE="$TMP_WORK_DIR/app.json"
trap 'rm -rf "$TMP_WORK_DIR" > /dev/null' RETURN trap 'rm -rf "$TMP_WORK_DIR" > /dev/null' RETURN INT TERM
copy_from_image "$IMAGE" "/app/app.json" "$TMP_WORK_DIR" 2>/dev/null || true copy_from_image "$IMAGE" "/app/app.json" "$TMP_WORK_DIR" 2>/dev/null || true
@@ -36,7 +22,8 @@ get_phase_script() {
execute_script() { execute_script() {
local desc="executes appropriate phase script key from app.json" local desc="executes appropriate phase script key from app.json"
local SCRIPT_CMD=$(get_phase_script "$PHASE_SCRIPT_KEY") local APP="$1"; local IMAGE="$2"; local PHASE_SCRIPT_KEY="$3"
local SCRIPT_CMD=$(get_phase_script "$IMAGE" "$PHASE_SCRIPT_KEY")
if [[ -n "$SCRIPT_CMD" ]];then if [[ -n "$SCRIPT_CMD" ]];then
dokku_log_info1 "Running '$SCRIPT_CMD' in app container" dokku_log_info1 "Running '$SCRIPT_CMD' in app container"
local COMMAND="cd /app ; " local COMMAND="cd /app ; "
@@ -49,7 +36,7 @@ execute_script() {
local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP") local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP")
local CACHE_DIR="$DOKKU_ROOT/$APP/cache" local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
id=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_DIR:/cache" $DOCKER_ARGS "$IMAGE" /bin/bash -c "$COMMAND") local id=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_DIR:/cache" $DOCKER_ARGS "$IMAGE" /bin/bash -c "$COMMAND")
test "$(docker wait "$id")" -eq 0 test "$(docker wait "$id")" -eq 0
dokku_container_log_verbose_quiet "$id" dokku_container_log_verbose_quiet "$id"
if [[ "$PHASE_SCRIPT_KEY" != "postdeploy" ]];then if [[ "$PHASE_SCRIPT_KEY" != "postdeploy" ]];then
@@ -58,5 +45,26 @@ execute_script() {
fi fi
} }
dokku_log_info1 "Attempting to run scripts.dokku.$PHASE_SCRIPT_KEY from app.json (if defined)" exec_app_json_scripts() {
execute_script local desc="core app.json scripts execution"
local trigger="$0 app_json_scripts"
local APP="$1"
case "$0" in
*pre-deploy)
local IMAGE_TAG="$2"
local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
local PHASE_SCRIPT_KEY="predeploy"
;;
*post-deploy)
local IMAGE_TAG="$4"
local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
local PHASE_SCRIPT_KEY="postdeploy"
;;
esac
dokku_log_info1 "Attempting to run scripts.dokku.$PHASE_SCRIPT_KEY from app.json (if defined)"
execute_script "$APP" "$IMAGE" "$PHASE_SCRIPT_KEY"
}
exec_app_json_scripts "$@"

View File

@@ -13,3 +13,35 @@ apps_create() {
echo "Creating $APP... done" echo "Creating $APP... done"
plugn trigger post-create "$APP" plugn trigger post-create "$APP"
} }
apps_destroy() {
local APP="$1"; local IMAGE_TAG=$(get_running_image_tag "$APP")
verify_app_name "$APP"
if [[ -z "$DOKKU_APPS_FORCE_DELETE" ]]; then
dokku_log_warn "WARNING: Potentially Destructive Action"
dokku_log_warn "This command will destroy $APP (including all add-ons)."
dokku_log_warn "To proceed, type \"$APP\""
echo ""
read -rp "> " app_name
if [[ "$app_name" != "$APP" ]]; then
dokku_log_fail "Confirmation did not match $APP. Aborted."
fi
fi
echo "Destroying $APP (including all add-ons)"
plugn trigger pre-delete "$APP" "$IMAGE_TAG"
local DOKKU_APP_CIDS=$(get_app_container_ids "$APP")
local cid
if [[ -n $DOKKU_APP_CIDS ]]; then
for cid in $DOKKU_APP_CIDS; do
docker stop "$cid" > /dev/null || true
docker rm "$cid" > /dev/null || true
done
fi
plugn trigger post-delete "$APP" "$IMAGE_TAG"
}

View File

@@ -2,11 +2,17 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_REPO=$(get_app_image_repo "$APP") app_post_delete() {
[[ -n $APP ]] && rm -rf "${DOKKU_ROOT:?}/$APP" > /dev/null local desc="apps post-delete plugin trigger"
local trigger="app_post_delete"
local APP="$1"; local IMAGE_REPO=$(get_app_image_repo "$APP")
[[ -n $APP ]] && rm -rf "${DOKKU_ROOT:?}/$APP" > /dev/null
# remove all application containers & images # remove all application containers & images
# shellcheck disable=SC2046 # shellcheck disable=SC2046
docker rm -f $(docker ps -a --no-trunc | egrep "dokku/${APP}:" | awk '{ print $1 }' | xargs) &>/dev/null || true docker rm -f $(docker ps -a --no-trunc | egrep "dokku/${APP}:" | awk '{ print $1 }' | xargs) &>/dev/null || true
# shellcheck disable=SC2046 # shellcheck disable=SC2046
docker rmi $(docker images -q "$IMAGE_REPO" | xargs) &>/dev/null || true docker rmi $(docker images -q "$IMAGE_REPO" | xargs) &>/dev/null || true
}
app_post_delete "$@"

View File

@@ -2,9 +2,15 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG"); CACHE_DIR="$DOKKU_ROOT/$APP/cache" apps_pre_delete() {
verify_app_name "$APP" local desc="apps pre-delete plugin trigger"
local trigger="apps_pre_delete"
local APP="$1"; local IMAGE_TAG="$2"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG"); local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
verify_app_name "$APP"
if [[ -d $CACHE_DIR ]]; then if [[ -d $CACHE_DIR ]]; then
docker run "$DOKKU_GLOBAL_RUN_ARGS" --rm -v "$CACHE_DIR:/cache" "$IMAGE" find /cache -depth -mindepth 1 -maxdepth 1 -exec rm -Rf {} \; || true docker run "$DOKKU_GLOBAL_RUN_ARGS" --rm -v "$CACHE_DIR:/cache" "$IMAGE" find /cache -depth -mindepth 1 -maxdepth 1 -exec rm -Rf {} \; || true
fi fi
}
apps_pre_delete "$@"

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/apps/functions"
apps_destroy_cmd() { apps_destroy_cmd() {
local desc="destroys an app" local desc="destroys an app"
@@ -8,35 +9,8 @@ apps_destroy_cmd() {
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on" [[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
[[ "$2" == "tls" ]] && dokku_log_fail "Unable to destroy tls directory" [[ "$2" == "tls" ]] && dokku_log_fail "Unable to destroy tls directory"
[[ "$3" == "force" ]] && export DOKKU_APPS_FORCE_DELETE=1 [[ "$3" == "force" ]] && export DOKKU_APPS_FORCE_DELETE=1
local APP="$2"; local IMAGE_TAG=$(get_running_image_tag "$APP") local APP="$2"
verify_app_name "$APP" apps_destroy "$APP"
if [[ -z "$DOKKU_APPS_FORCE_DELETE" ]]; then
dokku_log_warn "WARNING: Potentially Destructive Action"
dokku_log_warn "This command will destroy $APP (including all add-ons)."
dokku_log_warn "To proceed, type \"$APP\""
echo ""
read -rp "> " app_name
if [[ "$app_name" != "$APP" ]]; then
dokku_log_fail "Confirmation did not match $APP. Aborted."
fi
fi
echo "Destroying $APP (including all add-ons)"
plugn trigger pre-delete "$APP" "$IMAGE_TAG"
local DOKKU_APP_CIDS=$(get_app_container_ids "$APP")
local cid
if [[ -n $DOKKU_APP_CIDS ]]; then
for cid in $DOKKU_APP_CIDS; do
docker stop "$cid" > /dev/null || true
docker rm "$cid" > /dev/null || true
done
fi
plugn trigger post-delete "$APP" "$IMAGE_TAG"
} }
apps_destroy_cmd "$@" apps_destroy_cmd "$@"

View File

@@ -1,6 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/apps/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
apps_rename_cmd() { apps_rename_cmd() {
local desc="renames an app" local desc="renames an app"
@@ -14,11 +16,11 @@ apps_rename_cmd() {
docker run "$DOKKU_GLOBAL_RUN_ARGS" --rm -v "$DOKKU_ROOT/$OLD_APP/cache:/cache" "dokku/$OLD_APP" chmod 777 -R /cache docker run "$DOKKU_GLOBAL_RUN_ARGS" --rm -v "$DOKKU_ROOT/$OLD_APP/cache:/cache" "dokku/$OLD_APP" chmod 777 -R /cache
rm -rf "$DOKKU_ROOT/$OLD_APP/cache" rm -rf "$DOKKU_ROOT/$OLD_APP/cache"
cp -a "$DOKKU_ROOT/$OLD_APP/." "$DOKKU_ROOT/$NEW_APP" cp -a "$DOKKU_ROOT/$OLD_APP/." "$DOKKU_ROOT/$NEW_APP"
dokku apps:destroy "$OLD_APP" --force DOKKU_APPS_FORCE_DELETE=1 apps_destroy "$OLD_APP"
sed -i -e "s/$OLD_APP/$NEW_APP/g" "$DOKKU_ROOT/$NEW_APP/URLS" sed -i -e "s/$OLD_APP/$NEW_APP/g" "$DOKKU_ROOT/$NEW_APP/URLS"
sed -i -e "s/$OLD_APP/$NEW_APP/g" "$DOKKU_ROOT/$NEW_APP/VHOST" sed -i -e "s/$OLD_APP/$NEW_APP/g" "$DOKKU_ROOT/$NEW_APP/VHOST"
sed -i -e "s/git-hook $OLD_APP/git-hook $NEW_APP/g" "$DOKKU_ROOT/$NEW_APP/hooks/pre-receive" sed -i -e "s/git-hook $OLD_APP/git-hook $NEW_APP/g" "$DOKKU_ROOT/$NEW_APP/hooks/pre-receive"
dokku ps:rebuild "$NEW_APP" ps_rebuild "$NEW_APP"
plugn trigger post-app-rename "$OLD_APP" "$NEW_APP" plugn trigger post-app-rename "$OLD_APP" "$NEW_APP"
echo "Renaming $OLD_APP to $NEW_APP... done" echo "Renaming $OLD_APP to $NEW_APP... done"
} }

View File

@@ -3,33 +3,39 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions"
APP="$1"; IMAGE=$(get_app_image_name "$APP"); BUILD_ENV="" build_env_pre_build_buildpack() {
verify_app_name "$APP" local desc="build-env pre-build-buildpack plugin trigger"
local trigger="build_env_pre_build_buildpack"
local APP="$1"; local IMAGE=$(get_app_image_name "$APP"); local BUILD_ENV=""
verify_app_name "$APP"
[[ -z $(config_get --global CURL_CONNECT_TIMEOUT) ]] && config_set --global CURL_CONNECT_TIMEOUT=5 [[ -z $(config_get --global CURL_CONNECT_TIMEOUT) ]] && config_set --global CURL_CONNECT_TIMEOUT=5
[[ -z $(config_get --global CURL_TIMEOUT) ]] && config_set --global CURL_TIMEOUT=30 [[ -z $(config_get --global CURL_TIMEOUT) ]] && config_set --global CURL_TIMEOUT=30
if [[ -n $(config_export global) ]]; then if [[ -n $(config_export global) ]]; then
BUILD_ENV+=$'\n' local BUILD_ENV+=$'\n'
BUILD_ENV+=$(config_export global) local BUILD_ENV+=$(config_export global)
BUILD_ENV+=$'\n' local BUILD_ENV+=$'\n'
fi fi
if [[ -n $(config_export app "$APP") ]]; then if [[ -n $(config_export app "$APP") ]]; then
BUILD_ENV+=$'\n' local BUILD_ENV+=$'\n'
BUILD_ENV+=$(config_export app "$APP") local BUILD_ENV+=$(config_export app "$APP")
BUILD_ENV+=$'\n' local BUILD_ENV+=$'\n'
fi fi
if [[ ! -z "$BUILD_ENV" ]]; then if [[ ! -z "$BUILD_ENV" ]]; then
dokku_log_info1 "Adding BUILD_ENV to build environment..." dokku_log_info1 "Adding BUILD_ENV to build environment..."
# create build env files for use in buildpacks like this: # create build env files for use in buildpacks like this:
# https://github.com/niteoweb/heroku-buildpack-buildout/blob/5879fa3418f7d8e079f1aa5816ba1adde73f4948/bin/compile#L34 # https://github.com/niteoweb/heroku-buildpack-buildout/blob/5879fa3418f7d8e079f1aa5816ba1adde73f4948/bin/compile#L34
id=$(echo $BUILD_ENV |sed -e 's@export @@g' -e 's@\\n@ @g' | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "for ENV_VAR in $(cat); do echo \$ENV_VAR |sed 's@^\([^=]*\)=\(.*\)\$@echo \\\"\2\\\" >/tmp/env/\1@g' >>/tmp/set_env.sh; done && mkdir -p /tmp/env && /bin/bash /tmp/set_env.sh") local id=$(echo $BUILD_ENV |sed -e 's@export @@g' -e 's@\\n@ @g' | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "for ENV_VAR in $(cat); do echo \$ENV_VAR |sed 's@^\([^=]*\)=\(.*\)\$@echo \\\"\2\\\" >/tmp/env/\1@g' >>/tmp/set_env.sh; done && mkdir -p /tmp/env && /bin/bash /tmp/set_env.sh")
test "$(docker wait "$id")" -eq 0 test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null docker commit "$id" "$IMAGE" > /dev/null
# create build env for 'old style' buildpacks and dokku plugins # create build env for 'old style' buildpacks and dokku plugins
id=$(echo -e "$BUILD_ENV" | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "cat >> /app/.env") local id=$(echo -e "$BUILD_ENV" | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "cat >> /app/.env")
test "$(docker wait "$id")" -eq 0 test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null docker commit "$id" "$IMAGE" > /dev/null
fi fi
}
build_env_pre_build_buildpack "$@"

View File

@@ -5,7 +5,7 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
is_ssl_enabled() { is_ssl_enabled() {
local desc="returns 0 if ssl is enabled for given app" local desc="returns 0 if ssl is enabled for given app"
local APP=$1; verify_app_name "$APP" local APP=$1; verify_app_name "$APP"
APP_SSL_PATH="$DOKKU_ROOT/$APP/tls" local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
if [[ -e "$APP_SSL_PATH/server.crt" ]] && [[ -e "$APP_SSL_PATH/server.key" ]]; then if [[ -e "$APP_SSL_PATH/server.crt" ]] && [[ -e "$APP_SSL_PATH/server.key" ]]; then
return 0 return 0

View File

@@ -23,11 +23,11 @@ certs_info_cmd() {
dokku_log_info2 "Issuer: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Issuer:" | xargs | sed -e "s/Issuer: //g")" dokku_log_info2 "Issuer: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Issuer:" | xargs | sed -e "s/Issuer: //g")"
dokku_log_info2 "Starts At: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Not Before:" | awk -F ": " '{ print $2 }')" dokku_log_info2 "Starts At: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Not Before:" | awk -F ": " '{ print $2 }')"
dokku_log_info2 "Subject: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -subject | sed -e "s:subject= ::g"| sed -e "s:^/::g" | sed -e "s:/:; :g")" dokku_log_info2 "Subject: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -subject | sed -e "s:subject= ::g"| sed -e "s:^/::g" | sed -e "s:/:; :g")"
SSL_VERIFY_OUTPUT="$(openssl verify -verbose -purpose sslserver "$APP_SSL_PATH/server.crt" | awk -F ':' '{ print $2 }' | tail -1 | xargs || true)" local SSL_VERIFY_OUTPUT="$(openssl verify -verbose -purpose sslserver "$APP_SSL_PATH/server.crt" | awk -F ':' '{ print $2 }' | tail -1 | xargs || true)"
if [[ "$SSL_VERIFY_OUTPUT" == "OK" ]]; then if [[ "$SSL_VERIFY_OUTPUT" == "OK" ]]; then
SSL_SELF_SIGNED="verified by a certificate authority." local SSL_SELF_SIGNED="verified by a certificate authority."
else else
SSL_SELF_SIGNED="self signed." local SSL_SELF_SIGNED="self signed."
fi fi
dokku_log_info2 "SSL certificate is $SSL_SELF_SIGNED" dokku_log_info2 "SSL certificate is $SSL_SELF_SIGNED"
else else

View File

@@ -33,189 +33,198 @@
# TIMEOUT=60 # Timeout after a minute # TIMEOUT=60 # Timeout after a minute
# ATTEMPTS=10 # retry checks 10 times # ATTEMPTS=10 # retry checks 10 times
# #
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions" source "$PLUGIN_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions"
APP="$1"; DOKKU_APP_CONTAINER_ID="$2"; DOKKU_APP_CONTAINER_TYPE="$3"; DOKKU_APP_LISTEN_PORT="$4"; DOKKU_APP_LISTEN_IP="$5" checks_check_deploy() {
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then local desc="checks check-deploy plugin trigger"
DOKKU_APP_LISTEN_PORT=$(< "$DOKKU_ROOT/$APP/PORT") local trigger="checks_check_deploy"
fi local APP="$1"; local DOKKU_APP_CONTAINER_ID="$2"; local DOKKU_APP_CONTAINER_TYPE="$3"; local DOKKU_APP_LISTEN_PORT="$4"; local DOKKU_APP_LISTEN_IP="$5"
if [[ -z "$DOKKU_APP_LISTEN_IP" ]] && [[ -f "$DOKKU_ROOT/$APP/IP" ]]; then if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then
DOKKU_APP_LISTEN_IP=$(< "$DOKKU_ROOT/$APP/IP") local DOKKU_APP_LISTEN_PORT=$(< "$DOKKU_ROOT/$APP/PORT")
fi fi
if [[ -z "$DOKKU_APP_CONTAINER_ID" ]]; then if [[ -z "$DOKKU_APP_LISTEN_IP" ]] && [[ -f "$DOKKU_ROOT/$APP/IP" ]]; then
DOKKU_APP_CIDS=( $(get_app_container_ids "$APP") ) local DOKKU_APP_LISTEN_IP=$(< "$DOKKU_ROOT/$APP/IP")
DOKKU_APP_CONTAINER_ID=${DOKKU_APP_CIDS[0]} fi
fi if [[ -z "$DOKKU_APP_CONTAINER_ID" ]]; then
local DOKKU_APP_CIDS=( $(get_app_container_ids "$APP") )
local DOKKU_APP_CONTAINER_ID=${DOKKU_APP_CIDS[0]}
# source global and in-app envs to get DOKKU_CHECKS_WAIT and any other necessary vars
eval "$(config_export global)"
eval "$(config_export app "$APP")"
if [[ "$(is_app_checks_enabled "$APP")" == "false" ]];then
dokku_log_info2_quiet "Zero downtime checks for app ($APP) have been disabled. moving on..."
exit 0
fi
# Wait this many seconds (default 5) for server to start before running checks.
WAIT="${DOKKU_CHECKS_WAIT:-5}"
# Wait this many seconds (default 30) for each response.
TIMEOUT="${DOKKU_CHECKS_TIMEOUT:-30}"
# use this number of retries for checks
ATTEMPTS="${DOKKU_CHECKS_ATTEMPTS:-5}"
# try to copy CHECKS from container if not in APP dir & quit gracefully if it doesn't exist
# docker cp exits with status 1 when run as non-root user when it tries to chown the file
# after successfully copying the file. Thus, we suppress stderr.
# ref: https://github.com/dotcloud/docker/issues/3986
TMPDIR=$(mktemp -d /tmp/dokku_CHECKS.XXXXX)
docker cp $DOKKU_APP_CONTAINER_ID:/app/CHECKS "$TMPDIR" 2> /dev/null || true
FILENAME=${TMPDIR}/CHECKS
cleanup() {
local desc="cleans up TMPDIR and print container output"
rm -rf "$TMPDIR"
dokku_log_info2_quiet "$APP container output:"
dokku_container_log_verbose_quiet $DOKKU_APP_CONTAINER_ID
dokku_log_info2_quiet "end $APP container output"
}
trap cleanup EXIT
if [[ ! -s "${TMPDIR}/CHECKS" ]] || [[ "$DOKKU_APP_CONTAINER_TYPE" != "web" ]]; then
# We allow custom check for web instances only
if [[ "$DOKKU_APP_CONTAINER_TYPE" == "web" ]]; then
dokku_log_verbose "For more efficient zero downtime deployments, create a file CHECKS."
dokku_log_verbose "See http://dokku.viewdocs.io/dokku/checks-examples.md for examples"
dokku_log_verbose "CHECKS file not found in container: Running simple container check..."
else
dokku_log_verbose "Non web container detected: Running default container check..."
fi fi
rm -rf "$TMPDIR"
# simple default check to see if the container stuck around # source global and in-app envs to get DOKKU_CHECKS_WAIT and any other necessary vars
DOKKU_DEFAULT_CHECKS_WAIT="${DOKKU_DEFAULT_CHECKS_WAIT:-10}" eval "$(config_export global)"
dokku_log_info1 "Waiting for $DOKKU_DEFAULT_CHECKS_WAIT seconds ..." eval "$(config_export app "$APP")"
sleep "$DOKKU_DEFAULT_CHECKS_WAIT"
! (is_container_running $DOKKU_APP_CONTAINER_ID) && dokku_log_fail "App container failed to start!!" if [[ "$(is_app_checks_enabled "$APP")" == "false" ]];then
container_restarts=$(docker inspect -f "{{ .RestartCount }}" $DOKKU_APP_CONTAINER_ID) dokku_log_info2_quiet "Zero downtime checks for app ($APP) have been disabled. moving on..."
if [[ $container_restarts -ne 0 ]]; then exit 0
docker stop "$DOKKU_APP_CONTAINER_ID" || true
dokku_log_fail "App container failed to start!!"
fi fi
dokku_log_info1 "Default container check successful!" && exit 0 # Wait this many seconds (default 5) for server to start before running checks.
fi local WAIT="${DOKKU_CHECKS_WAIT:-5}"
# Wait this many seconds (default 30) for each response.
local TIMEOUT="${DOKKU_CHECKS_TIMEOUT:-30}"
# use this number of retries for checks
local ATTEMPTS="${DOKKU_CHECKS_ATTEMPTS:-5}"
# Reads name/value pairs, sets the WAIT and TIMEOUT variables # try to copy CHECKS from container if not in APP dir & quit gracefully if it doesn't exist
exec < "$FILENAME" # docker cp exits with status 1 when run as non-root user when it tries to chown the file
while read -r LINE; do # after successfully copying the file. Thus, we suppress stderr.
# Name/value pair # ref: https://github.com/dotcloud/docker/issues/3986
if [[ "$LINE" =~ ^.+= ]]; then local TMPDIR=$(mktemp -d /tmp/dokku_CHECKS.XXXXX)
TRIM=${LINE%#*} docker cp $DOKKU_APP_CONTAINER_ID:/app/CHECKS "$TMPDIR" 2> /dev/null || true
NAME=${TRIM%=*}
VALUE=${TRIM#*=}
[[ "$NAME" = "WAIT" ]] && WAIT=$VALUE
[[ "$NAME" = "TIMEOUT" ]] && TIMEOUT=$VALUE
[[ "$NAME" = "ATTEMPTS" ]] && ATTEMPTS=$VALUE
fi
done
ATTEMPT=0 local FILENAME=${TMPDIR}/CHECKS
until [[ $SUCCESS == 1 || $ATTEMPT -ge $ATTEMPTS ]] cleanup() {
do local desc="cleans up TMPDIR and print container output"
FAILEDCHECKS=0 local id="$1"
ATTEMPT=$(( ATTEMPT + 1 )) rm -rf "$TMPDIR"
dokku_log_info1 "Attempt $ATTEMPT/$ATTEMPTS Waiting for $WAIT seconds ..." dokku_log_info2_quiet "$APP container output:"
sleep "$WAIT" dokku_container_log_verbose_quiet "$id"
dokku_log_info2_quiet "end $APP container output"
}
trap 'cleanup $DOKKU_APP_CONTAINER_ID' RETURN INT TERM EXIT
if [[ ! -s "${TMPDIR}/CHECKS" ]] || [[ "$DOKKU_APP_CONTAINER_TYPE" != "web" ]]; then
# We allow custom check for web instances only
if [[ "$DOKKU_APP_CONTAINER_TYPE" == "web" ]]; then
dokku_log_verbose "For more efficient zero downtime deployments, create a file CHECKS."
dokku_log_verbose "See http://dokku.viewdocs.io/dokku/checks-examples.md for examples"
dokku_log_verbose "CHECKS file not found in container: Running simple container check..."
else
dokku_log_verbose "Non web container detected: Running default container check..."
fi
# -q do not use .curlrc (must come first) rm -rf "$TMPDIR"
# --compressed Test compression handled correctly
# --fail Fail on server errors (4xx, 5xx)
# --location Follow redirects
CURL_OPTIONS="-q --compressed --fail --location --max-time $TIMEOUT"
# Set X-Forwarded-Proto header if TLS is enabled. # simple default check to see if the container stuck around
SSL="$DOKKU_ROOT/$APP/tls"; WILDCARD_SSL="$DOKKU_ROOT/tls" local DOKKU_DEFAULT_CHECKS_WAIT="${DOKKU_DEFAULT_CHECKS_WAIT:-10}"
if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]] || [[ -e "$WILDCARD_SSL/server.crt" && -e "$WILDCARD_SSL/server.key" ]]; then dokku_log_info1 "Waiting for $DOKKU_DEFAULT_CHECKS_WAIT seconds ..."
CURL_OPTIONS+=" -H X-Forwarded-Proto:https" sleep "$DOKKU_DEFAULT_CHECKS_WAIT"
! (is_container_running $DOKKU_APP_CONTAINER_ID) && dokku_log_fail "App container failed to start!!"
local container_restarts=$(docker inspect -f "{{ .RestartCount }}" $DOKKU_APP_CONTAINER_ID)
if [[ $container_restarts -ne 0 ]]; then
docker stop "$DOKKU_APP_CONTAINER_ID" || true
dokku_log_fail "App container failed to start!!"
fi
dokku_log_info1 "Default container check successful!" && exit 0
fi fi
# Reads name/value pairs, sets the WAIT and TIMEOUT variables
exec < "$FILENAME" exec < "$FILENAME"
while read -r CHECK_URL EXPECTED; do local LINE
# Ignore empty lines and lines starting with # while read -r LINE; do
# shellcheck disable=SC1001 # Name/value pair
[[ -z "$CHECK_URL" || "$CHECK_URL" =~ ^\# ]] && continue if [[ "$LINE" =~ ^.+= ]]; then
# Ignore if it's not a URL in a supported format local TRIM=${LINE%#*}
# shellcheck disable=SC1001 local NAME=${TRIM%=*}
! [[ "$CHECK_URL" =~ ^(http(s)?:)?\/.* ]] && continue local VALUE=${TRIM#*=}
[[ "$NAME" = "WAIT" ]] && local WAIT=$VALUE
[[ "$NAME" = "TIMEOUT" ]] && local TIMEOUT=$VALUE
[[ "$NAME" = "ATTEMPTS" ]] && local ATTEMPTS=$VALUE
fi
done
if [[ "$CHECK_URL" =~ ^https?: ]]; then local ATTEMPT=0
URL_PROTOCOL=${CHECK_URL%:*}
CHECK_URL=${CHECK_URL#*:} until [[ $SUCCESS == 1 || $ATTEMPT -ge $ATTEMPTS ]]
else do
URL_PROTOCOL="http" local FAILEDCHECKS=0
local ATTEMPT=$(( ATTEMPT + 1 ))
dokku_log_info1 "Attempt $ATTEMPT/$ATTEMPTS Waiting for $WAIT seconds ..."
sleep "$WAIT"
# -q do not use .curlrc (must come first)
# --compressed Test compression handled correctly
# --fail Fail on server errors (4xx, 5xx)
# --location Follow redirects
local CURL_OPTIONS="-q --compressed --fail --location --max-time $TIMEOUT"
# Set X-Forwarded-Proto header if TLS is enabled.
local SSL="$DOKKU_ROOT/$APP/tls"; local WILDCARD_SSL="$DOKKU_ROOT/tls"
if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]] || [[ -e "$WILDCARD_SSL/server.crt" && -e "$WILDCARD_SSL/server.key" ]]; then
local CURL_OPTIONS+=" -H X-Forwarded-Proto:https"
fi fi
if [[ "$CHECK_URL" =~ ^//.+ ]]; then exec < "$FILENAME"
# To test a URL with specific host name, we still make request to localhost, local CHECK_URL
# but we set Host header to $SEND_HOST. local EXPECTED
# while read -r CHECK_URL EXPECTED; do
# The pattern is # Ignore empty lines and lines starting with #
# //SEND_HOST/PATHNAME # shellcheck disable=SC1001
UNPREFIXED=${CHECK_URL#//} [[ -z "$CHECK_URL" || "$CHECK_URL" =~ ^\# ]] && continue
URL_HOSTNAME=${UNPREFIXED%%/*} # Ignore if it's not a URL in a supported format
URL_PATHNAME=${UNPREFIXED#$URL_HOSTNAME} # shellcheck disable=SC1001
! [[ "$CHECK_URL" =~ ^(http(s)?:)?\/.* ]] && continue
HEADERS="-H Host:$URL_HOSTNAME" if [[ "$CHECK_URL" =~ ^https?: ]]; then
else local URL_PROTOCOL=${CHECK_URL%:*}
URL_HOSTNAME=localhost local CHECK_URL=${CHECK_URL#*:}
URL_PATHNAME=$CHECK_URL else
fi local URL_PROTOCOL="http"
# This URL will show up in the messages
LOG_URL="$URL_PROTOCOL://$URL_HOSTNAME$URL_PATHNAME"
# And how we formulate the CURL request
CURL_ARGS="$CURL_OPTIONS $URL_PROTOCOL://$DOKKU_APP_LISTEN_IP:$DOKKU_APP_LISTEN_PORT$URL_PATHNAME $HEADERS"
dokku_log_verbose "CHECKS expected result:"
dokku_log_verbose "$LOG_URL => \"$EXPECTED\""
[[ $DOKKU_TRACE ]] && dokku_log_verbose "$ curl $CURL_ARGS"
# Capture HTTP response or CURL error message
# shellcheck disable=SC2086
if OUTPUT=$(curl -# $CURL_ARGS 2>&1); then
# OUTPUT contains the HTTP response
if [[ ! "$OUTPUT" =~ $EXPECTED ]]; then
dokku_log_warn "$LOG_URL: expected to but did not find: \"$EXPECTED\""
FAILEDCHECKS=$(( FAILEDCHECKS + 1 ))
fi fi
if [[ "$CHECK_URL" =~ ^//.+ ]]; then
# To test a URL with specific host name, we still make request to localhost,
# but we set Host header to $SEND_HOST.
#
# The pattern is
# //SEND_HOST/PATHNAME
local UNPREFIXED=${CHECK_URL#//}
local URL_HOSTNAME=${UNPREFIXED%%/*}
local URL_PATHNAME=${UNPREFIXED#$URL_HOSTNAME}
local HEADERS="-H Host:$URL_HOSTNAME"
else
local URL_HOSTNAME=localhost
local URL_PATHNAME=$CHECK_URL
fi
# This URL will show up in the messages
local LOG_URL="$URL_PROTOCOL://$URL_HOSTNAME$URL_PATHNAME"
# And how we formulate the CURL request
local CURL_ARGS="$CURL_OPTIONS $URL_PROTOCOL://$DOKKU_APP_LISTEN_IP:$DOKKU_APP_LISTEN_PORT$URL_PATHNAME $HEADERS"
dokku_log_verbose "CHECKS expected result:"
dokku_log_verbose "$LOG_URL => \"$EXPECTED\""
[[ $DOKKU_TRACE ]] && dokku_log_verbose "$ curl $CURL_ARGS"
# Capture HTTP response or CURL error message
# shellcheck disable=SC2086
if OUTPUT=$(curl -# $CURL_ARGS 2>&1); then
# OUTPUT contains the HTTP response
if [[ ! "$OUTPUT" =~ $EXPECTED ]]; then
dokku_log_warn "$LOG_URL: expected to but did not find: \"$EXPECTED\""
local FAILEDCHECKS=$(( FAILEDCHECKS + 1 ))
fi
else
# Failed to connect/no response, OUTPUT contains error message
dokku_log_warn "$OUTPUT"
local FAILEDCHECKS=$(( FAILEDCHECKS + 1 ))
fi
done
if [[ $FAILEDCHECKS -gt 0 ]]; then
dokku_log_warn "Check attempt $ATTEMPT/$ATTEMPTS failed."
local SUCCESS=0
else else
# Failed to connect/no response, OUTPUT contains error message local SUCCESS=1
dokku_log_warn "$OUTPUT"
FAILEDCHECKS=$(( FAILEDCHECKS + 1 ))
fi fi
done done
if [[ $FAILEDCHECKS -gt 0 ]]; then if [[ $FAILEDCHECKS -gt 0 ]]; then
dokku_log_warn "Check attempt $ATTEMPT/$ATTEMPTS failed." dokku_log_fail "Could not start due to $FAILEDCHECKS failed checks."
SUCCESS=0 exit 1
else
SUCCESS=1
fi fi
done
if [[ $FAILEDCHECKS -gt 0 ]]; then dokku_log_info1 "All checks successful!"
dokku_log_fail "Could not start due to $FAILEDCHECKS failed checks." }
exit 1
fi
dokku_log_info1 "All checks successful!" checks_check_deploy "$@"

View File

@@ -118,9 +118,8 @@ dokku_log_event() {
dokku_log_plugn_trigger_call() { dokku_log_plugn_trigger_call() {
local desc="log plugn trigger calls" local desc="log plugn trigger calls"
local l_hook
l_hook="$1" ; shift local l_hook="$1" ; shift
dokku_log_event "INVOKED: ${l_hook}( $* ) NAME=$NAME FINGERPRINT=$FINGERPRINT" dokku_log_event "INVOKED: ${l_hook}( $* ) NAME=$NAME FINGERPRINT=$FINGERPRINT"
} }
@@ -131,6 +130,7 @@ dokku_container_log_verbose_quiet() {
OIFS=$IFS OIFS=$IFS
IFS=$'\n' IFS=$'\n'
local line
for line in $(docker logs "$CID" 2>&1); do for line in $(docker logs "$CID" 2>&1); do
dokku_log_verbose_quiet "$line" dokku_log_verbose_quiet "$line"
done done
@@ -173,10 +173,10 @@ get_app_image_name() {
[[ -z "$APP" ]] && dokku_log_fail "(get_app_image_name) APP must not be null" [[ -z "$APP" ]] && dokku_log_fail "(get_app_image_name) APP must not be null"
if [[ -n "$IMAGE_TAG" ]]; then if [[ -n "$IMAGE_TAG" ]]; then
IMAGE="$IMAGE_REPO:$IMAGE_TAG" local IMAGE="$IMAGE_REPO:$IMAGE_TAG"
verify_image "$IMAGE" || dokku_log_fail "app image ($IMAGE) not found" verify_image "$IMAGE" || dokku_log_fail "app image ($IMAGE) not found"
else else
IMAGE="$IMAGE_REPO:latest" local IMAGE="$IMAGE_REPO:latest"
fi fi
echo "$IMAGE" echo "$IMAGE"
} }
@@ -187,8 +187,8 @@ get_running_image_tag() {
[[ ! -n "$APP" ]] && dokku_log_fail "(get_running_image_tag) APP must not be null" [[ ! -n "$APP" ]] && dokku_log_fail "(get_running_image_tag) APP must not be null"
verify_app_name "$APP" verify_app_name "$APP"
CIDS=( $(get_app_container_ids "$APP") ) local CIDS=( $(get_app_container_ids "$APP") )
RUNNING_IMAGE_TAG=$(docker inspect -f '{{ .Config.Image }}' ${CIDS[0]} 2>/dev/null | awk -F: '{ print $2 }' || echo '') local RUNNING_IMAGE_TAG=$(docker inspect -f '{{ .Config.Image }}' ${CIDS[0]} 2>/dev/null | awk -F: '{ print $2 }' || echo '')
echo "$RUNNING_IMAGE_TAG" echo "$RUNNING_IMAGE_TAG"
} }
@@ -212,7 +212,7 @@ is_number() {
is_abs_path() { is_abs_path() {
local desc="returns 0 if input path is absolute" local desc="returns 0 if input path is absolute"
local TEST_PATH=$1 local TEST_PATH=$1
if [[ "$TEST_PATH" = /* ]]; then if [[ "$TEST_PATH" == /* ]]; then
return 0 return 0
else else
return 1 return 1
@@ -241,7 +241,7 @@ parse_args() {
export DOKKU_APP_NAME=${args[$next_index]}; skip=true export DOKKU_APP_NAME=${args[$next_index]}; skip=true
;; ;;
esac esac
next_index=$(( next_index + 1 )) local next_index=$(( next_index + 1 ))
done done
return 0 return 0
} }
@@ -254,10 +254,10 @@ copy_from_image() {
if verify_image "$IMAGE"; then if verify_image "$IMAGE"; then
if ! is_abs_path "$SRC_FILE"; then if ! is_abs_path "$SRC_FILE"; then
local WORKDIR=$(docker inspect -f '{{.Config.WorkingDir}}' "$IMAGE") local WORKDIR=$(docker inspect -f '{{.Config.WorkingDir}}' "$IMAGE")
[[ -z "$WORKDIR" ]] && WORKDIR=/app [[ -z "$WORKDIR" ]] && local WORKDIR=/app
SRC_FILE="$WORKDIR/$SRC_FILE" local SRC_FILE="$WORKDIR/$SRC_FILE"
fi fi
CID=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" -d "$IMAGE" bash) local CID=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" -d "$IMAGE" bash)
docker cp "$CID:$SRC_FILE" "$DST_DIR" docker cp "$CID:$SRC_FILE" "$DST_DIR"
docker rm -f "$CID" &> /dev/null docker rm -f "$CID" &> /dev/null
else else
@@ -272,20 +272,21 @@ get_app_container_ids() {
[[ -f $DOKKU_ROOT/$APP/CONTAINER ]] && DOKKU_CIDS+=$(< "$DOKKU_ROOT/$APP/CONTAINER") [[ -f $DOKKU_ROOT/$APP/CONTAINER ]] && DOKKU_CIDS+=$(< "$DOKKU_ROOT/$APP/CONTAINER")
if [[ -n "$CONTAINER_TYPE" ]]; then if [[ -n "$CONTAINER_TYPE" ]]; then
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE.*" local CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE.*"
if [[ $CONTAINER_TYPE == *.* ]]; then if [[ $CONTAINER_TYPE == *.* ]]; then
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE" local CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE"
[[ ! -f $CONTAINER_PATTERN ]] && echo "" && return 0 [[ ! -f $CONTAINER_PATTERN ]] && echo "" && return 0
fi fi
else else
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.*" local CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.*"
fi fi
shopt -s nullglob shopt -s nullglob
local DOKKU_CID_FILE
for DOKKU_CID_FILE in $CONTAINER_PATTERN; do for DOKKU_CID_FILE in $CONTAINER_PATTERN; do
DOKKU_CIDS+=" " local DOKKU_CIDS+=" "
DOKKU_CIDS+=$(< "$DOKKU_CID_FILE") local DOKKU_CIDS+=$(< "$DOKKU_CID_FILE")
DOKKU_CIDS+=" " local DOKKU_CIDS+=" "
done done
shopt -u nullglob shopt -u nullglob
echo "$DOKKU_CIDS" echo "$DOKKU_CIDS"
@@ -318,8 +319,8 @@ get_cmd_from_procfile() {
if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then
continue continue
fi fi
name="${line%%:*}" local name="${line%%:*}"
command="${line#*:[[:space:]]}" local command="${line#*:[[:space:]]}"
[[ "$name" == "$PROC_TYPE" ]] && echo "$command" && break [[ "$name" == "$PROC_TYPE" ]] && echo "$command" && break
done < "$DOKKU_PROCFILE" done < "$DOKKU_PROCFILE"
fi fi
@@ -376,6 +377,8 @@ is_app_running() {
release_and_deploy() { release_and_deploy() {
local desc="main function for releasing and deploying an app" local desc="main function for releasing and deploying an app"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
local APP="$1"; local IMAGE_TAG="$2"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG") local APP="$1"; local IMAGE_TAG="$2"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP" verify_app_name "$APP"
@@ -386,8 +389,8 @@ release_and_deploy() {
local IMAGE_SOURCE_TYPE="dockerfile" local IMAGE_SOURCE_TYPE="dockerfile"
fi fi
local DOKKU_APP_SKIP_DEPLOY="$(dokku config:get "$APP" DOKKU_SKIP_DEPLOY || true)" local DOKKU_APP_SKIP_DEPLOY="$(config_get "$APP" DOKKU_SKIP_DEPLOY || true)"
local DOKKU_GLOBAL_SKIP_DEPLOY="$(dokku config:get --global DOKKU_SKIP_DEPLOY || true)" local DOKKU_GLOBAL_SKIP_DEPLOY="$(config_get --global DOKKU_SKIP_DEPLOY || true)"
local DOKKU_SKIP_DEPLOY=${DOKKU_APP_SKIP_DEPLOY:="$DOKKU_GLOBAL_SKIP_DEPLOY"} local DOKKU_SKIP_DEPLOY=${DOKKU_APP_SKIP_DEPLOY:="$DOKKU_GLOBAL_SKIP_DEPLOY"}
@@ -398,7 +401,7 @@ release_and_deploy() {
dokku_log_info1 "Deploying $APP ($IMAGE)..." dokku_log_info1 "Deploying $APP ($IMAGE)..."
dokku deploy "$APP" "$IMAGE_TAG" dokku deploy "$APP" "$IMAGE_TAG"
dokku_log_info2 "Application deployed:" dokku_log_info2 "Application deployed:"
dokku urls "$APP" | sed "s/^/ /" get_app_urls urls "$APP" | sed "s/^/ /"
else else
dokku_log_info1 "Skipping deployment" dokku_log_info1 "Skipping deployment"
fi fi
@@ -453,18 +456,18 @@ _ipv4_regex() {
_ipv6_regex() { _ipv6_regex() {
local desc="ipv6 regex" local desc="ipv6 regex"
local RE_IPV4="$(_ipv4_regex)" local RE_IPV4="$(_ipv4_regex)"
local RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" # TEST: 1:2:3:4:5:6:7:8 local RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" # TEST: 1:2:3:4:5:6:7:8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|" # TEST: 1:: 1:2:3:4:5:6:7:: local RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|" # TEST: 1:: 1:2:3:4:5:6:7::
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" # TEST: 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8 local RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" # TEST: 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" # TEST: 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8 local RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" # TEST: 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" # TEST: 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8 local RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" # TEST: 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" # TEST: 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8 local RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" # TEST: 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" # TEST: 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8 local RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" # TEST: 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" # TEST: 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8 local RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" # TEST: 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 :: local RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|" # TEST: fe08::7:8%eth0 fe08::7:8%1 (link-local IPv6 addresses with zone index) local RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|" # TEST: fe08::7:8%eth0 fe08::7:8%1 (link-local IPv6 addresses with zone index)
RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|" # TEST: ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses) local RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|" # TEST: ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}" # TEST: 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33 local RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}" # TEST: 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33
echo "$RE_IPV6" echo "$RE_IPV6"
} }

View File

@@ -3,16 +3,22 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions" source "$PLUGIN_AVAILABLE_PATH/config/functions"
STDIN=$(cat); APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG") config_docker_args() {
DOCKERFILE_ENV_FILE="$DOKKU_ROOT/$APP/DOCKERFILE_ENV_FILE" local desc="config docker-args plugin trigger"
verify_app_name "$APP" local trigger="$0 config_docker_args"
local STDIN=$(cat); local APP="$1"; local IMAGE_TAG="$2"; local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
local DOCKERFILE_ENV_FILE="$DOKKU_ROOT/$APP/DOCKERFILE_ENV_FILE"
verify_app_name "$APP"
if ! is_image_herokuish_based "$IMAGE"; then if ! is_image_herokuish_based "$IMAGE"; then
> "$DOCKERFILE_ENV_FILE" > "$DOCKERFILE_ENV_FILE"
config_export global | sed -e "s:^export ::g" -e "s:=':=:g" -e "s:'$::g" > "$DOCKERFILE_ENV_FILE" config_export global | sed -e "s:^export ::g" -e "s:=':=:g" -e "s:'$::g" > "$DOCKERFILE_ENV_FILE"
config_export app "$APP" | sed -e "s:^export ::g" -e "s:=':=:g" -e "s:'$::g" >> "$DOCKERFILE_ENV_FILE" config_export app "$APP" | sed -e "s:^export ::g" -e "s:=':=:g" -e "s:'$::g" >> "$DOCKERFILE_ENV_FILE"
echo "$STDIN --env-file=$DOCKERFILE_ENV_FILE" echo "$STDIN --env-file=$DOCKERFILE_ENV_FILE"
else else
echo "$STDIN" echo "$STDIN"
fi fi
}
config_docker_args "$@"

View File

@@ -1,71 +1,78 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
STDIN=$(cat) docker_args() {
APP="$1"; IMAGE_SOURCE_TYPE="$2" local desc="docker args plugin trigger"
local trigger="$0"
local STDIN=$(cat)
local APP="$1"; local IMAGE_SOURCE_TYPE="$2"
case "$0" in case "$0" in
*docker-args-build) *docker-args-build)
PHASE=BUILD local PHASE=BUILD
;; ;;
*docker-args-deploy) *docker-args-deploy)
PHASE=DEPLOY local PHASE=DEPLOY
;; ;;
*docker-args-run) *docker-args-run)
PHASE=RUN local PHASE=RUN
;; ;;
esac esac
FILE_PREFIX="DOCKER_OPTIONS_" local FILE_PREFIX="DOCKER_OPTIONS_"
PHASE_FILE_PATH="${DOKKU_ROOT}/${APP}/${FILE_PREFIX}${PHASE}" local PHASE_FILE_PATH="${DOKKU_ROOT}/${APP}/${FILE_PREFIX}${PHASE}"
output="" local output=""
if [[ -f "$PHASE_FILE_PATH" ]]; then if [[ -f "$PHASE_FILE_PATH" ]]; then
DONE=false local DONE=false
until $DONE; do until $DONE; do
read -r line || DONE=true local line
read -r line || local DONE=true
[[ ! -n "$line" ]] && continue [[ ! -n "$line" ]] && continue
# shellcheck disable=SC1001 # shellcheck disable=SC1001
case "$line" in case "$line" in
\#*) \#*)
continue continue
;; ;;
*) *)
case "$IMAGE_SOURCE_TYPE" in case "$IMAGE_SOURCE_TYPE" in
dockerfile) dockerfile)
case "$line" in case "$line" in
--link*|-v*) --link*|-v*)
continue continue
;; ;;
*) *)
output="$output $line" local output="$output $line"
;; ;;
esac esac
;; ;;
herokuish) herokuish)
case "$line" in case "$line" in
--file*|--build-args*) --file*|--build-args*)
continue continue
;; ;;
*) *)
output="$output $line" local output="$output $line"
;; ;;
esac esac
;; ;;
*) *)
output="$output $line" local output="$output $line"
;; ;;
esac esac
;; ;;
esac esac
done < "$PHASE_FILE_PATH" done < "$PHASE_FILE_PATH"
fi fi
echo "$STDIN$output" echo "$STDIN$output"
}
docker_args "$@"

View File

@@ -49,8 +49,7 @@ display_all_phases_options() {
local desc="print docker-options for all phases" local desc="print docker-options for all phases"
local phases=("${AVAILABLE_PHASES[@]}") local phases=("${AVAILABLE_PHASES[@]}")
for phase in "${phases[@]}"; do for phase in "${phases[@]}"; do
local phase_file_path local phase_file_path="$(get_phase_file_path "$phase")"
phase_file_path="$(get_phase_file_path "$phase")"
if [[ -s "$phase_file_path" ]]; then if [[ -s "$phase_file_path" ]]; then
display_phase_options "$phase" "$phase_file_path" display_phase_options "$phase" "$phase_file_path"
fi fi
@@ -62,8 +61,7 @@ display_passed_phases_options() {
local passed_phases=("${!1}") local passed_phases=("${!1}")
local phase local phase
for phase in "${passed_phases[@]}"; do for phase in "${passed_phases[@]}"; do
local phase_file_path local phase_file_path="$(get_phase_file_path "$phase")"
phase_file_path="$(get_phase_file_path "$phase")"
if [[ ! -s "$phase_file_path" ]]; then if [[ ! -s "$phase_file_path" ]]; then
echo "${phase^} options: none" echo "${phase^} options: none"
else else
@@ -79,11 +77,10 @@ add_passed_docker_option() {
local passed_option_string="$*" local passed_option_string="$*"
local phase local phase
for phase in "${passed_phases[@]}"; do for phase in "${passed_phases[@]}"; do
local phase_file_path local phase_file_path="$(get_phase_file_path "$phase")"
phase_file_path="$(get_phase_file_path "$phase")"
create_phase_file_if_required "$phase_file_path" create_phase_file_if_required "$phase_file_path"
echo "${passed_option_string}" >> "$phase_file_path" echo "${passed_option_string}" >> "$phase_file_path"
all_phase_options="$(< "$phase_file_path")" local all_phase_options="$(< "$phase_file_path")"
echo -e "${all_phase_options}" | sed '/^$/d' | sort -u > "$phase_file_path" echo -e "${all_phase_options}" | sed '/^$/d' | sort -u > "$phase_file_path"
done done
} }
@@ -95,11 +92,10 @@ remove_passed_docker_option() {
local passed_option_string="$*" local passed_option_string="$*"
local phase local phase
for phase in "${passed_phases[@]}"; do for phase in "${passed_phases[@]}"; do
local phase_file_path local phase_file_path="$(get_phase_file_path "$phase")"
phase_file_path="$(get_phase_file_path "$phase")"
[[ ! -s "$phase_file_path" ]] || { [[ ! -s "$phase_file_path" ]] || {
all_phase_options="$(< "$phase_file_path")" local all_phase_options="$(< "$phase_file_path")"
all_phase_options=$(echo -e "${all_phase_options}" | sed "s#^${passed_option_string}\$##") local all_phase_options=$(echo -e "${all_phase_options}" | sed "s#^${passed_option_string}\$##")
echo -e "${all_phase_options}" | sed '/^$/d' | sort -u > "$phase_file_path" echo -e "${all_phase_options}" | sed '/^$/d' | sort -u > "$phase_file_path"
} }
done done

View File

@@ -10,7 +10,7 @@ docker_options_add_cmd() {
verify_app_name "$2" && local APP="$2" verify_app_name "$2" && local APP="$2"
read -ra passed_phases <<< "$(get_phases "$3")" read -ra passed_phases <<< "$(get_phases "$3")"
shift 3 # everything else passed is the docker option shift 3 # everything else passed is the docker option
passed_docker_option="$*" local passed_docker_option="$*"
[[ -z "$passed_docker_option" ]] && dokku_log_fail "Please specify docker options to add to the phase" [[ -z "$passed_docker_option" ]] && dokku_log_fail "Please specify docker options to add to the phase"
add_passed_docker_option passed_phases[@] "${passed_docker_option[@]}" add_passed_docker_option passed_phases[@] "${passed_docker_option[@]}"
} }

View File

@@ -41,78 +41,109 @@ git_build_app_repo() {
fi fi
} }
case "$1" in git_hook_cmd() {
git-hook) local desc="kick off receive-app trigger from git prereceive hook"
APP=$2 local cmd="git-hook"
local APP="$2"
while read -r oldrev newrev refname; do local oldrev newrev refname
# Only run this script for the master branch. You can remove this while read -r oldrev newrev refname; do
# if block if you wish to run it for others as well. # Only run this script for the master branch. You can remove this
if [[ $refname = "refs/heads/master" ]]; then # if block if you wish to run it for others as well.
# broken out into plugin so we might support other methods to receive an app if [[ $refname = "refs/heads/master" ]]; then
# shellcheck disable=SC2086 # broken out into plugin so we might support other methods to receive an app
plugn trigger receive-app $APP $newrev # shellcheck disable=SC2086
else plugn trigger receive-app $APP $newrev
if test -f "$PLUGIN_PATH"/enabled/*/receive-branch; then
# shellcheck disable=SC2086
plugn trigger receive-branch $APP $newrev $refname
else
echo $'\e[1G\e[K'"-----> WARNING: deploy did not complete, you must push to master."
echo $'\e[1G\e[K'"-----> for example, try 'git push <dokku> ${refname/refs\/heads\/}:master'"
fi
fi
done
;;
git-upload-pack)
APP="$(echo "$2" | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g')"
plugn trigger git-pre-pull "$APP"
cat | git-upload-pack "$DOKKU_ROOT/$APP"
plugn trigger git-post-pull "$APP"
;;
git-build)
APP="$2"; APP_BUILD_LOCK="$DOKKU_ROOT/$APP/.build.lock"
APP_BUILD_LOCK_MSG="$APP is currently being deployed or locked. Waiting..."
[[ $(flock -n "$APP_BUILD_LOCK" true &>/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG"
shift 1
flock -o "$APP_BUILD_LOCK" dokku git-build-locked "$@"
;;
git-build-locked)
APP="$2"
if [[ $# -ge 3 ]]; then
REF="$3"
else else
REF=$(< "$DOKKU_ROOT/$APP/refs/heads/master") if test -f "$PLUGIN_PATH"/enabled/*/receive-branch; then
# shellcheck disable=SC2086
plugn trigger receive-branch $APP $newrev $refname
else
echo $'\e[1G\e[K'"-----> WARNING: deploy did not complete, you must push to master."
echo $'\e[1G\e[K'"-----> for example, try 'git push <dokku> ${refname/refs\/heads\/}:master'"
fi
fi fi
# shellcheck disable=SC2086 done
git_build_app_repo $APP $REF }
;;
git-*) git_upload_pack_cmd() {
APP="$(echo "$2" | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g' | sed 's/^\///g')" local desc="executes git-upload-pack"
APP_PATH=$DOKKU_ROOT/$APP local cmd="git-upload-pack"
local APP="$(echo "$2" | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g')"
plugn trigger git-pre-pull "$APP"
cat | git-upload-pack "$DOKKU_ROOT/$APP"
plugn trigger git-post-pull "$APP"
}
if [[ $1 == "git-receive-pack" && ! -d "$APP_PATH/refs" ]]; then git_build_cmd() {
git init --bare "$APP_PATH" > /dev/null local desc="lock git-build"
PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive" local cmd="git-build"
cat > "$PRERECEIVE_HOOK" <<EOF local APP="$2"; local APP_BUILD_LOCK="$DOKKU_ROOT/$APP/.build.lock"
local APP_BUILD_LOCK_MSG="$APP is currently being deployed or locked. Waiting..."
[[ $(flock -n "$APP_BUILD_LOCK" true &>/dev/null ; echo $?) -ne 0 ]] && echo "$APP_BUILD_LOCK_MSG"
shift 1
flock -o "$APP_BUILD_LOCK" dokku git-build-locked "$@"
}
git_build_locked_cmd() {
local desc="setup and call git_build_app_repo"
local cmd="git-build-locked"
local APP="$2"
if [[ $# -ge 3 ]]; then
local REF="$3"
else
local REF=$(< "$DOKKU_ROOT/$APP/refs/heads/master")
fi
# shellcheck disable=SC2086
git_build_app_repo $APP $REF
}
git_glob_cmd() {
local desc="catch-all for any other git-* commands"
local cmd="git-*"
local APP="$(echo "$2" | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g' | sed 's/^\///g')"
local APP_PATH=$DOKKU_ROOT/$APP
if [[ $1 == "git-receive-pack" && ! -d "$APP_PATH/refs" ]]; then
git init --bare "$APP_PATH" > /dev/null
local PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive"
cat > "$PRERECEIVE_HOOK" <<EOF
#!/usr/bin/env bash #!/usr/bin/env bash
set -e; set -o pipefail; set -e; set -o pipefail;
cat | DOKKU_ROOT="$DOKKU_ROOT" dokku git-hook $APP cat | DOKKU_ROOT="$DOKKU_ROOT" dokku git-hook $APP
EOF EOF
chmod +x "$PRERECEIVE_HOOK" chmod +x "$PRERECEIVE_HOOK"
fi fi
if [[ $1 == "git-receive-pack" ]]; then if [[ $1 == "git-receive-pack" ]]; then
args="$1 '$APP_PATH'" local args="$1 '$APP_PATH'"
else else
args=$* local args=$*
fi fi
git-shell -c "$args" git-shell -c "$args"
}
case "$1" in
git-hook)
git_hook_cmd "$@"
;;
git-upload-pack)
git_upload_pack_cmd "$@"
;;
git-build)
git_build_cmd "$@"
;;
git-build-locked)
git_build_locked_cmd "$@"
;;
git-*)
git_glob_cmd "$@"
;; ;;
help | git:help) help | git:help)

View File

@@ -2,12 +2,18 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; REV="$2" git_receive_app(){
local desc="git receive-app plugin trigger"
local trigger="git_receive_app"
local APP="$1"; local REV="$2"
# Don't trigger git build if there is no git repository. # Don't trigger git build if there is no git repository.
if [[ ! -d "$DOKKU_ROOT/$APP/refs" ]]; then if [[ ! -d "$DOKKU_ROOT/$APP/refs" ]]; then
true true
else else
# shellcheck disable=SC2086 # shellcheck disable=SC2086
dokku git-build $APP $REV dokku git-build $APP $REV
fi fi
}
git_receive_app "$@"

View File

@@ -1,8 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/logs/functions"
logs_default_cmd() { logs_default_cmd() {
local desc="shows the last logs for an app via command line" local desc="shows the last logs for an app via command line"

View File

@@ -2,28 +2,36 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; APP_ROOT="$DOKKU_ROOT/$APP" named_containers_post_deploy() {
[[ -z $(stat -t "$APP_ROOT"/CONTAINER.* 2>/dev/null) ]] && exit 0 local desc="names deployed app container is consistent manner"
for container in "$APP_ROOT"/CONTAINER.*; do local trigger="named_containers_post_deploy"
DYNO=$(echo "$container" | sed -r 's/.*CONTAINER\.(.*)/\1/') || true local APP="$1"; local APP_ROOT="$DOKKU_ROOT/$APP"
NAME="$APP.$DYNO" [[ -z $(stat -t "$APP_ROOT"/CONTAINER.* 2>/dev/null) ]] && exit 0
CURRENT_CONTAINER_ID="$(< "$container")" local container
PREVIOUS_CIDS=$(docker ps -a -q -f name="^.?$NAME\$" | xargs) || true for container in "$APP_ROOT"/CONTAINER.*; do
if [[ -n $PREVIOUS_CIDS ]]; then local DYNO=$(echo "$container" | sed -r 's/.*CONTAINER\.(.*)/\1/') || true
dokku_log_info1_quiet "Found previous container(s) ($PREVIOUS_CIDS) named $NAME" local NAME="$APP.$DYNO"
# in case $PREVIOUS_CIDS has more than one entry local CURRENT_CONTAINER_ID="$(< "$container")"
for cid in $PREVIOUS_CIDS; do local PREVIOUS_CIDS=$(docker ps -a -q -f name="^.?$NAME\$" | xargs) || true
PREVIOUS_CONTAINER_STATUS=$(docker inspect -f '{{.State.Status}}' "$cid" || echo "dead") if [[ -n $PREVIOUS_CIDS ]]; then
# dead containers cannot be renamed dokku_log_info1_quiet "Found previous container(s) ($PREVIOUS_CIDS) named $NAME"
if [[ "$PREVIOUS_CONTAINER_STATUS" != "dead" ]]; then # in case $PREVIOUS_CIDS has more than one entry
CONTAINER_DATE_NAME="$NAME.$(date +%s)" local cid
dokku_log_info2_quiet "renaming container ($cid) ${NAME} to $CONTAINER_DATE_NAME" for cid in $PREVIOUS_CIDS; do
docker rename "$NAME" "$CONTAINER_DATE_NAME" > /dev/null local PREVIOUS_CONTAINER_STATUS=$(docker inspect -f '{{.State.Status}}' "$cid" || echo "dead")
fi # dead containers cannot be renamed
done if [[ "$PREVIOUS_CONTAINER_STATUS" != "dead" ]]; then
fi local CONTAINER_DATE_NAME="$NAME.$(date +%s)"
ID=$(cat "$container") dokku_log_info2_quiet "renaming container ($cid) ${NAME} to $CONTAINER_DATE_NAME"
CURRENT_NAME=$(docker inspect -f '{{.Name}}' "$ID" | tr -d /) docker rename "$NAME" "$CONTAINER_DATE_NAME" > /dev/null
dokku_log_info2_quiet "renaming container (${ID:0:12}) $CURRENT_NAME to $NAME" fi
docker rename "$CURRENT_NAME" "$NAME" > /dev/null done
done fi
local ID=$(cat "$container")
local CURRENT_NAME=$(docker inspect -f '{{.Name}}' "$ID" | tr -d /)
dokku_log_info2_quiet "renaming container (${ID:0:12}) $CURRENT_NAME to $NAME"
docker rename "$CURRENT_NAME" "$NAME" > /dev/null
done
}
named_containers_post_deploy "$@"

View File

@@ -47,9 +47,9 @@ nginx_logs() {
local NGINX_LOGS_PATH="/var/log/nginx/$APP-$NGINX_LOGS_TYPE.log" local NGINX_LOGS_PATH="/var/log/nginx/$APP-$NGINX_LOGS_TYPE.log"
if [[ $3 == "-t" ]]; then if [[ $3 == "-t" ]]; then
NGINX_LOGS_ARGS="-F" local NGINX_LOGS_ARGS="-F"
else else
NGINX_LOGS_ARGS="-n 20" local NGINX_LOGS_ARGS="-n 20"
fi fi
tail "$NGINX_LOGS_ARGS" "$NGINX_LOGS_PATH" tail "$NGINX_LOGS_ARGS" "$NGINX_LOGS_PATH"

View File

@@ -6,6 +6,8 @@ source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
nginx_post_deploy() { nginx_post_deploy() {
local desc="nginx-vhosts post-deploy plugin trigger"
local trigger="nginx_post_deploy"
local APP="$1" local APP="$1"
if [[ -f "$DOKKU_ROOT/$APP/IP.web.1" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]]; then if [[ -f "$DOKKU_ROOT/$APP/IP.web.1" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]]; then
if [[ "$(is_app_vhost_enabled "$APP")" == "false" ]]; then if [[ "$(is_app_vhost_enabled "$APP")" == "false" ]]; then

View File

@@ -4,6 +4,12 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions" source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
if [[ "$(get_app_proxy_type "$1")" == "nginx" ]]; then nginx_post_domains_update() {
nginx_build_config "$1" local desc="calls nginx build_config when domains are updated"
fi local trigger="nginx_post_domains_update"
if [[ "$(get_app_proxy_type "$1")" == "nginx" ]]; then
nginx_build_config "$1"
fi
}
nginx_post_domains_update "$@"

View File

@@ -4,8 +4,9 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions"
nginx_disable() { nginx_proxy_disable() {
local desc="disable nginx proxy" local desc="disable nginx proxy"
local trigger="nginx_proxy_disable"
local APP="$1"; verify_app_name "$APP" local APP="$1"; verify_app_name "$APP"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
@@ -14,4 +15,4 @@ nginx_disable() {
fi fi
} }
nginx_disable "$@" nginx_proxy_disable "$@"

View File

@@ -4,8 +4,9 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/ps/functions"
nginx_enable() { nginx_proxy_enable() {
local desc="enable nginx proxy" local desc="enable nginx proxy"
local trigger="nginx_proxy_enable"
local APP="$1"; verify_app_name "$APP" local APP="$1"; verify_app_name "$APP"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
@@ -14,4 +15,4 @@ nginx_enable() {
fi fi
} }
nginx_enable "$@" nginx_proxy_enable "$@"

View File

@@ -44,7 +44,7 @@ generate_scale_file() {
if [[ ! -f $DOKKU_SCALE_FILE ]]; then if [[ ! -f $DOKKU_SCALE_FILE ]]; then
dokku_log_info1_quiet "DOKKU_SCALE file not found in app image. Generating one based on Procfile..." dokku_log_info1_quiet "DOKKU_SCALE file not found in app image. Generating one based on Procfile..."
TMP_WORK_DIR=$(mktemp -d -t "dokku_scale.XXXX") local TMP_WORK_DIR=$(mktemp -d -t "dokku_scale.XXXX")
trap 'rm -rf "$TMP_WORK_DIR" > /dev/null' RETURN trap 'rm -rf "$TMP_WORK_DIR" > /dev/null' RETURN
if [[ -f $DOKKU_PROCFILE ]]; then if [[ -f $DOKKU_PROCFILE ]]; then
@@ -52,8 +52,8 @@ generate_scale_file() {
if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then
continue continue
fi fi
NAME=${line%%:*} local NAME=${line%%:*}
NUM_PROCS=0 local NUM_PROCS=0
[[ "$NAME" == "web" ]] && NUM_PROCS=1 [[ "$NAME" == "web" ]] && NUM_PROCS=1
[[ -n "$NAME" ]] && echo "$NAME=$NUM_PROCS" >> "$DOKKU_SCALE_FILE" [[ -n "$NAME" ]] && echo "$NAME=$NUM_PROCS" >> "$DOKKU_SCALE_FILE"
done < "$DOKKU_PROCFILE" done < "$DOKKU_PROCFILE"
@@ -73,8 +73,8 @@ set_scale() {
shift 1 shift 1
local SCALE_SETTINGS=("$@") local SCALE_SETTINGS=("$@")
for procscale in "${SCALE_SETTINGS[@]}"; do for procscale in "${SCALE_SETTINGS[@]}"; do
PROC_NAME=${procscale%%=*} local PROC_NAME=${procscale%%=*}
PROC_COUNT=${procscale#*=} local PROC_COUNT=${procscale#*=}
is_number $PROC_COUNT || dokku_log_fail "ps:scale $PROC_COUNT is not a number" is_number $PROC_COUNT || dokku_log_fail "ps:scale $PROC_COUNT is not a number"
dokku_log_info1_quiet "Scaling $APP:$PROC_NAME to $PROC_COUNT" dokku_log_info1_quiet "Scaling $APP:$PROC_NAME to $PROC_COUNT"
if (egrep -q ^${PROC_NAME}= "$DOKKU_SCALE_FILE" > /dev/null 2>&1); then if (egrep -q ^${PROC_NAME}= "$DOKKU_SCALE_FILE" > /dev/null 2>&1); then
@@ -147,8 +147,8 @@ ps_scale() {
dokku_col_log_info1_quiet "--------" "---" dokku_col_log_info1_quiet "--------" "---"
while read -r line || [[ -n "$line" ]]; do while read -r line || [[ -n "$line" ]]; do
[[ -z "$line" ]] && continue [[ -z "$line" ]] && continue
PROC_NAME=${line%%=*} local PROC_NAME=${line%%=*}
PROC_COUNT=${line#*=} local PROC_COUNT=${line#*=}
dokku_col_log_info1 "$PROC_NAME" "$PROC_COUNT" dokku_col_log_info1 "$PROC_NAME" "$PROC_COUNT"
done < "$DOKKU_SCALE_FILE" done < "$DOKKU_SCALE_FILE"
else else

View File

@@ -1,9 +1,16 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions" source "$PLUGIN_AVAILABLE_PATH/ps/functions"
APP="$1" ps_post_deploy() {
local desc="ps post-deploy plugin trigger"
local trigger="ps_post_deploy"
local APP="$1"
remove_procfile "$APP" remove_procfile "$APP"
dokku config:set --no-restart "$APP" DOKKU_APP_RESTORE=1 config_set --no-restart "$APP" DOKKU_APP_RESTORE=1
}
ps_post_deploy "$@"

View File

@@ -1,8 +1,13 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions" source "$PLUGIN_AVAILABLE_PATH/ps/functions"
APP="$1" ps_post_stop() {
local desc="ps post-stop plugin trigger"
local trigger="ps_post_stop"
local APP="$1"
dokku config:set --no-restart "$APP" DOKKU_APP_RESTORE=0 config_set --no-restart "$APP" DOKKU_APP_RESTORE=0
}

View File

@@ -3,7 +3,13 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions" source "$PLUGIN_AVAILABLE_PATH/ps/functions"
APP="$1" ps_pre_deploy() {
local desc="ps pre-deploy plugin trigger"
local trigger="ps_pre_deploy"
local APP="$1"
extract_procfile "$APP" extract_procfile "$APP"
generate_scale_file "$APP" generate_scale_file "$APP"
}
ps_pre_deploy "$@"

View File

@@ -12,8 +12,9 @@ ps_main_cmd() {
! (is_deployed "$APP") && echo "App $APP has not been deployed" && exit 0 ! (is_deployed "$APP") && echo "App $APP has not been deployed" && exit 0
local CID
for CID in $DOKKU_APP_RUNNING_CONTAINER_IDS; do for CID in $DOKKU_APP_RUNNING_CONTAINER_IDS; do
has_tty && DOKKU_RUN_OPTS="-i -t" has_tty && local DOKKU_RUN_OPTS="-i -t"
dokku_log_info1_quiet "running processes in container: $CID" dokku_log_info1_quiet "running processes in container: $CID"
# shellcheck disable=SC2086 # shellcheck disable=SC2086
docker exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww" docker exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww"

View File

@@ -1,13 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions" source "$PLUGIN_AVAILABLE_PATH/ps/functions"
ps_restore_cmd() { ps_restore_cmd() {
local desc="starts all apps with DOKKU_APP_RESTORE not set to 0 via command line" local desc="starts all apps with DOKKU_APP_RESTORE not set to 0 via command line"
local cmd="ps:restore" local cmd="ps:restore"
for app in $(dokku_apps); do for app in $(dokku_apps); do
local DOKKU_APP_RESTORE=$(dokku config:get "$app" DOKKU_APP_RESTORE || true) local DOKKU_APP_RESTORE=$(config_get "$app" DOKKU_APP_RESTORE || true)
if [[ $DOKKU_APP_RESTORE != 0 ]]; then if [[ $DOKKU_APP_RESTORE != 0 ]]; then
echo "Restoring app $app ..." echo "Restoring app $app ..."
ps_start "$app" ps_start "$app"

View File

@@ -1,40 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
[[ " storage storage:list storage:mount storage:unmount storage:help help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT" [[ " storage:help help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/storage/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/docker-options/functions"
case "$1" in case "$1" in
storage:list)
# List all bound mounts
passed_phases="deploy"
[[ ! $2 ]] && dokku_log_fail "storage:list requires an app to list."
verify_app_name "$2" && APP="$2"
echo "$APP volume bind-mounts:"
get_bind_mounts "$(get_phase_file_path "$passed_phases")"
;;
storage:mount)
# Add bind-mount, redeploy app if running
passed_phases=(deploy run)
[[ -z $3 || $4 ]] && dokku_log_fail "storage:mount requires an app and a two paths devided by colon."
verify_app_name "$2" && APP="$2"
verify_paths "$3" && MOUNT_PATH="$3"
check_if_path_exists "$MOUNT_PATH" "$(get_phase_file_path "${passed_phases[@]}")" && dokku_log_fail "Mount path already exists."
add_passed_docker_option passed_phases[@] "-v $MOUNT_PATH"
;;
storage:unmount)
# Remove bind-mount, restart app if running
passed_phases=(deploy run)
[[ -z $3 || $4 ]] && dokku_log_fail "storage:unmount requires an app and a two paths devided by colon."
verify_app_name "$2" && APP="$2"
verify_paths "$3" && MOUNT_PATH="$3"
check_if_path_exists "$MOUNT_PATH" "$(get_phase_file_path "${passed_phases[@]}")" || dokku_log_fail "Mount path does not exist."
remove_passed_docker_option passed_phases[@] "-v $MOUNT_PATH"
;;
help | storage:help) help | storage:help)
cat<<EOF cat<<EOF
storage:list <app>, List bind mounts for app's container(s) (host:container) storage:list <app>, List bind mounts for app's container(s) (host:container)

View File

@@ -3,16 +3,19 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
verify_paths() { verify_paths() {
echo "$1" | grep -qe '^/.*\:/' || dokku_log_fail "Storage path must be two valid paths devided by colon." local desc="verifies storage paths"
echo "$1" | grep -qe '^/.*\:/' || dokku_log_fail "Storage path must be two valid paths divided by colon."
} }
check_if_path_exists() { check_if_path_exists() {
local desc="checks if path exists"
local -r passed_path=$1 local -r passed_path=$1
local -r phase_file_path=$2 local -r phase_file_path=$2
[[ -r "$phase_file_path" ]] && grep -qe "^-v $passed_path" "$phase_file_path" [[ -r "$phase_file_path" ]] && grep -qe "^-v $passed_path" "$phase_file_path"
} }
get_bind_mounts() { get_bind_mounts() {
local desc="strips docker options and prints mounts"
local -r phase_file_path=$1 local -r phase_file_path=$1
[[ -r "$phase_file_path" ]] && sed -e '/^-v/!d' -e 's/^-v/ /' < "$phase_file_path" [[ -r "$phase_file_path" ]] && sed -e '/^-v/!d' -e 's/^-v/ /' < "$phase_file_path"
} }

View 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/storage/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/docker-options/functions"
storage_list_cmd() {
local desc="List all bound mounts"
local cmd="storage:list"
local passed_phases="deploy"
[[ ! $2 ]] && dokku_log_fail "storage:list requires an app to list."
verify_app_name "$2" && local APP="$2"
echo "$APP volume bind-mounts:"
get_bind_mounts "$(get_phase_file_path "$passed_phases")"
}
storage_list_cmd "$@"

View 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/storage/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/docker-options/functions"
storage_mount_cmd() {
local desc="Add bind-mount, redeploy app if running"
local cmd="storage:mount"
local passed_phases=(deploy run)
[[ -z $3 || $4 ]] && dokku_log_fail "storage:mount requires an app and a two paths divided by colon."
verify_app_name "$2" && local APP="$2"
verify_paths "$3" && local MOUNT_PATH="$3"
check_if_path_exists "$MOUNT_PATH" "$(get_phase_file_path "${passed_phases[@]}")" && dokku_log_fail "Mount path already exists."
add_passed_docker_option passed_phases[@] "-v $MOUNT_PATH"
}
storage_mount_cmd "$@"

View 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/storage/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/docker-options/functions"
storage_unmount_cmd() {
local desc="Remove bind-mount, restart app if running"
local cmd="storage:unmount"
local passed_phases=(deploy run)
[[ -z $3 || $4 ]] && dokku_log_fail "storage:unmount requires an app and a two paths divided by colon."
verify_app_name "$2" && local APP="$2"
verify_paths "$3" && local MOUNT_PATH="$3"
check_if_path_exists "$MOUNT_PATH" "$(get_phase_file_path "${passed_phases[@]}")" || dokku_log_fail "Mount path does not exist."
remove_passed_docker_option passed_phases[@] "-v $MOUNT_PATH"
}
storage_unmount_cmd "$@"

View File

@@ -7,7 +7,7 @@ tags_destroy_cmd() {
local desc="destroys an app image tag via command line" local desc="destroys an app image tag via command line"
local cmd="tags:destroy" local cmd="tags:destroy"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on" [[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG="$3"; IMAGE_REPO=$(get_app_image_repo "$APP") local APP="$2"; local IMAGE_TAG="$3"; local IMAGE_REPO=$(get_app_image_repo "$APP")
verify_app_name "$2" verify_app_name "$2"
case "$IMAGE_TAG" in case "$IMAGE_TAG" in

View File

@@ -3,7 +3,8 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions" source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
tar_receive_app() { tar_receive_app() {
local desc="receives app tarball and calls tar:build" local desc="tar receive-app plugin trigger"
local trigger="tar_receive_app"
local APP="$1"; local REV="$2" local APP="$1"; local REV="$2"
# Don't trigger tar build if there is no tarball. # Don't trigger tar build if there is no tarball.

View File

@@ -12,7 +12,7 @@ tar_build_locked_cmd() {
# clean up after ourselves # clean up after ourselves
local TMP_WORK_DIR=$(mktemp -d -t "dokku_tar.XXXX") local TMP_WORK_DIR=$(mktemp -d -t "dokku_tar.XXXX")
trap 'rm -rf "$TMP_WORK_DIR" > /dev/null' INT TERM EXIT trap 'rm -rf "$TMP_WORK_DIR" > /dev/null' RETURN INT TERM EXIT
# extract tar file # extract tar file
chmod 755 "$TMP_WORK_DIR" chmod 755 "$TMP_WORK_DIR"

View File

@@ -24,7 +24,10 @@ succeeded() {
TMP=$(mktemp -d -t "$TARGET.XXXXX") TMP=$(mktemp -d -t "$TARGET.XXXXX")
rmdir "$TMP" && cp -r "$(dirname "$SELF")/$APP" "$TMP" rmdir "$TMP" && cp -r "$(dirname "$SELF")/$APP" "$TMP"
cd "$TMP"
pushd "$TMP" &> /dev/null || exit 1
trap 'popd &> /dev/null || true; rm -rf "$TMP"' INT TERM EXIT
git init git init
git config user.email "robot@example.com" git config user.email "robot@example.com"
git config user.name "Test Robot" git config user.name "Test Robot"