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"
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"
if [[ -z "$DOKKU_SKIP_CLEANUP" ]]; then
dokku_log_info1 "Cleaning up..."
@@ -21,6 +23,8 @@ dokku_receive() {
}
dokku_deploy() {
local desc="deploy phase"
local cmd="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")
verify_app_name "$APP"
@@ -55,9 +59,9 @@ dokku_deploy() {
[[ -n "$DOKKU_HEROKUISH" ]] && local START_CMD="/start $PROC_TYPE"
if [[ -z "$DOKKU_HEROKUISH" ]]; then
local DOKKU_DOCKERFILE_PORTS=($(dokku config:get "$APP" DOKKU_DOCKERFILE_PORTS || true))
local DOKKU_DOCKERFILE_PORT=$(dokku config:get "$APP" DOKKU_DOCKERFILE_PORT || true)
local DOKKU_DOCKERFILE_START_CMD=$(dokku config:get "$APP" DOKKU_DOCKERFILE_START_CMD || true)
local DOKKU_DOCKERFILE_PORTS=($(config_get "$APP" DOKKU_DOCKERFILE_PORTS || true))
local DOKKU_DOCKERFILE_PORT=$(config_get "$APP" DOKKU_DOCKERFILE_PORT || 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 START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD}
fi
@@ -77,7 +81,7 @@ dokku_deploy() {
local DOKKU_DOCKER_PORT_ARGS+=" -p $p "
done
fi
if [[ "$DOKKU_IS_APP_PROXY_ENABLED" = "true" ]]; then
if [[ "$DOKKU_IS_APP_PROXY_ENABLED" == "true" ]]; then
# shellcheck disable=SC2086
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")
@@ -99,7 +103,8 @@ dokku_deploy() {
# if we can't post-deploy successfully, kill new container
kill_new() {
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
kill -9 $$
}
@@ -108,7 +113,7 @@ dokku_deploy() {
if [[ "$(is_app_checks_enabled "$APP")" == "false" ]]; then
dokku_log_info1 "zero downtime is disabled for app ($APP). skipping pre-flight checks"
else
trap kill_new INT TERM EXIT
trap 'kill_new $id' INT TERM EXIT
dokku_log_info1 "Running pre-flight checks"
plugn trigger check-deploy "$APP" "$id" "$PROC_TYPE" "$port" "$ipaddr"
trap - INT TERM EXIT
@@ -144,8 +149,8 @@ dokku_deploy() {
if [[ -n "$oldids" ]]; 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_GLOBAL_DOKKU_WAIT_TO_RETIRE=$(dokku config:get --global 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=$(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"}
fi
@@ -176,6 +181,8 @@ dokku_deploy() {
}
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")
verify_app_name "$APP"
@@ -224,6 +231,8 @@ dokku_build() {
}
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")
verify_app_name "$APP"
@@ -256,6 +265,8 @@ dokku_release() {
}
dokku_trace() {
local desc="enables/disables DOKKU_TRACE"
local cmd="trace"
[[ -d $DOKKU_ROOT/.dokkurc ]] || mkdir -p "$DOKKU_ROOT/.dokkurc"
[[ "$2" == "on" ]] || [[ "$2" == "off" ]] || {
dokku_log_fail "Valid trace options are [on/off]"
@@ -273,6 +284,8 @@ dokku_trace() {
}
dokku_ls() {
local desc="lists installed apps with status"
local cmd="ls"
local installed_apps=$(dokku_apps)
local dokku_app
@@ -297,6 +310,8 @@ dokku_ls() {
}
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"
local APP="$2"; local IMAGE_TAG=$(get_running_image_tag "$APP"); local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP"
@@ -304,8 +319,8 @@ dokku_run() {
shift 2
if [[ -z "$DOKKU_RM_CONTAINER" ]]; then
local DOKKU_APP_RM_CONTAINER=$(dokku config:get "$APP" DOKKU_RM_CONTAINER || true)
local DOKKU_GLOBAL_RM_CONTAINER=$(dokku config:get --global DOKKU_RM_CONTAINER || true)
local DOKKU_APP_RM_CONTAINER=$(config_get "$APP" 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"}
fi
@@ -313,7 +328,7 @@ dokku_run() {
[[ "$DOKKU_TRACE" ]] && local DOCKER_ARGS+=" -e TRACE=true "
[[ "$DOKKU_RM_CONTAINER" ]] && local DOKKU_RUN_OPTS="--rm"
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
docker run $DOKKU_GLOBAL_RUN_ARGS $DOKKU_RUN_OPTS $DOCKER_ARGS $IMAGE $EXEC_CMD "$@"
}

View File

@@ -1,27 +1,13 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
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() {
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 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
@@ -36,7 +22,8 @@ get_phase_script() {
execute_script() {
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
dokku_log_info1 "Running '$SCRIPT_CMD' in app container"
local COMMAND="cd /app ; "
@@ -49,7 +36,7 @@ execute_script() {
local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP")
local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
# 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
dokku_container_log_verbose_quiet "$id"
if [[ "$PHASE_SCRIPT_KEY" != "postdeploy" ]];then
@@ -58,5 +45,26 @@ execute_script() {
fi
}
dokku_log_info1 "Attempting to run scripts.dokku.$PHASE_SCRIPT_KEY from app.json (if defined)"
execute_script
exec_app_json_scripts() {
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"
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
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; IMAGE_REPO=$(get_app_image_repo "$APP")
[[ -n $APP ]] && rm -rf "${DOKKU_ROOT:?}/$APP" > /dev/null
app_post_delete() {
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
# shellcheck disable=SC2046
docker rm -f $(docker ps -a --no-trunc | egrep "dokku/${APP}:" | awk '{ print $1 }' | xargs) &>/dev/null || true
# shellcheck disable=SC2046
docker rmi $(docker images -q "$IMAGE_REPO" | xargs) &>/dev/null || true
# remove all application containers & images
# shellcheck disable=SC2046
docker rm -f $(docker ps -a --no-trunc | egrep "dokku/${APP}:" | awk '{ print $1 }' | xargs) &>/dev/null || true
# shellcheck disable=SC2046
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
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"
verify_app_name "$APP"
apps_pre_delete() {
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
docker run "$DOKKU_GLOBAL_RUN_ARGS" --rm -v "$CACHE_DIR:/cache" "$IMAGE" find /cache -depth -mindepth 1 -maxdepth 1 -exec rm -Rf {} \; || true
fi
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
fi
}
apps_pre_delete "$@"

View File

@@ -1,6 +1,7 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/apps/functions"
apps_destroy_cmd() {
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"
[[ "$2" == "tls" ]] && dokku_log_fail "Unable to destroy tls directory"
[[ "$3" == "force" ]] && export DOKKU_APPS_FORCE_DELETE=1
local APP="$2"; 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"
local APP="$2"
apps_destroy "$APP"
}
apps_destroy_cmd "$@"

View File

@@ -1,6 +1,8 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/apps/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
apps_rename_cmd() {
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
rm -rf "$DOKKU_ROOT/$OLD_APP/cache"
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/VHOST"
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"
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_AVAILABLE_PATH/config/functions"
APP="$1"; IMAGE=$(get_app_image_name "$APP"); BUILD_ENV=""
verify_app_name "$APP"
build_env_pre_build_buildpack() {
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_TIMEOUT) ]] && config_set --global CURL_TIMEOUT=30
[[ -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
if [[ -n $(config_export global) ]]; then
BUILD_ENV+=$'\n'
BUILD_ENV+=$(config_export global)
BUILD_ENV+=$'\n'
fi
if [[ -n $(config_export app "$APP") ]]; then
BUILD_ENV+=$'\n'
BUILD_ENV+=$(config_export app "$APP")
BUILD_ENV+=$'\n'
fi
if [[ -n $(config_export global) ]]; then
local BUILD_ENV+=$'\n'
local BUILD_ENV+=$(config_export global)
local BUILD_ENV+=$'\n'
fi
if [[ -n $(config_export app "$APP") ]]; then
local BUILD_ENV+=$'\n'
local BUILD_ENV+=$(config_export app "$APP")
local BUILD_ENV+=$'\n'
fi
if [[ ! -z "$BUILD_ENV" ]]; then
dokku_log_info1 "Adding BUILD_ENV to build environment..."
# create build env files for use in buildpacks like this:
# 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")
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
if [[ ! -z "$BUILD_ENV" ]]; then
dokku_log_info1 "Adding BUILD_ENV to build environment..."
# create build env files for use in buildpacks like this:
# https://github.com/niteoweb/heroku-buildpack-buildout/blob/5879fa3418f7d8e079f1aa5816ba1adde73f4948/bin/compile#L34
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
docker commit "$id" "$IMAGE" > /dev/null
# 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")
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
fi
# create build env for 'old style' buildpacks and dokku plugins
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
docker commit "$id" "$IMAGE" > /dev/null
fi
}
build_env_pre_build_buildpack "$@"

View File

@@ -5,7 +5,7 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
is_ssl_enabled() {
local desc="returns 0 if ssl is enabled for given 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
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 "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")"
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
SSL_SELF_SIGNED="verified by a certificate authority."
local SSL_SELF_SIGNED="verified by a certificate authority."
else
SSL_SELF_SIGNED="self signed."
local SSL_SELF_SIGNED="self signed."
fi
dokku_log_info2 "SSL certificate is $SSL_SELF_SIGNED"
else

View File

@@ -33,189 +33,198 @@
# TIMEOUT=60 # Timeout after a minute
# ATTEMPTS=10 # retry checks 10 times
#
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/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"
if [[ -z "$DOKKU_APP_LISTEN_PORT" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then
DOKKU_APP_LISTEN_PORT=$(< "$DOKKU_ROOT/$APP/PORT")
fi
if [[ -z "$DOKKU_APP_LISTEN_IP" ]] && [[ -f "$DOKKU_ROOT/$APP/IP" ]]; then
DOKKU_APP_LISTEN_IP=$(< "$DOKKU_ROOT/$APP/IP")
fi
if [[ -z "$DOKKU_APP_CONTAINER_ID" ]]; then
DOKKU_APP_CIDS=( $(get_app_container_ids "$APP") )
DOKKU_APP_CONTAINER_ID=${DOKKU_APP_CIDS[0]}
fi
# 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..."
checks_check_deploy() {
local desc="checks check-deploy plugin trigger"
local trigger="checks_check_deploy"
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_PORT" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT" ]]; then
local DOKKU_APP_LISTEN_PORT=$(< "$DOKKU_ROOT/$APP/PORT")
fi
if [[ -z "$DOKKU_APP_LISTEN_IP" ]] && [[ -f "$DOKKU_ROOT/$APP/IP" ]]; then
local DOKKU_APP_LISTEN_IP=$(< "$DOKKU_ROOT/$APP/IP")
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]}
fi
rm -rf "$TMPDIR"
# simple default check to see if the container stuck around
DOKKU_DEFAULT_CHECKS_WAIT="${DOKKU_DEFAULT_CHECKS_WAIT:-10}"
dokku_log_info1 "Waiting for $DOKKU_DEFAULT_CHECKS_WAIT seconds ..."
sleep "$DOKKU_DEFAULT_CHECKS_WAIT"
# 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")"
! (is_container_running $DOKKU_APP_CONTAINER_ID) && dokku_log_fail "App container failed to start!!"
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!!"
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
dokku_log_info1 "Default container check successful!" && exit 0
fi
# Wait this many seconds (default 5) for server to start before running checks.
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
exec < "$FILENAME"
while read -r LINE; do
# Name/value pair
if [[ "$LINE" =~ ^.+= ]]; then
TRIM=${LINE%#*}
NAME=${TRIM%=*}
VALUE=${TRIM#*=}
[[ "$NAME" = "WAIT" ]] && WAIT=$VALUE
[[ "$NAME" = "TIMEOUT" ]] && TIMEOUT=$VALUE
[[ "$NAME" = "ATTEMPTS" ]] && ATTEMPTS=$VALUE
fi
done
# 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
local TMPDIR=$(mktemp -d /tmp/dokku_CHECKS.XXXXX)
docker cp $DOKKU_APP_CONTAINER_ID:/app/CHECKS "$TMPDIR" 2> /dev/null || true
ATTEMPT=0
local FILENAME=${TMPDIR}/CHECKS
until [[ $SUCCESS == 1 || $ATTEMPT -ge $ATTEMPTS ]]
do
FAILEDCHECKS=0
ATTEMPT=$(( ATTEMPT + 1 ))
dokku_log_info1 "Attempt $ATTEMPT/$ATTEMPTS Waiting for $WAIT seconds ..."
sleep "$WAIT"
cleanup() {
local desc="cleans up TMPDIR and print container output"
local id="$1"
rm -rf "$TMPDIR"
dokku_log_info2_quiet "$APP container output:"
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)
# --compressed Test compression handled correctly
# --fail Fail on server errors (4xx, 5xx)
# --location Follow redirects
CURL_OPTIONS="-q --compressed --fail --location --max-time $TIMEOUT"
rm -rf "$TMPDIR"
# Set X-Forwarded-Proto header if TLS is enabled.
SSL="$DOKKU_ROOT/$APP/tls"; 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
CURL_OPTIONS+=" -H X-Forwarded-Proto:https"
# simple default check to see if the container stuck around
local DOKKU_DEFAULT_CHECKS_WAIT="${DOKKU_DEFAULT_CHECKS_WAIT:-10}"
dokku_log_info1 "Waiting for $DOKKU_DEFAULT_CHECKS_WAIT seconds ..."
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
# Reads name/value pairs, sets the WAIT and TIMEOUT variables
exec < "$FILENAME"
while read -r CHECK_URL EXPECTED; do
# Ignore empty lines and lines starting with #
# shellcheck disable=SC1001
[[ -z "$CHECK_URL" || "$CHECK_URL" =~ ^\# ]] && continue
# Ignore if it's not a URL in a supported format
# shellcheck disable=SC1001
! [[ "$CHECK_URL" =~ ^(http(s)?:)?\/.* ]] && continue
local LINE
while read -r LINE; do
# Name/value pair
if [[ "$LINE" =~ ^.+= ]]; then
local TRIM=${LINE%#*}
local NAME=${TRIM%=*}
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
URL_PROTOCOL=${CHECK_URL%:*}
CHECK_URL=${CHECK_URL#*:}
else
URL_PROTOCOL="http"
local ATTEMPT=0
until [[ $SUCCESS == 1 || $ATTEMPT -ge $ATTEMPTS ]]
do
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
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
UNPREFIXED=${CHECK_URL#//}
URL_HOSTNAME=${UNPREFIXED%%/*}
URL_PATHNAME=${UNPREFIXED#$URL_HOSTNAME}
exec < "$FILENAME"
local CHECK_URL
local EXPECTED
while read -r CHECK_URL EXPECTED; do
# Ignore empty lines and lines starting with #
# shellcheck disable=SC1001
[[ -z "$CHECK_URL" || "$CHECK_URL" =~ ^\# ]] && continue
# Ignore if it's not a URL in a supported format
# shellcheck disable=SC1001
! [[ "$CHECK_URL" =~ ^(http(s)?:)?\/.* ]] && continue
HEADERS="-H Host:$URL_HOSTNAME"
else
URL_HOSTNAME=localhost
URL_PATHNAME=$CHECK_URL
fi
# 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 ))
if [[ "$CHECK_URL" =~ ^https?: ]]; then
local URL_PROTOCOL=${CHECK_URL%:*}
local CHECK_URL=${CHECK_URL#*:}
else
local URL_PROTOCOL="http"
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
# Failed to connect/no response, OUTPUT contains error message
dokku_log_warn "$OUTPUT"
FAILEDCHECKS=$(( FAILEDCHECKS + 1 ))
local SUCCESS=1
fi
done
if [[ $FAILEDCHECKS -gt 0 ]]; then
dokku_log_warn "Check attempt $ATTEMPT/$ATTEMPTS failed."
SUCCESS=0
else
SUCCESS=1
dokku_log_fail "Could not start due to $FAILEDCHECKS failed checks."
exit 1
fi
done
if [[ $FAILEDCHECKS -gt 0 ]]; then
dokku_log_fail "Could not start due to $FAILEDCHECKS failed checks."
exit 1
fi
dokku_log_info1 "All checks successful!"
}
dokku_log_info1 "All checks successful!"
checks_check_deploy "$@"

View File

@@ -118,9 +118,8 @@ dokku_log_event() {
dokku_log_plugn_trigger_call() {
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"
}
@@ -131,6 +130,7 @@ dokku_container_log_verbose_quiet() {
OIFS=$IFS
IFS=$'\n'
local line
for line in $(docker logs "$CID" 2>&1); do
dokku_log_verbose_quiet "$line"
done
@@ -173,10 +173,10 @@ get_app_image_name() {
[[ -z "$APP" ]] && dokku_log_fail "(get_app_image_name) APP must not be null"
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"
else
IMAGE="$IMAGE_REPO:latest"
local IMAGE="$IMAGE_REPO:latest"
fi
echo "$IMAGE"
}
@@ -187,8 +187,8 @@ get_running_image_tag() {
[[ ! -n "$APP" ]] && dokku_log_fail "(get_running_image_tag) APP must not be null"
verify_app_name "$APP"
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 CIDS=( $(get_app_container_ids "$APP") )
local RUNNING_IMAGE_TAG=$(docker inspect -f '{{ .Config.Image }}' ${CIDS[0]} 2>/dev/null | awk -F: '{ print $2 }' || echo '')
echo "$RUNNING_IMAGE_TAG"
}
@@ -212,7 +212,7 @@ is_number() {
is_abs_path() {
local desc="returns 0 if input path is absolute"
local TEST_PATH=$1
if [[ "$TEST_PATH" = /* ]]; then
if [[ "$TEST_PATH" == /* ]]; then
return 0
else
return 1
@@ -241,7 +241,7 @@ parse_args() {
export DOKKU_APP_NAME=${args[$next_index]}; skip=true
;;
esac
next_index=$(( next_index + 1 ))
local next_index=$(( next_index + 1 ))
done
return 0
}
@@ -254,10 +254,10 @@ copy_from_image() {
if verify_image "$IMAGE"; then
if ! is_abs_path "$SRC_FILE"; then
local WORKDIR=$(docker inspect -f '{{.Config.WorkingDir}}' "$IMAGE")
[[ -z "$WORKDIR" ]] && WORKDIR=/app
SRC_FILE="$WORKDIR/$SRC_FILE"
[[ -z "$WORKDIR" ]] && local WORKDIR=/app
local SRC_FILE="$WORKDIR/$SRC_FILE"
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 rm -f "$CID" &> /dev/null
else
@@ -272,20 +272,21 @@ get_app_container_ids() {
[[ -f $DOKKU_ROOT/$APP/CONTAINER ]] && DOKKU_CIDS+=$(< "$DOKKU_ROOT/$APP/CONTAINER")
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
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE"
local CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE"
[[ ! -f $CONTAINER_PATTERN ]] && echo "" && return 0
fi
else
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.*"
local CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.*"
fi
shopt -s nullglob
local DOKKU_CID_FILE
for DOKKU_CID_FILE in $CONTAINER_PATTERN; do
DOKKU_CIDS+=" "
DOKKU_CIDS+=$(< "$DOKKU_CID_FILE")
DOKKU_CIDS+=" "
local DOKKU_CIDS+=" "
local DOKKU_CIDS+=$(< "$DOKKU_CID_FILE")
local DOKKU_CIDS+=" "
done
shopt -u nullglob
echo "$DOKKU_CIDS"
@@ -318,8 +319,8 @@ get_cmd_from_procfile() {
if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then
continue
fi
name="${line%%:*}"
command="${line#*:[[:space:]]}"
local name="${line%%:*}"
local command="${line#*:[[:space:]]}"
[[ "$name" == "$PROC_TYPE" ]] && echo "$command" && break
done < "$DOKKU_PROCFILE"
fi
@@ -376,6 +377,8 @@ is_app_running() {
release_and_deploy() {
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")
verify_app_name "$APP"
@@ -386,8 +389,8 @@ release_and_deploy() {
local IMAGE_SOURCE_TYPE="dockerfile"
fi
local DOKKU_APP_SKIP_DEPLOY="$(dokku config:get "$APP" DOKKU_SKIP_DEPLOY || true)"
local DOKKU_GLOBAL_SKIP_DEPLOY="$(dokku config:get --global DOKKU_SKIP_DEPLOY || true)"
local DOKKU_APP_SKIP_DEPLOY="$(config_get "$APP" 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"}
@@ -398,7 +401,7 @@ release_and_deploy() {
dokku_log_info1 "Deploying $APP ($IMAGE)..."
dokku deploy "$APP" "$IMAGE_TAG"
dokku_log_info2 "Application deployed:"
dokku urls "$APP" | sed "s/^/ /"
get_app_urls urls "$APP" | sed "s/^/ /"
else
dokku_log_info1 "Skipping deployment"
fi
@@ -453,18 +456,18 @@ _ipv4_regex() {
_ipv6_regex() {
local desc="ipv6 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
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
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
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
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 ::
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)
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="([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="${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,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,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,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,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,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}:((:[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}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
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)
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)
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"
}

View File

@@ -3,16 +3,22 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
STDIN=$(cat); APP="$1"; IMAGE_TAG="$2"; IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
DOCKERFILE_ENV_FILE="$DOKKU_ROOT/$APP/DOCKERFILE_ENV_FILE"
verify_app_name "$APP"
config_docker_args() {
local desc="config docker-args plugin trigger"
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
> "$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"
if ! is_image_herokuish_based "$IMAGE"; then
> "$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"
echo "$STDIN --env-file=$DOCKERFILE_ENV_FILE"
else
echo "$STDIN"
fi
echo "$STDIN --env-file=$DOCKERFILE_ENV_FILE"
else
echo "$STDIN"
fi
}
config_docker_args "$@"

View File

@@ -1,71 +1,78 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
STDIN=$(cat)
APP="$1"; IMAGE_SOURCE_TYPE="$2"
docker_args() {
local desc="docker args plugin trigger"
local trigger="$0"
local STDIN=$(cat)
local APP="$1"; local IMAGE_SOURCE_TYPE="$2"
case "$0" in
*docker-args-build)
PHASE=BUILD
;;
*docker-args-deploy)
PHASE=DEPLOY
;;
*docker-args-run)
PHASE=RUN
;;
esac
case "$0" in
*docker-args-build)
local PHASE=BUILD
;;
*docker-args-deploy)
local PHASE=DEPLOY
;;
*docker-args-run)
local PHASE=RUN
;;
esac
FILE_PREFIX="DOCKER_OPTIONS_"
PHASE_FILE_PATH="${DOKKU_ROOT}/${APP}/${FILE_PREFIX}${PHASE}"
local FILE_PREFIX="DOCKER_OPTIONS_"
local PHASE_FILE_PATH="${DOKKU_ROOT}/${APP}/${FILE_PREFIX}${PHASE}"
output=""
local output=""
if [[ -f "$PHASE_FILE_PATH" ]]; then
DONE=false
until $DONE; do
read -r line || DONE=true
if [[ -f "$PHASE_FILE_PATH" ]]; then
local DONE=false
until $DONE; do
local line
read -r line || local DONE=true
[[ ! -n "$line" ]] && continue
[[ ! -n "$line" ]] && continue
# shellcheck disable=SC1001
case "$line" in
\#*)
continue
;;
*)
case "$IMAGE_SOURCE_TYPE" in
dockerfile)
case "$line" in
--link*|-v*)
continue
;;
# shellcheck disable=SC1001
case "$line" in
\#*)
continue
;;
*)
case "$IMAGE_SOURCE_TYPE" in
dockerfile)
case "$line" in
--link*|-v*)
continue
;;
*)
output="$output $line"
;;
esac
;;
*)
local output="$output $line"
;;
esac
;;
herokuish)
case "$line" in
--file*|--build-args*)
continue
;;
herokuish)
case "$line" in
--file*|--build-args*)
continue
;;
*)
output="$output $line"
;;
esac
;;
*)
local output="$output $line"
;;
esac
;;
*)
output="$output $line"
;;
esac
;;
esac
done < "$PHASE_FILE_PATH"
fi
*)
local output="$output $line"
;;
esac
;;
esac
done < "$PHASE_FILE_PATH"
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 phases=("${AVAILABLE_PHASES[@]}")
for phase in "${phases[@]}"; do
local phase_file_path
phase_file_path="$(get_phase_file_path "$phase")"
local phase_file_path="$(get_phase_file_path "$phase")"
if [[ -s "$phase_file_path" ]]; then
display_phase_options "$phase" "$phase_file_path"
fi
@@ -62,8 +61,7 @@ display_passed_phases_options() {
local passed_phases=("${!1}")
local phase
for phase in "${passed_phases[@]}"; do
local phase_file_path
phase_file_path="$(get_phase_file_path "$phase")"
local phase_file_path="$(get_phase_file_path "$phase")"
if [[ ! -s "$phase_file_path" ]]; then
echo "${phase^} options: none"
else
@@ -79,11 +77,10 @@ add_passed_docker_option() {
local passed_option_string="$*"
local phase
for phase in "${passed_phases[@]}"; do
local phase_file_path
phase_file_path="$(get_phase_file_path "$phase")"
local phase_file_path="$(get_phase_file_path "$phase")"
create_phase_file_if_required "$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"
done
}
@@ -95,11 +92,10 @@ remove_passed_docker_option() {
local passed_option_string="$*"
local phase
for phase in "${passed_phases[@]}"; do
local phase_file_path
phase_file_path="$(get_phase_file_path "$phase")"
local phase_file_path="$(get_phase_file_path "$phase")"
[[ ! -s "$phase_file_path" ]] || {
all_phase_options="$(< "$phase_file_path")"
all_phase_options=$(echo -e "${all_phase_options}" | sed "s#^${passed_option_string}\$##")
local all_phase_options="$(< "$phase_file_path")"
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"
}
done

View File

@@ -10,7 +10,7 @@ docker_options_add_cmd() {
verify_app_name "$2" && local APP="$2"
read -ra passed_phases <<< "$(get_phases "$3")"
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"
add_passed_docker_option passed_phases[@] "${passed_docker_option[@]}"
}

View File

@@ -41,78 +41,109 @@ git_build_app_repo() {
fi
}
case "$1" in
git-hook)
APP=$2
git_hook_cmd() {
local desc="kick off receive-app trigger from git prereceive hook"
local cmd="git-hook"
local APP="$2"
while read -r oldrev newrev refname; do
# Only run this script for the master branch. You can remove this
# if block if you wish to run it for others as well.
if [[ $refname = "refs/heads/master" ]]; then
# broken out into plugin so we might support other methods to receive an app
# shellcheck disable=SC2086
plugn trigger receive-app $APP $newrev
else
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"
local oldrev newrev refname
while read -r oldrev newrev refname; do
# Only run this script for the master branch. You can remove this
# if block if you wish to run it for others as well.
if [[ $refname = "refs/heads/master" ]]; then
# broken out into plugin so we might support other methods to receive an app
# shellcheck disable=SC2086
plugn trigger receive-app $APP $newrev
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
# shellcheck disable=SC2086
git_build_app_repo $APP $REF
;;
done
}
git-*)
APP="$(echo "$2" | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g' | sed 's/^\///g')"
APP_PATH=$DOKKU_ROOT/$APP
git_upload_pack_cmd() {
local desc="executes git-upload-pack"
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 init --bare "$APP_PATH" > /dev/null
PRERECEIVE_HOOK="$APP_PATH/hooks/pre-receive"
cat > "$PRERECEIVE_HOOK" <<EOF
git_build_cmd() {
local desc="lock git-build"
local cmd="git-build"
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
set -e; set -o pipefail;
cat | DOKKU_ROOT="$DOKKU_ROOT" dokku git-hook $APP
EOF
chmod +x "$PRERECEIVE_HOOK"
fi
chmod +x "$PRERECEIVE_HOOK"
fi
if [[ $1 == "git-receive-pack" ]]; then
args="$1 '$APP_PATH'"
else
args=$*
fi
git-shell -c "$args"
if [[ $1 == "git-receive-pack" ]]; then
local args="$1 '$APP_PATH'"
else
local args=$*
fi
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)

View File

@@ -2,12 +2,18 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
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.
if [[ ! -d "$DOKKU_ROOT/$APP/refs" ]]; then
true
else
# shellcheck disable=SC2086
dokku git-build $APP $REV
fi
# Don't trigger git build if there is no git repository.
if [[ ! -d "$DOKKU_ROOT/$APP/refs" ]]; then
true
else
# shellcheck disable=SC2086
dokku git-build $APP $REV
fi
}
git_receive_app "$@"

View File

@@ -1,8 +1,6 @@
#!/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/logs/functions"
logs_default_cmd() {
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
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
APP="$1"; APP_ROOT="$DOKKU_ROOT/$APP"
[[ -z $(stat -t "$APP_ROOT"/CONTAINER.* 2>/dev/null) ]] && exit 0
for container in "$APP_ROOT"/CONTAINER.*; do
DYNO=$(echo "$container" | sed -r 's/.*CONTAINER\.(.*)/\1/') || true
NAME="$APP.$DYNO"
CURRENT_CONTAINER_ID="$(< "$container")"
PREVIOUS_CIDS=$(docker ps -a -q -f name="^.?$NAME\$" | xargs) || true
if [[ -n $PREVIOUS_CIDS ]]; then
dokku_log_info1_quiet "Found previous container(s) ($PREVIOUS_CIDS) named $NAME"
# in case $PREVIOUS_CIDS has more than one entry
for cid in $PREVIOUS_CIDS; do
PREVIOUS_CONTAINER_STATUS=$(docker inspect -f '{{.State.Status}}' "$cid" || echo "dead")
# dead containers cannot be renamed
if [[ "$PREVIOUS_CONTAINER_STATUS" != "dead" ]]; then
CONTAINER_DATE_NAME="$NAME.$(date +%s)"
dokku_log_info2_quiet "renaming container ($cid) ${NAME} to $CONTAINER_DATE_NAME"
docker rename "$NAME" "$CONTAINER_DATE_NAME" > /dev/null
fi
done
fi
ID=$(cat "$container")
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() {
local desc="names deployed app container is consistent manner"
local trigger="named_containers_post_deploy"
local APP="$1"; local APP_ROOT="$DOKKU_ROOT/$APP"
[[ -z $(stat -t "$APP_ROOT"/CONTAINER.* 2>/dev/null) ]] && exit 0
local container
for container in "$APP_ROOT"/CONTAINER.*; do
local DYNO=$(echo "$container" | sed -r 's/.*CONTAINER\.(.*)/\1/') || true
local NAME="$APP.$DYNO"
local CURRENT_CONTAINER_ID="$(< "$container")"
local PREVIOUS_CIDS=$(docker ps -a -q -f name="^.?$NAME\$" | xargs) || true
if [[ -n $PREVIOUS_CIDS ]]; then
dokku_log_info1_quiet "Found previous container(s) ($PREVIOUS_CIDS) named $NAME"
# in case $PREVIOUS_CIDS has more than one entry
local cid
for cid in $PREVIOUS_CIDS; do
local PREVIOUS_CONTAINER_STATUS=$(docker inspect -f '{{.State.Status}}' "$cid" || echo "dead")
# dead containers cannot be renamed
if [[ "$PREVIOUS_CONTAINER_STATUS" != "dead" ]]; then
local CONTAINER_DATE_NAME="$NAME.$(date +%s)"
dokku_log_info2_quiet "renaming container ($cid) ${NAME} to $CONTAINER_DATE_NAME"
docker rename "$NAME" "$CONTAINER_DATE_NAME" > /dev/null
fi
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"
if [[ $3 == "-t" ]]; then
NGINX_LOGS_ARGS="-F"
local NGINX_LOGS_ARGS="-F"
else
NGINX_LOGS_ARGS="-n 20"
local NGINX_LOGS_ARGS="-n 20"
fi
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"
nginx_post_deploy() {
local desc="nginx-vhosts post-deploy plugin trigger"
local trigger="nginx_post_deploy"
local APP="$1"
if [[ -f "$DOKKU_ROOT/$APP/IP.web.1" ]] && [[ -f "$DOKKU_ROOT/$APP/PORT.web.1" ]]; 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/proxy/functions"
if [[ "$(get_app_proxy_type "$1")" == "nginx" ]]; then
nginx_build_config "$1"
fi
nginx_post_domains_update() {
local desc="calls nginx build_config when domains are updated"
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/ps/functions"
nginx_disable() {
nginx_proxy_disable() {
local desc="disable nginx proxy"
local trigger="nginx_proxy_disable"
local APP="$1"; verify_app_name "$APP"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
@@ -14,4 +15,4 @@ nginx_disable() {
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/ps/functions"
nginx_enable() {
nginx_proxy_enable() {
local desc="enable nginx proxy"
local trigger="nginx_proxy_enable"
local APP="$1"; verify_app_name "$APP"
if [[ "$(get_app_proxy_type "$APP")" == "nginx" ]]; then
@@ -14,4 +15,4 @@ nginx_enable() {
fi
}
nginx_enable "$@"
nginx_proxy_enable "$@"

View File

@@ -44,7 +44,7 @@ generate_scale_file() {
if [[ ! -f $DOKKU_SCALE_FILE ]]; then
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
if [[ -f $DOKKU_PROCFILE ]]; then
@@ -52,8 +52,8 @@ generate_scale_file() {
if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then
continue
fi
NAME=${line%%:*}
NUM_PROCS=0
local NAME=${line%%:*}
local NUM_PROCS=0
[[ "$NAME" == "web" ]] && NUM_PROCS=1
[[ -n "$NAME" ]] && echo "$NAME=$NUM_PROCS" >> "$DOKKU_SCALE_FILE"
done < "$DOKKU_PROCFILE"
@@ -73,8 +73,8 @@ set_scale() {
shift 1
local SCALE_SETTINGS=("$@")
for procscale in "${SCALE_SETTINGS[@]}"; do
PROC_NAME=${procscale%%=*}
PROC_COUNT=${procscale#*=}
local PROC_NAME=${procscale%%=*}
local PROC_COUNT=${procscale#*=}
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"
if (egrep -q ^${PROC_NAME}= "$DOKKU_SCALE_FILE" > /dev/null 2>&1); then
@@ -147,8 +147,8 @@ ps_scale() {
dokku_col_log_info1_quiet "--------" "---"
while read -r line || [[ -n "$line" ]]; do
[[ -z "$line" ]] && continue
PROC_NAME=${line%%=*}
PROC_COUNT=${line#*=}
local PROC_NAME=${line%%=*}
local PROC_COUNT=${line#*=}
dokku_col_log_info1 "$PROC_NAME" "$PROC_COUNT"
done < "$DOKKU_SCALE_FILE"
else

View File

@@ -1,9 +1,16 @@
#!/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"
APP="$1"
ps_post_deploy() {
local desc="ps post-deploy plugin trigger"
local trigger="ps_post_deploy"
local APP="$1"
remove_procfile "$APP"
dokku config:set --no-restart "$APP" DOKKU_APP_RESTORE=1
remove_procfile "$APP"
config_set --no-restart "$APP" DOKKU_APP_RESTORE=1
}
ps_post_deploy "$@"

View File

@@ -1,8 +1,13 @@
#!/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"
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_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"
generate_scale_file "$APP"
extract_procfile "$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
local CID
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"
# shellcheck disable=SC2086
docker exec $DOKKU_RUN_OPTS $CID /bin/sh -c "ps auxwww"

View File

@@ -1,13 +1,14 @@
#!/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"
ps_restore_cmd() {
local desc="starts all apps with DOKKU_APP_RESTORE not set to 0 via command line"
local cmd="ps:restore"
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
echo "Restoring app $app ..."
ps_start "$app"

View File

@@ -1,40 +1,8 @@
#!/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
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
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)
cat<<EOF
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"
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() {
local desc="checks if path exists"
local -r passed_path=$1
local -r phase_file_path=$2
[[ -r "$phase_file_path" ]] && grep -qe "^-v $passed_path" "$phase_file_path"
}
get_bind_mounts() {
local desc="strips docker options and prints mounts"
local -r phase_file_path=$1
[[ -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 cmd="tags:destroy"
[[ -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"
case "$IMAGE_TAG" in

View File

@@ -3,7 +3,8 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
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"
# Don't trigger tar build if there is no tarball.

View File

@@ -12,7 +12,7 @@ tar_build_locked_cmd() {
# clean up after ourselves
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
chmod 755 "$TMP_WORK_DIR"

View File

@@ -24,7 +24,10 @@ succeeded() {
TMP=$(mktemp -d -t "$TARGET.XXXXX")
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 config user.email "robot@example.com"
git config user.name "Test Robot"