set pipefail on pre/post deploy tasks. fix pre/post deploy support for dockerfile apps. closes #2062

This commit is contained in:
Michael Hobbs
2016-04-01 13:47:22 -07:00
parent 9da47d84e0
commit 6caed369d7
7 changed files with 102 additions and 17 deletions

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/config/functions"
get_phase_script() {
declare desc="extracts app.json from app image and returns the appropriate json key/value"
@@ -26,29 +27,50 @@ execute_script() {
local SCRIPT_CMD=$(get_phase_script "$IMAGE" "$PHASE_SCRIPT_KEY" 2>/dev/null)
if [[ -n "$SCRIPT_CMD" ]];then
dokku_log_info1 "Running '$SCRIPT_CMD' in app container"
local COMMAND="export HOME=/app ; "
local COMMAND+=" cd \$HOME ; "
local COMMAND+=" for file in /app/.profile.d/*; do source \$file; done ; "
local COMMAND+=" echo restoring installation cache... ; "
local COMMAND+=" rm -rf /tmp/cache || true ; "
local COMMAND+=" ln -sf /cache /tmp/cache || true ; "
local COMMAND+=" $SCRIPT_CMD ; RC=\$? ;"
local COMMAND+=" echo removing installation cache... ; "
local COMMAND+=" rm -f /tmp/cache || true ; "
local COMMAND+=" exit \$RC "
local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
local COMMAND
COMMAND="set -eo pipefail; [[ \$DOKKU_TRACE ]] && set -x ; "
COMMAND+=" if [[ -d '/app' ]]; then "
COMMAND+=" export HOME=/app ; "
COMMAND+=" cd \$HOME ; "
COMMAND+=" fi ; "
COMMAND+=" if [[ -d '/app/.profile.d' ]]; then "
COMMAND+=" for file in /app/.profile.d/*; do source \$file; done ; "
COMMAND+=" fi ; "
COMMAND+=" if [[ -d '/cache' ]]; then "
COMMAND+=" echo restoring installation cache... ; "
COMMAND+=" rm -rf /tmp/cache ; "
COMMAND+=" ln -sf /cache /tmp/cache ; "
COMMAND+=" fi ; "
COMMAND+=" $SCRIPT_CMD ;"
COMMAND+=" if [[ -d '/cache' ]]; then "
COMMAND+=" echo removing installation cache... ; "
COMMAND+=" rm -f /tmp/cache ; "
COMMAND+=" fi "
local DOCKER_ARGS_RESTART_RE="(.*)--restart=.+([\s,$])"
local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
local DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP")
# strip --restart args from DOCKER_ARGS
local DOCKER_ARGS=$(sed -e "s/--restart=[[:graph:]]\+[[:blank:]]\?//g" <<< "$DOCKER_ARGS")
# shellcheck disable=SC2086
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"; exit 1)
dokku_container_log_verbose_quiet "$id"
if [[ "$PHASE_SCRIPT_KEY" != "postdeploy" ]];then
docker commit "$id" "$IMAGE" > /dev/null
local id=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" -e DOKKU_TRACE="$DOKKU_TRACE" --label=dokku_phase_script="${PHASE_SCRIPT_KEY}" -d -v "$CACHE_DIR:/cache" $DOCKER_ARGS "$IMAGE" /bin/bash -c "$COMMAND")
if test "$(docker wait "$id")" -eq 0; then
dokku_container_log_verbose_quiet "$id"
if [[ "$PHASE_SCRIPT_KEY" != "postdeploy" ]];then
if ! is_image_herokuish_based "$IMAGE"; then
local DOKKU_DOCKERFILE_ENTRYPOINT=$(config_get "$APP" DOKKU_DOCKERFILE_ENTRYPOINT)
local DOKKU_DOCKERFILE_CMD=$(config_get "$APP" DOKKU_DOCKERFILE_CMD)
[[ -n "$DOKKU_DOCKERFILE_ENTRYPOINT" ]] && local DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG="--change='$DOKKU_DOCKERFILE_ENTRYPOINT'"
[[ -n "$DOKKU_DOCKERFILE_CMD" ]] && local DOCKER_COMMIT_CMD_CHANGE_ARG="--change='$DOKKU_DOCKERFILE_CMD'"
local DOCKER_COMMIT_ARGS="$DOCKER_COMMIT_ENTRYPOINT_CHANGE_ARG $DOCKER_COMMIT_CMD_CHANGE_ARG"
fi
# shellcheck disable=SC2086
eval docker commit $DOCKER_COMMIT_ARGS "$id" "$IMAGE" > /dev/null
fi
else
dokku_container_log_verbose_quiet "$id"
dokku_log_fail "execution of '$SCRIPT_CMD' failed!"
fi
fi
}

View File

@@ -37,6 +37,12 @@ dokku_build_cmd() {
# extract first port from Dockerfile
local DOCKERFILE_PORTS=$(get_dockerfile_exposed_ports Dockerfile)
[[ -n "$DOCKERFILE_PORTS" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_PORTS="$DOCKERFILE_PORTS"
# extract ENTRYPOINT/CMD from Dockerfile
local DOCKERFILE_ENTRYPOINT=$(extract_directive_from_dockerfile Dockerfile ENTRYPOINT)
[[ -n "$DOCKERFILE_ENTRYPOINT" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_ENTRYPOINT="$DOCKERFILE_ENTRYPOINT"
local DOCKERFILE_CMD=$(extract_directive_from_dockerfile Dockerfile CMD)
[[ -n "$DOCKERFILE_CMD" ]] && config_set --no-restart "$APP" DOKKU_DOCKERFILE_CMD="$DOCKERFILE_CMD"
plugn trigger pre-build-dockerfile "$APP"
[[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache"

View File

@@ -571,6 +571,13 @@ get_dockerfile_exposed_ports() {
echo "$DOCKERFILE_PORTS"
}
extract_directive_from_dockerfile() {
declare desc="return requested directive from passed file path"
local FILE_PATH="$1"; local SEARCH_STRING="$2"
local FOUND_LINE=$(egrep "^${SEARCH_STRING} " "$FILE_PATH" | tail -n1) || true
echo "$FOUND_LINE"
}
get_app_raw_tcp_ports() {
declare desc="extracts raw tcp port numbers from DOCKERFILE_PORTS config variable"
source "$PLUGIN_AVAILABLE_PATH/config/functions"

View File

@@ -1 +1,5 @@
WAIT=2 # wait 2 seconds
TIMEOUT=5 # set timeout to 5 seconds
ATTEMPTS=2 # try 2 times
/ Hello World!

View File

@@ -1 +1,5 @@
WAIT=2 # wait 2 seconds
TIMEOUT=5 # set timeout to 5 seconds
ATTEMPTS=2 # try 2 times
/ nodejs/express

View File

@@ -1 +1,5 @@
WAIT=2 # wait 2 seconds
TIMEOUT=5 # set timeout to 5 seconds
ATTEMPTS=2 # try 2 times
/ Hello World!

View File

@@ -0,0 +1,38 @@
{
"name": "Sample node.js express app",
"description": "Used in dokku's test suite",
"keywords": [
"nodejs",
"express",
"testing"
],
"website": "http://dokku.viewdocs.io/dokku/",
"repository": "https://github.com/dokku/dokku",
"logo": "https://raw.githubusercontent.com/dokku/dokku/master/docs/assets/dokku.png",
"scripts": {
"dokku": {
"predeploy": "touch /app/predeploy.test",
"postdeploy": "touch /app/postdeploy.test"
}
},
"env": {
"SECRET_TOKEN": {
"description": "A secret key for verifying the integrity of signed cookies.",
"value": "secret"
},
"WEB_CONCURRENCY": {
"description": "The number of processes to run.",
"generator": "echo 5"
}
},
"image": "gliderlabs/herokuish",
"addons": [
"dokku-postgres",
"dokku-redis"
],
"buildpacks": [
{
"url": "https://github.com/heroku/heroku-buildpack-nodejs"
}
]
}