move standard commands into subcommands

This commit is contained in:
Michael Hobbs
2016-03-03 14:02:04 -08:00
parent aa2415eeb8
commit 3aa8bbd629
15 changed files with 448 additions and 395 deletions

16
dokku
View File

@@ -100,17 +100,29 @@ execute_dokku_cmd() {
nginx|nginx:*)
local PLUGIN_NAME=${PLUGIN_NAME/nginx/nginx-vhosts}
;;
receive|deploy|build|release)
local PLUGIN_NAME="00_dokku-standard"
;;
trace|delete|ls|run|cleanup)
local PLUGIN_NAME="00_dokku-standard"
;;
url|urls|report|version)
local PLUGIN_NAME="00_dokku-standard"
;;
esac
if [[ "$(readlink -f "$PLUGIN_ENABLED_PATH/${PLUGIN_NAME%%:*}")" == *core-plugins* ]]; then
if [[ "$(readlink -f "$PLUGIN_ENABLED_PATH/${PLUGIN_NAME%%:*}")" == *core-plugins* ]] ; then
[[ ${argv[0]} == "$PLUGIN_CMD" ]] && shift 1
[[ ! -z $DOKKU_APP_NAME ]] && set -- "$DOKKU_APP_NAME" "$@"
set -- "$PLUGIN_NAME" "$@"
set -- "$PLUGIN_CMD" "$@"
fi
if [[ -x $PLUGIN_ENABLED_PATH/$PLUGIN_NAME/subcommands/default ]]; then
"$PLUGIN_ENABLED_PATH/$PLUGIN_NAME/subcommands/default" "$@"
implemented=1
elif [[ -x $PLUGIN_ENABLED_PATH/$PLUGIN_NAME/subcommands/$PLUGIN_CMD ]]; then
"$PLUGIN_ENABLED_PATH/$PLUGIN_NAME/subcommands/$PLUGIN_CMD" "$@"
implemented=1
elif [[ -x $PLUGIN_ENABLED_PATH/${PLUGIN_NAME%%:*}/subcommands/${1#*:} ]]; then
"$PLUGIN_ENABLED_PATH/${PLUGIN_NAME%%:*}/subcommands/${1#*:}" "$@"
implemented=1

View File

@@ -1,400 +1,8 @@
#!/usr/bin/env bash
[[ " receive deploy build release trace delete ls run cleanup url urls report version help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
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"
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..."
docker_cleanup
else
dokku_log_info1 "DOKKU_SKIP_CLEANUP set. Skipping dokku cleanup"
fi
dokku_log_info1 "Building $APP from $IMAGE_SOURCE_TYPE..."
dokku build "$APP" "$IMAGE_SOURCE_TYPE" "$TMP_WORK_DIR"
release_and_deploy "$APP"
}
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"
plugn trigger pre-deploy "$APP" "$IMAGE_TAG"
is_image_herokuish_based "$IMAGE" && local DOKKU_HEROKUISH=true
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
local oldids=$(get_app_container_ids "$APP")
local DOKKU_DEFAULT_DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG")
local DOKKU_IS_APP_PROXY_ENABLED="$(is_app_proxy_enabled "$APP")"
local line
while read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^#.* ]] && continue
local TRIM=${line%#*}
local PROC_TYPE=${TRIM%%=*}
local PROC_COUNT=${TRIM#*=}
local CONTAINER_INDEX=1
while [[ $CONTAINER_INDEX -le $PROC_COUNT ]]; do
local id=""; local port=""; local ipaddr=""
local DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_TYPE.$CONTAINER_INDEX"
local DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_TYPE.$CONTAINER_INDEX"
local DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_TYPE.$CONTAINER_INDEX"
# start the app
local DOCKER_ARGS="$DOKKU_DEFAULT_DOCKER_ARGS"
local DOCKER_ARGS+=" -e DYNO='$PROC_TYPE.$CONTAINER_INDEX' "
[[ "$DOKKU_TRACE" ]] && local DOCKER_ARGS+=" -e TRACE=true "
[[ -n "$DOKKU_HEROKUISH" ]] && local START_CMD="/start $PROC_TYPE"
if [[ -z "$DOKKU_HEROKUISH" ]]; then
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
if [[ "$PROC_TYPE" == "web" ]]; then
if [[ -z "${DOKKU_DOCKERFILE_PORTS[*]}" ]]; then
local port=5000
local DOKKU_DOCKER_PORT_ARGS+="-p $port"
else
local p
for p in ${DOKKU_DOCKERFILE_PORTS[*]};do
if [[ ! "$p" =~ .*udp.* ]]; then
# set port to first non-udp port
local p=${p//\/tcp}
local port=${port:="$p"}
fi
local DOKKU_DOCKER_PORT_ARGS+=" -p $p "
done
fi
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")
# Docker < 1.9 compatibility
if [[ -z $ipaddr ]]; then
local ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$id")
fi
else
# shellcheck disable=SC2086
local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD)
local port=$(docker port "$id" "$port" | sed 's/[0-9.]*://')
local ipaddr=127.0.0.1
fi
else
# shellcheck disable=SC2086
local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOCKER_ARGS $IMAGE $START_CMD)
fi
# if we can't post-deploy successfully, kill new container
kill_new() {
local desc="wrapper function to kill newly started app container"
local id="$1"
docker inspect "$id" &> /dev/null && docker stop "$id" > /dev/null && docker kill "$id" &> /dev/null
trap - INT TERM EXIT
kill -9 $$
}
# run checks first, then post-deploy hooks, which switches Nginx traffic
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 $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
fi
# now using the new container
[[ -n "$id" ]] && echo "$id" > "$DOKKU_CONTAINER_ID_FILE"
[[ -n "$ipaddr" ]] && echo "$ipaddr" > "$DOKKU_IP_FILE"
[[ -n "$port" ]] && echo "$port" > "$DOKKU_PORT_FILE"
# cleanup pre-migration files
rm -f "$DOKKU_ROOT/$APP/CONTAINER" "$DOKKU_ROOT/$APP/IP" "$DOKKU_ROOT/$APP/PORT"
local CONTAINER_INDEX=$(( CONTAINER_INDEX + 1 ))
done
# cleanup when we scale down
if [[ "$PROC_COUNT" == 0 ]]; then
local CONTAINER_IDX_OFFSET=0
else
local CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1))
fi
local container_state_filetype
for container_state_filetype in CONTAINER IP PORT; do
cd "$DOKKU_ROOT/$APP"
find . -maxdepth 1 -name "$container_state_filetype.$PROC_TYPE.*" -printf "%f\n" | sort -t . -k 3 -n | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f
done
done < "$DOKKU_SCALE_FILE"
dokku_log_info1 "Running post-deploy"
plugn trigger post-deploy "$APP" "$port" "$ipaddr" "$IMAGE_TAG"
# kill the old container
if [[ -n "$oldids" ]]; then
if [[ -z "$DOKKU_WAIT_TO_RETIRE" ]]; then
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
# Let the old container finish processing requests, before terminating it
local WAIT="${DOKKU_WAIT_TO_RETIRE:-60}"
dokku_log_info1 "Shutting down old containers in $WAIT seconds"
local oldid
for oldid in $oldids; do
dokku_log_info2 "$oldid"
done
(
exec >/dev/null 2>/dev/null </dev/null
trap '' INT HUP
sleep "$WAIT"
for oldid in $oldids; do
# Attempt to stop, if that fails, then force a kill as docker seems
# to not send SIGKILL as the docs would indicate. If that fails, move
# on to the next.
docker stop "$oldid" \
|| docker kill "$oldid" \
|| plugn trigger retire-container-failed "$APP" # plugin trigger for event logging
done
) & disown -a
# Use trap since disown/nohup don't seem to keep child alive
# Give child process just enough time to set the traps
sleep 0.1
fi
}
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"
local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
eval "$(config_export app "$APP")"
pushd "$TMP_WORK_DIR" &> /dev/null
case "$IMAGE_SOURCE_TYPE" in
herokuish)
local id=$(tar -c . | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app")
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
[[ -d $CACHE_DIR ]] || mkdir "$CACHE_DIR"
plugn trigger pre-build-buildpack "$APP"
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE")
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
# shellcheck disable=SC2086
local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -v $CACHE_DIR:/cache -e CACHE_PATH=/cache $DOCKER_ARGS $IMAGE /build)
docker attach "$id"
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
plugn trigger post-build-buildpack "$APP"
;;
dockerfile)
# 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"
plugn trigger pre-build-dockerfile "$APP"
[[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache"
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE")
# shellcheck disable=SC2086
docker build $DOCKER_ARGS $DOKKU_DOCKER_BUILD_OPTS -t $IMAGE .
plugn trigger post-build-dockerfile "$APP"
;;
*)
dokku_log_fail "Building image source type $IMAGE_SOURCE_TYPE not supported!"
;;
esac
}
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"
case "$IMAGE_SOURCE_TYPE" in
herokuish)
plugn trigger pre-release-buildpack "$APP" "$IMAGE_TAG"
if [[ -n $(config_export global) ]]; then
local id=$(config_export global | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh")
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
fi
if [[ -n $(config_export app "$APP") ]]; then
local id=$(config_export app "$APP" | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh")
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
fi
plugn trigger post-release-buildpack "$APP" "$IMAGE_TAG"
;;
dockerfile)
# buildstep plugins don't necessarily make sense for dockerfiles. call the new breed!!!
plugn trigger pre-release-dockerfile "$APP" "$IMAGE_TAG"
plugn trigger post-release-dockerfile "$APP" "$IMAGE_TAG"
;;
*)
dokku_log_fail "Releasing image source type $IMAGE_SOURCE_TYPE not supported!"
;;
esac
}
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]"
}
if [[ "$2" == "on" ]]; then
echo "Enabling dokku trace"
echo "export DOKKU_TRACE=1" > "$DOKKU_ROOT/.dokkurc/DOKKU_TRACE"
fi
if [[ "$2" == "off" ]]; then
echo "Disabling dokku trace"
rm -f "$DOKKU_ROOT/.dokkurc/DOKKU_TRACE"
fi
}
dokku_ls() {
local desc="lists installed apps with status"
local cmd="ls"
local installed_apps=$(dokku_apps)
local dokku_app
dokku_col_log_info1_quiet "App Name" "Container Type" "Container Id" "Status"
for dokku_app in $installed_apps; do
local APP=$(basename "$dokku_app")
local DOKKU_APP_CIDS=$(get_app_container_ids "$APP")
local DOCKER_RUNNING_CONTAINERS=$(docker ps -q --no-trunc)
if [[ -n $DOKKU_APP_CIDS ]]; then
local DOKKU_APP_CID
for DOKKU_APP_CID in $DOKKU_APP_CIDS; do
local DOKKU_APP_CONTAINER_STATUS="stopped"
[[ $DOCKER_RUNNING_CONTAINERS =~ $DOKKU_APP_CID ]] && local DOKKU_APP_CONTAINER_STATUS="running"
local DOKKU_APP_CONTAINER_TYPE=$(grep -l "$DOKKU_APP_CID" "$DOKKU_ROOT/$APP"/CONTAINER.* | awk -F '/' '{ print $5 }' | awk -F '.' '{ print $2 }')
dokku_col_log_msg "$APP" "$DOKKU_APP_CONTAINER_TYPE" "${DOKKU_APP_CID:0:12}" "$DOKKU_APP_CONTAINER_STATUS"
done
else
dokku_col_log_msg "$APP" "NOT_DEPLOYED" "NOT_DEPLOYED" "NOT_DEPLOYED"
fi
done
}
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"
shift 2
if [[ -z "$DOKKU_RM_CONTAINER" ]]; then
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
local DOCKER_ARGS=$(: | plugn trigger docker-args-run "$APP" "$IMAGE_TAG")
[[ "$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" && local EXEC_CMD="/exec"
# shellcheck disable=SC2086
docker run $DOKKU_GLOBAL_RUN_ARGS $DOKKU_RUN_OPTS $DOCKER_ARGS $IMAGE $EXEC_CMD "$@"
}
case "$1" in
receive)
dokku_receive "$@"
;;
deploy)
dokku_deploy "$@"
;;
build)
dokku_build "$@"
;;
release)
dokku_release "$@"
;;
trace)
dokku_trace "$@"
;;
delete)
dokku apps:destroy "$2"
;;
ls)
dokku_ls "$@"
;;
run)
dokku_run "$@"
;;
cleanup)
docker_cleanup
;;
url | urls)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
get_app_urls "$@"
;;
report)
dokku_log_info1 "uname: $(uname -a)"
dokku_log_info1 "memory: "
free -m
dokku_log_info1 "docker version: "
docker version
dokku_log_info1 "docker daemon info: "
docker -D info
dokku_log_info1 "sigil version: $(sigil -v)"
dokku_log_info1 "herokuish version: "
docker run --rm -ti gliderlabs/herokuish:latest herokuish version
dokku_log_info1 "dokku version: $(dokku version)"
dokku_log_info1 "dokku plugins: "
dokku plugin
;;
version)
cat "$DOKKU_ROOT/VERSION" || dokku_log_fail "Unable to determine dokku's version"
;;
help)
cat<<EOF
ls, Pretty listing of deployed applications and containers

View File

@@ -0,0 +1,56 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
dokku_build_cmd() {
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"
local CACHE_DIR="$DOKKU_ROOT/$APP/cache"
eval "$(config_export app "$APP")"
pushd "$TMP_WORK_DIR" &> /dev/null
case "$IMAGE_SOURCE_TYPE" in
herokuish)
local id=$(tar -c . | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$DOKKU_IMAGE" /bin/bash -c "mkdir -p /app && tar -xC /app")
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
[[ -d $CACHE_DIR ]] || mkdir "$CACHE_DIR"
plugn trigger pre-build-buildpack "$APP"
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE")
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
# shellcheck disable=SC2086
local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -v $CACHE_DIR:/cache -e CACHE_PATH=/cache $DOCKER_ARGS $IMAGE /build)
docker attach "$id"
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
plugn trigger post-build-buildpack "$APP"
;;
dockerfile)
# 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"
plugn trigger pre-build-dockerfile "$APP"
[[ "$DOKKU_DOCKERFILE_CACHE_BUILD" == "false" ]] && DOKKU_DOCKER_BUILD_OPTS="$DOKKU_DOCKER_BUILD_OPTS --no-cache"
local DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE")
# shellcheck disable=SC2086
docker build $DOCKER_ARGS $DOKKU_DOCKER_BUILD_OPTS -t $IMAGE .
plugn trigger post-build-dockerfile "$APP"
;;
*)
dokku_log_fail "Building image source type $IMAGE_SOURCE_TYPE not supported!"
;;
esac
}
dokku_build_cmd "$@"

View File

@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
dokku_cleanup_cmd(){
local desc="cleans up old deployment cruft"
local cmd="cleanup"
docker_cleanup
}
dokku_cleanup_cmd "$@"

View File

@@ -0,0 +1,166 @@
#!/usr/bin/env bash
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"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
dokku_deploy_cmd() {
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"
plugn trigger pre-deploy "$APP" "$IMAGE_TAG"
is_image_herokuish_based "$IMAGE" && local DOKKU_HEROKUISH=true
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
local oldids=$(get_app_container_ids "$APP")
local DOKKU_DEFAULT_DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG")
local DOKKU_IS_APP_PROXY_ENABLED="$(is_app_proxy_enabled "$APP")"
local line
while read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^#.* ]] && continue
local TRIM=${line%#*}
local PROC_TYPE=${TRIM%%=*}
local PROC_COUNT=${TRIM#*=}
local CONTAINER_INDEX=1
while [[ $CONTAINER_INDEX -le $PROC_COUNT ]]; do
local id=""; local port=""; local ipaddr=""
local DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_TYPE.$CONTAINER_INDEX"
local DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_TYPE.$CONTAINER_INDEX"
local DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_TYPE.$CONTAINER_INDEX"
# start the app
local DOCKER_ARGS="$DOKKU_DEFAULT_DOCKER_ARGS"
local DOCKER_ARGS+=" -e DYNO='$PROC_TYPE.$CONTAINER_INDEX' "
[[ "$DOKKU_TRACE" ]] && local DOCKER_ARGS+=" -e TRACE=true "
[[ -n "$DOKKU_HEROKUISH" ]] && local START_CMD="/start $PROC_TYPE"
if [[ -z "$DOKKU_HEROKUISH" ]]; then
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
if [[ "$PROC_TYPE" == "web" ]]; then
if [[ -z "${DOKKU_DOCKERFILE_PORTS[*]}" ]]; then
local port=5000
local DOKKU_DOCKER_PORT_ARGS+="-p $port"
else
local p
for p in ${DOKKU_DOCKERFILE_PORTS[*]};do
if [[ ! "$p" =~ .*udp.* ]]; then
# set port to first non-udp port
local p=${p//\/tcp}
local port=${port:="$p"}
fi
local DOKKU_DOCKER_PORT_ARGS+=" -p $p "
done
fi
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")
# Docker < 1.9 compatibility
if [[ -z $ipaddr ]]; then
local ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$id")
fi
else
# shellcheck disable=SC2086
local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD)
local port=$(docker port "$id" "$port" | sed 's/[0-9.]*://')
local ipaddr=127.0.0.1
fi
else
# shellcheck disable=SC2086
local id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOCKER_ARGS $IMAGE $START_CMD)
fi
# if we can't post-deploy successfully, kill new container
kill_new() {
local desc="wrapper function to kill newly started app container"
local id="$1"
docker inspect "$id" &> /dev/null && docker stop "$id" > /dev/null && docker kill "$id" &> /dev/null
trap - INT TERM EXIT
kill -9 $$
}
# run checks first, then post-deploy hooks, which switches Nginx traffic
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 $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
fi
# now using the new container
[[ -n "$id" ]] && echo "$id" > "$DOKKU_CONTAINER_ID_FILE"
[[ -n "$ipaddr" ]] && echo "$ipaddr" > "$DOKKU_IP_FILE"
[[ -n "$port" ]] && echo "$port" > "$DOKKU_PORT_FILE"
# cleanup pre-migration files
rm -f "$DOKKU_ROOT/$APP/CONTAINER" "$DOKKU_ROOT/$APP/IP" "$DOKKU_ROOT/$APP/PORT"
local CONTAINER_INDEX=$(( CONTAINER_INDEX + 1 ))
done
# cleanup when we scale down
if [[ "$PROC_COUNT" == 0 ]]; then
local CONTAINER_IDX_OFFSET=0
else
local CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1))
fi
local container_state_filetype
for container_state_filetype in CONTAINER IP PORT; do
cd "$DOKKU_ROOT/$APP"
find . -maxdepth 1 -name "$container_state_filetype.$PROC_TYPE.*" -printf "%f\n" | sort -t . -k 3 -n | tail -n +$CONTAINER_IDX_OFFSET | xargs rm -f
done
done < "$DOKKU_SCALE_FILE"
dokku_log_info1 "Running post-deploy"
plugn trigger post-deploy "$APP" "$port" "$ipaddr" "$IMAGE_TAG"
# kill the old container
if [[ -n "$oldids" ]]; then
if [[ -z "$DOKKU_WAIT_TO_RETIRE" ]]; then
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
# Let the old container finish processing requests, before terminating it
local WAIT="${DOKKU_WAIT_TO_RETIRE:-60}"
dokku_log_info1 "Shutting down old containers in $WAIT seconds"
local oldid
for oldid in $oldids; do
dokku_log_info2 "$oldid"
done
(
exec >/dev/null 2>/dev/null </dev/null
trap '' INT HUP
sleep "$WAIT"
for oldid in $oldids; do
# Attempt to stop, if that fails, then force a kill as docker seems
# to not send SIGKILL as the docs would indicate. If that fails, move
# on to the next.
docker stop "$oldid" \
|| docker kill "$oldid" \
|| plugn trigger retire-container-failed "$APP" # plugin trigger for event logging
done
) & disown -a
# Use trap since disown/nohup don't seem to keep child alive
# Give child process just enough time to set the traps
sleep 0.1
fi
}
dokku_deploy_cmd "$@"

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
dokku_ls_cmd() {
local desc="lists installed apps with status"
local cmd="ls"
local installed_apps=$(dokku_apps)
local dokku_app
dokku_col_log_info1_quiet "App Name" "Container Type" "Container Id" "Status"
for dokku_app in $installed_apps; do
local APP=$(basename "$dokku_app")
local DOKKU_APP_CIDS=$(get_app_container_ids "$APP")
local DOCKER_RUNNING_CONTAINERS=$(docker ps -q --no-trunc)
if [[ -n $DOKKU_APP_CIDS ]]; then
local DOKKU_APP_CID
for DOKKU_APP_CID in $DOKKU_APP_CIDS; do
local DOKKU_APP_CONTAINER_STATUS="stopped"
[[ $DOCKER_RUNNING_CONTAINERS =~ $DOKKU_APP_CID ]] && local DOKKU_APP_CONTAINER_STATUS="running"
local DOKKU_APP_CONTAINER_TYPE=$(grep -l "$DOKKU_APP_CID" "$DOKKU_ROOT/$APP"/CONTAINER.* | awk -F '/' '{ print $5 }' | awk -F '.' '{ print $2 }')
dokku_col_log_msg "$APP" "$DOKKU_APP_CONTAINER_TYPE" "${DOKKU_APP_CID:0:12}" "$DOKKU_APP_CONTAINER_STATUS"
done
else
dokku_col_log_msg "$APP" "NOT_DEPLOYED" "NOT_DEPLOYED" "NOT_DEPLOYED"
fi
done
}
dokku_ls_cmd "$@"

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
dokku_receive_cmd() {
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..."
docker_cleanup
else
dokku_log_info1 "DOKKU_SKIP_CLEANUP set. Skipping dokku cleanup"
fi
dokku_log_info1 "Building $APP from $IMAGE_SOURCE_TYPE..."
dokku build "$APP" "$IMAGE_SOURCE_TYPE" "$TMP_WORK_DIR"
release_and_deploy "$APP"
}
dokku_receive_cmd "$@"

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
dokku_release_cmd() {
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"
case "$IMAGE_SOURCE_TYPE" in
herokuish)
plugn trigger pre-release-buildpack "$APP" "$IMAGE_TAG"
if [[ -n $(config_export global) ]]; then
local id=$(config_export global | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/00-global-env.sh")
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
fi
if [[ -n $(config_export app "$APP") ]]; then
local id=$(config_export app "$APP" | docker run "$DOKKU_GLOBAL_RUN_ARGS" -i -a stdin "$IMAGE" /bin/bash -c "mkdir -p /app/.profile.d && cat > /app/.profile.d/01-app-env.sh")
test "$(docker wait "$id")" -eq 0
docker commit "$id" "$IMAGE" > /dev/null
fi
plugn trigger post-release-buildpack "$APP" "$IMAGE_TAG"
;;
dockerfile)
# buildstep plugins don't necessarily make sense for dockerfiles. call the new breed!!!
plugn trigger pre-release-dockerfile "$APP" "$IMAGE_TAG"
plugn trigger post-release-dockerfile "$APP" "$IMAGE_TAG"
;;
*)
dokku_log_fail "Releasing image source type $IMAGE_SOURCE_TYPE not supported!"
;;
esac
}
dokku_release_cmd "$@"

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
dokku_report_cmd() {
local desc="reports dokku vitals for troubleshooting"
local cmd="report"
dokku_log_info1 "uname: $(uname -a)"
dokku_log_info1 "memory: "
free -m
dokku_log_info1 "docker version: "
docker version
dokku_log_info1 "docker daemon info: "
docker -D info
dokku_log_info1 "sigil version: $(sigil -v)"
dokku_log_info1 "herokuish version: "
docker run --rm -ti gliderlabs/herokuish:latest herokuish version
dokku_log_info1 "dokku version: $(dokku version)"
dokku_log_info1 "dokku plugins: "
dokku plugin
}
dokku_report_cmd "$@"

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
dokku_run_cmd() {
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"
shift 2
if [[ -z "$DOKKU_RM_CONTAINER" ]]; then
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
local DOCKER_ARGS=$(: | plugn trigger docker-args-run "$APP" "$IMAGE_TAG")
[[ "$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" && local EXEC_CMD="/exec"
# shellcheck disable=SC2086
docker run $DOKKU_GLOBAL_RUN_ARGS $DOKKU_RUN_OPTS $DOCKER_ARGS $IMAGE $EXEC_CMD "$@"
}
dokku_run_cmd "$@"

View File

@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
dokku_trace_cmd() {
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]"
}
if [[ "$2" == "on" ]]; then
echo "Enabling dokku trace"
echo "export DOKKU_TRACE=1" > "$DOKKU_ROOT/.dokkurc/DOKKU_TRACE"
fi
if [[ "$2" == "off" ]]; then
echo "Disabling dokku trace"
rm -f "$DOKKU_ROOT/.dokkurc/DOKKU_TRACE"
fi
}
dokku_trace_cmd "$@"

View File

@@ -0,0 +1 @@
urls

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
dokku_urls_cmd() {
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
local APP="$2"
get_app_urls "$@"
}
dokku_urls_cmd "$@"

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
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"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
dokku_version_cmd() {
local desc="prints dokku version"
local cmd="version"
cat "$DOKKU_ROOT/VERSION" || dokku_log_fail "Unable to determine dokku's version"
}
dokku_version_cmd "$@"

View File

@@ -602,6 +602,7 @@ get_container_ports() {
get_app_urls() {
local desc="print an app's available urls"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
local APP="$2"; verify_app_name "$APP"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")"