Merge pull request #1953 from dokku/1579_mh-commands_refactor

subcommands/bashstyle refactor
This commit is contained in:
Michael Hobbs
2016-03-08 16:35:30 -05:00
148 changed files with 2830 additions and 1956 deletions

1
.gitignore vendored
View File

@@ -1,7 +1,6 @@
.vagrant
.DS_Store
stack.tgz
build
tmp
*.deb
.ruby-version

2
Vagrantfile vendored
View File

@@ -2,6 +2,7 @@
# vi: set ft=ruby :
BOX_NAME = ENV["BOX_NAME"] || "bento/ubuntu-14.04"
BOX_CPUS = ENV["BOX_CPUS"] || "1"
BOX_MEMORY = ENV["BOX_MEMORY"] || "1024"
DOKKU_DOMAIN = ENV["DOKKU_DOMAIN"] || "dokku.me"
DOKKU_IP = ENV["DOKKU_IP"] || "10.0.0.2"
@@ -24,6 +25,7 @@ Vagrant::configure("2") do |config|
# Ubuntu's Raring 64-bit cloud image is set to a 32-bit Ubuntu OS type by
# default in Virtualbox and thus will not boot. Manually override that.
vb.customize ["modifyvm", :id, "--ostype", "Ubuntu_64"]
vb.customize ["modifyvm", :id, "--cpus", BOX_CPUS]
vb.customize ["modifyvm", :id, "--memory", BOX_MEMORY]
end

View File

@@ -54,80 +54,43 @@ if [[ ! -z $DOKKU_HOST ]]; then
echo "This is not a git repository"
fi
if [[ "$appname" != "" ]] && [[ -n "$*" ]]; then
case "$1" in
apps|help|plugins*|ps:restartall|trace|version)
true
;;
apps:destroy)
if [[ -z "$2" ]] || [[ "$2" == "force" ]]; then
donotshift="YES"
fi
;;
*)
donotshift="YES"
;;
esac
fi
if [[ "$1" = "apps:create" ]]; then
if [[ -z "$2" ]]; then
appname=$(random_name)
counter=0
while ssh -p "$DOKKU_PORT" "dokku@$DOKKU_HOST" apps 2>/dev/null| grep -q "$appname"; do
if [[ $counter -ge 100 ]]; then
echo "Error: could not reasonably generate a new app name. try cleaning up some apps..."
ssh -p "$DOKKU_PORT" "dokku@$DOKKU_HOST" apps
exit 1
else
appname=$(random_name)
counter=$((counter+1))
fi
done
else
appname="$2"
fi
if git remote add dokku "dokku@$DOKKU_HOST:$appname"; then
echo "-----> Dokku remote added at $DOKKU_HOST"
echo "-----> Application name is $appname"
else
echo "! Dokku remote not added! Do you already have a dokku remote?"
return
fi
git push dokku master
return $?
fi
if [[ -z "$donotshift" ]]; then
# shellcheck disable=SC2029
ssh -o LogLevel=QUIET -p "$DOKKU_PORT" -t "dokku@$DOKKU_HOST" "$@"
exit $?
fi
if [[ -z "$verb" ]]; then
if [[ ! "$1" =~ --* ]]; then
verb=$1
shift
if [[ "$1" == "$appname" ]]; then
shift
case "$1" in
apps:create)
if [[ -z "$2" ]]; then
appname=$(random_name)
counter=0
while ssh -p "$DOKKU_PORT" "dokku@$DOKKU_HOST" apps 2>/dev/null| grep -q "$appname"; do
if [[ $counter -ge 100 ]]; then
echo "Error: could not reasonably generate a new app name. try cleaning up some apps..."
ssh -p "$DOKKU_PORT" "dokku@$DOKKU_HOST" apps
exit 1
else
appname=$(random_name)
counter=$((counter+1))
fi
done
else
appname="$2"
fi
if git remote add dokku "dokku@$DOKKU_HOST:$appname"; then
echo "-----> Dokku remote added at $DOKKU_HOST"
echo "-----> Application name is $appname"
else
echo "! Dokku remote not added! Do you already have a dokku remote?"
return
fi
git push dokku master
return $?
;;
apps:destroy)
git remote remove dokku
;;
esac
args="$*"
else
long_args="--"
for arg in "$@"; do
if [[ "$arg" =~ --* ]]; then
long_args+=" $arg"
args=("${args[@]/$arg}")
else
verb="$arg"
fi
done
fi
fi
# shellcheck disable=SC2086,SC2029
ssh -o LogLevel=QUIET -p "$DOKKU_PORT" -t "dokku@$DOKKU_HOST" $long_args "$verb" "$appname" "${args[@]}"
[[ -n "$@" ]] && [[ -n "$appname" ]] && app_arg="--app $appname"
# echo "ssh -o LogLevel=QUIET -p $DOKKU_PORT -t dokku@$DOKKU_HOST -- $app_arg $@"
# shellcheck disable=SC2068,SC2086
ssh -o LogLevel=QUIET -p $DOKKU_PORT -t dokku@$DOKKU_HOST -- $app_arg $@
}
if [[ "$0" == "dokku" ]] || [[ "$0" == *dokku_client.sh ]] || [[ "$0" == $(which dokku) ]]; then

View File

@@ -8,28 +8,73 @@ If you create your own plugin:
4. Edit [this page](/dokku/plugins) and add a link to it.
5. Subscribe to the [dokku development blog](http://progrium.com) to be notified about API changes and releases
### Sample plugin
The below plugin is a dummy `dokku hello` plugin. If your plugin exposes commands, this is a good template for your `commands` file:
### Sample plugin
The below plugin is a dummy `dokku hello` plugin.
hello/subcommands/default
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
hello_main_cmd() {
declare desc="prints Hello \$APP"
local cmd="hello"
# Support --app/$DOKKU_APP_NAME flag
# Use the following lines to reorder args into "$cmd $DOKKU_APP_NAME $@""
local argv=("$@")
[[ ${argv[0]} == "$cmd" ]] && shift 1
[[ ! -z $DOKKU_APP_NAME ]] && set -- $DOKKU_APP_NAME $@
set -- $cmd $@
##
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
local APP="$2";
echo "Hello $APP"
}
hello_main_cmd "$@"
```
hello/subcommands/world
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
hello_world_cmd() {
declare desc="prints Hello World"
local cmd="hello:world"
# Support --app/$DOKKU_APP_NAME flag
# Use the following lines to reorder args into "$cmd $DOKKU_APP_NAME $@""
local argv=("$@")
[[ ${argv[0]} == "$cmd" ]] && shift 1
[[ ! -z $DOKKU_APP_NAME ]] && set -- $DOKKU_APP_NAME $@
set -- $cmd $@
##
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
verify_app_name "$2"
local APP="$2";
echo "Hello world"
}
hello_world_cmd "$@"
```
hello/commands
```shell
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
case "$1" in
hello)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG=$(get_running_image_tag $APP); IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
verify_app_name "$APP"
echo "Hello $APP"
;;
hello:world)
echo "Hello world"
;;
help)
cat<<EOF
hello <app>, Says "Hello <app>"

253
dokku
View File

@@ -40,14 +40,14 @@ export DOKKU_CONTAINER_LABEL=dokku
export DOKKU_GLOBAL_RUN_ARGS="--label=$DOKKU_CONTAINER_LABEL"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/checks/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
parse_args "$@"
args=("$@")
if [[ "${args[0]}" =~ ^--.* ]]; then
for arg in "$@"; do
if [[ "$arg" =~ ^--.* ]]; then
if [[ "$arg" == "--app" ]]; then
shift 2
elif [[ "$arg" =~ ^--.* ]]; then
shift 1
else
break
@@ -86,180 +86,76 @@ if ! dokku_auth "$@" ; then
exit 1
fi
case "$1" in
receive)
APP="$2"; IMAGE=$(get_app_image_name "$APP"); IMAGE_SOURCE_TYPE="$3"; 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"
;;
execute_dokku_cmd() {
declare desc="executes dokku sub-commands"
local PLUGIN_NAME="$1"
local PLUGIN_CMD=$PLUGIN_NAME
local implemented=0; local script
local argv=("$@")
deploy)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to deploy"
APP="$2"; IMAGE_TAG="$3"; IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP"
plugn trigger pre-deploy "$APP" "$IMAGE_TAG"
case "$PLUGIN_NAME" in
events|events:*)
local PLUGIN_NAME=${PLUGIN_NAME/events/20_events}
;;
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
is_image_herokuish_based "$IMAGE" && DOKKU_HEROKUISH=true
DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
oldids=$(get_app_container_ids "$APP")
DOKKU_DEFAULT_DOCKER_ARGS=$(: | plugn trigger docker-args-deploy "$APP" "$IMAGE_TAG")
DOKKU_IS_APP_PROXY_ENABLED="$(is_app_proxy_enabled "$APP")"
while read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^#.* ]] && continue
TRIM=${line%#*}
PROC_TYPE=${TRIM%%=*}
PROC_COUNT=${TRIM#*=}
CONTAINER_INDEX=1
while [[ $CONTAINER_INDEX -le $PROC_COUNT ]]; do
id=""; port=""; ipaddr=""
DOKKU_CONTAINER_ID_FILE="$DOKKU_ROOT/$APP/CONTAINER.$PROC_TYPE.$CONTAINER_INDEX"
DOKKU_IP_FILE="$DOKKU_ROOT/$APP/IP.$PROC_TYPE.$CONTAINER_INDEX"
DOKKU_PORT_FILE="$DOKKU_ROOT/$APP/PORT.$PROC_TYPE.$CONTAINER_INDEX"
# start the app
DOCKER_ARGS="$DOKKU_DEFAULT_DOCKER_ARGS"
DOCKER_ARGS+=" -e DYNO='$PROC_TYPE.$CONTAINER_INDEX' "
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
[[ -n "$DOKKU_HEROKUISH" ]] && START_CMD="/start $PROC_TYPE"
if [[ -z "$DOKKU_HEROKUISH" ]]; then
DOKKU_DOCKERFILE_PORTS=($(dokku config:get "$APP" DOKKU_DOCKERFILE_PORTS || true))
DOKKU_DOCKERFILE_PORT=$(dokku config:get "$APP" DOKKU_DOCKERFILE_PORT || true)
DOKKU_DOCKERFILE_START_CMD=$(dokku config:get "$APP" DOKKU_DOCKERFILE_START_CMD || true)
DOKKU_PROCFILE_START_CMD=$(get_cmd_from_procfile "$APP" "$PROC_TYPE")
START_CMD=${DOKKU_DOCKERFILE_START_CMD:-$DOKKU_PROCFILE_START_CMD}
fi
if [[ "$PROC_TYPE" == "web" ]]; then
if [[ -z "${DOKKU_DOCKERFILE_PORTS[*]}" ]]; then
port=5000
DOKKU_DOCKER_PORT_ARGS+="-p $port"
else
for p in ${DOKKU_DOCKERFILE_PORTS[*]};do
if [[ ! "$p" =~ .*udp.* ]]; then
# set port to first non-udp port
p=${p//\/tcp}
port=${port:="$p"}
fi
DOKKU_DOCKER_PORT_ARGS+=" -p $p "
done
fi
if [[ "$DOKKU_IS_APP_PROXY_ENABLED" = "true" ]]; then
# shellcheck disable=SC2086
id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD)
ipaddr=$(docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "$id")
# Docker < 1.9 compatibility
if [[ -z $ipaddr ]]; then
ipaddr=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' "$id")
fi
else
# shellcheck disable=SC2086
id=$(docker run $DOKKU_GLOBAL_RUN_ARGS -d $DOKKU_DOCKER_PORT_ARGS -e PORT=$port $DOCKER_ARGS $IMAGE $START_CMD)
port=$(docker port "$id" "$port" | sed 's/[0-9.]*://')
ipaddr=127.0.0.1
fi
else
# shellcheck disable=SC2086
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() {
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 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"
CONTAINER_INDEX=$(( CONTAINER_INDEX + 1 ))
done
# cleanup when we scale down
if [[ "$PROC_COUNT" == 0 ]]; then
CONTAINER_IDX_OFFSET=0
if [[ "$(readlink -f "$PLUGIN_ENABLED_PATH/${PLUGIN_NAME%%:*}")" == *core-plugins* ]] ; then
[[ ${argv[0]} == "$PLUGIN_CMD" ]] && shift 1
if [[ ! -z $DOKKU_APP_NAME ]]; then
if [[ "$PLUGIN_CMD" == config* ]] && [[ ${argv[1]} == "--no-restart" ]]; then
shift 1
set -- "--no-restart" "$DOKKU_APP_NAME" "$@"
else
CONTAINER_IDX_OFFSET=$((PROC_COUNT + 1))
set -- "$DOKKU_APP_NAME" "$@"
fi
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
DOKKU_APP_DOKKU_WAIT_TO_RETIRE=$(dokku config:get "$APP" DOKKU_WAIT_TO_RETIRE || true)
DOKKU_GLOBAL_DOKKU_WAIT_TO_RETIRE=$(dokku config:get --global DOKKU_WAIT_TO_RETIRE || true)
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
WAIT="${DOKKU_WAIT_TO_RETIRE:-60}"
dokku_log_info1 "Shutting down old containers in $WAIT seconds"
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
;;
set -- "$PLUGIN_CMD" "$@"
fi
cleanup)
docker_cleanup
;;
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
fi
# DEPRECATED as of v0.3.14
deploy:all)
echo "*DEPRECATED* in v0.3.14: deploy:all will be removed in future versions"
dokku ps:restartall
;;
if [[ $implemented -eq 0 ]];then
for script in $PLUGIN_ENABLED_PATH/*/commands; do
set +e; $script "$@" ; exit_code=$? ; set -e
if [[ "$exit_code" -eq "$DOKKU_NOT_IMPLEMENTED_EXIT" ]]; then
continue
fi
implemented=1
if [[ "$exit_code" -ne "$DOKKU_VALID_EXIT" ]]; then
exit $exit_code
fi
done
fi
if [[ "$implemented" -eq 0 ]]; then
dokku_log_warn "\`$*\` is not a dokku command."
dokku_log_warn "See \`dokku help\` for a list of available commands."
exit 1
fi
}
case "$1" in
help|'')
echo "Usage: dokku [--quiet|--trace|--rm-container|--rm|--force] COMMAND <app> [command-specific-options]"
echo ""
@@ -271,24 +167,7 @@ EOF
;;
*)
implemented=0
for script in $PLUGIN_ENABLED_PATH/*/commands; do
set +e; $script "$@" ; exit_code=$? ; set -e
if [[ "$exit_code" -eq "$DOKKU_NOT_IMPLEMENTED_EXIT" ]]; then
continue
fi
implemented=1
if [[ "$exit_code" -ne "$DOKKU_VALID_EXIT" ]]; then
exit $exit_code
fi
done
if [[ "$implemented" -eq 0 ]]; then
dokku_log_warn "\`$*\` is not a dokku command."
dokku_log_warn "See \`dokku help\` for a list of available commands."
exit 1
fi
execute_dokku_cmd "$@"
;;
esac

View File

@@ -1,182 +1,8 @@
#!/usr/bin/env bash
[[ " build release trace delete ls run 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/config/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/proxy/functions"
case "$1" in
build)
APP="$2"; IMAGE_SOURCE_TYPE="$3"; TMP_WORK_DIR="$4"; IMAGE=$(get_app_image_name "$APP")
verify_app_name "$APP"
CACHE_DIR="$DOKKU_ROOT/$APP/cache"
eval "$(config_export app "$APP")"
pushd "$TMP_WORK_DIR" &> /dev/null
case "$IMAGE_SOURCE_TYPE" in
herokuish)
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"
DOCKER_ARGS=$(: | plugn trigger docker-args-build "$APP" "$IMAGE_SOURCE_TYPE")
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
# shellcheck disable=SC2086
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
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"
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
;;
release)
APP="$2"; IMAGE_SOURCE_TYPE="$3"; IMAGE_TAG="$4"; 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
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
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
;;
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
;;
delete)
dokku apps:destroy "$2"
;;
ls)
installed_apps=$(dokku_apps)
dokku_col_log_info1_quiet "App Name" "Container Type" "Container Id" "Status"
for dokku_app in $installed_apps; do
APP=$(basename "$dokku_app")
DOKKU_APP_CIDS=$(get_app_container_ids "$APP")
DOCKER_RUNNING_CONTAINERS=$(docker ps -q --no-trunc)
if [[ -n $DOKKU_APP_CIDS ]]; then
for DOKKU_APP_CID in $DOKKU_APP_CIDS; do
DOKKU_APP_CONTAINER_STATUS="stopped"
[[ $DOCKER_RUNNING_CONTAINERS =~ $DOKKU_APP_CID ]] && DOKKU_APP_CONTAINER_STATUS="running"
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
;;
run)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; IMAGE_TAG=$(get_running_image_tag "$APP"); IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP"
shift 2
if [[ -z "$DOKKU_RM_CONTAINER" ]]; then
DOKKU_APP_RM_CONTAINER=$(dokku config:get "$APP" DOKKU_RM_CONTAINER || true)
DOKKU_GLOBAL_RM_CONTAINER=$(dokku config:get --global DOKKU_RM_CONTAINER || true)
DOKKU_RM_CONTAINER=${DOKKU_APP_RM_CONTAINER:="$DOKKU_GLOBAL_RM_CONTAINER"}
fi
DOCKER_ARGS=$(: | plugn trigger docker-args-run "$APP" "$IMAGE_TAG")
[[ "$DOKKU_TRACE" ]] && DOCKER_ARGS+=" -e TRACE=true "
[[ "$DOKKU_RM_CONTAINER" ]] && DOKKU_RUN_OPTS="--rm"
has_tty && DOKKU_RUN_OPTS+=" -i -t"
is_image_herokuish_based "$IMAGE" && EXEC_CMD="/exec"
# shellcheck disable=SC2086
docker run $DOKKU_GLOBAL_RUN_ARGS $DOKKU_RUN_OPTS $DOCKER_ARGS $IMAGE $EXEC_CMD "$@"
;;
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

@@ -1,26 +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 PHASE_SCRIPT_KEY="$1"
declare desc="extracts app.json from app image and returns the appropriate json key/value"
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
@@ -34,7 +21,9 @@ get_phase_script() {
}
execute_script() {
local SCRIPT_CMD=$(get_phase_script "$PHASE_SCRIPT_KEY")
declare desc="executes appropriate phase script key from app.json"
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 ; "
@@ -47,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
@@ -56,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() {
declare 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

@@ -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() {
declare 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(){
declare 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() {
declare 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() {
declare 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() {
declare 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() {
declare 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() {
declare 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() {
declare 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() {
declare 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() {
declare 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() {
declare 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

@@ -1,43 +1,8 @@
#!/usr/bin/env bash
[[ " events events:on events:off events:list help events:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help events:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
case "$1" in
events)
if [[ -f $DOKKU_EVENTS_LOGFILE ]]; then
if [[ $2 == "-t" ]]; then
tail -F "$DOKKU_EVENTS_LOGFILE"
else
tail -n 100 "$DOKKU_EVENTS_LOGFILE"
fi
fi
;;
events:on)
echo "Enabling dokku events logger"
[[ -d $DOKKU_ROOT/.dokkurc ]] || mkdir -p "$DOKKU_ROOT/.dokkurc"
echo "export DOKKU_EVENTS=1" > "$DOKKU_ROOT/.dokkurc/DOKKU_EVENTS"
;;
events:off)
echo "Disabling dokku events logger"
rm -f "$DOKKU_ROOT/.dokkurc/DOKKU_EVENTS"
;;
events:list)
PLUGIN_DIR="$(dirname "$0")/"
if [[ "$DOKKU_EVENTS" ]]; then
logged="$(find "$PLUGIN_DIR" -type l -printf '%f ' | sort)"
dokku_col_log_info2_quiet "Events currently logged"
for hook in $logged; do
dokku_col_log_msg "$hook"
done
else
dokku_log_warn "Events logger disabled"
fi
;;
help | events:help)
cat<<EOF
events [-t], Show the last events (-t follows)

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
events_main_cmd() {
declare desc="shows contents of dokku events log"
local cmd="events"
if [[ -f $DOKKU_EVENTS_LOGFILE ]]; then
if [[ $2 == "-t" ]]; then
tail -F "$DOKKU_EVENTS_LOGFILE"
else
tail -n 100 "$DOKKU_EVENTS_LOGFILE"
fi
fi
}
events_main_cmd "$@"

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
events_list_cmd() {
declare desc="lists enabled events"
local cmd="events:list"
local PLUGIN_DIR="$(dirname "$0")/.."
if [[ "$DOKKU_EVENTS" ]]; then
local logged="$(find "$PLUGIN_DIR" -type l -printf '%f ' | sort)"
dokku_col_log_info2_quiet "Events currently logged"
local hook
for hook in $logged; do
dokku_col_log_msg "$hook"
done
else
dokku_log_warn "Events logger disabled"
fi
}
events_list_cmd "$@"

View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
events_off_cmd() {
declare desc="disables dokku events logger"
local cmd="events:off"
echo "Disabling dokku events logger"
rm -f "$DOKKU_ROOT/.dokkurc/DOKKU_EVENTS"
}
events_off_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"
events_on_cmd() {
declare desc="enables dokku events logger"
local cmd="events:on"
echo "Enabling dokku events logger"
[[ -d $DOKKU_ROOT/.dokkurc ]] || mkdir -p "$DOKKU_ROOT/.dokkurc"
echo "export DOKKU_EVENTS=1" > "$DOKKU_ROOT/.dokkurc/DOKKU_EVENTS"
}
events_on_cmd "$@"

View File

@@ -1,73 +1,8 @@
#!/usr/bin/env bash
[[ " apps apps:create apps:rename apps:destroy help apps:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help apps: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/apps/functions"
case "$1" in
apps)
dokku_log_info2_quiet "My Apps"
for app in $(dokku_apps); do
echo "$app"
done
;;
apps:create)
apps_create "$2"
;;
apps:rename)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
[[ -d "$DOKKU_ROOT/$3" ]] && dokku_log_fail "Name is already taken"
OLD_APP="$2"
NEW_APP="$3"
mkdir -p "$DOKKU_ROOT/$NEW_APP"
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
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"
plugn trigger post-app-rename "$OLD_APP" "$NEW_APP"
echo "Renaming $OLD_APP to $NEW_APP... done"
;;
apps:destroy)
[[ -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" ]] && DOKKU_APPS_FORCE_DELETE=1
APP="$2"; 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"
DOKKU_APP_CIDS=$(get_app_container_ids "$APP")
if [[ -n $DOKKU_APP_CIDS ]]; then
for ID in $DOKKU_APP_CIDS; do
docker stop "$ID" > /dev/null || true
docker rm "$ID" > /dev/null || true
done
fi
plugn trigger post-delete "$APP" "$IMAGE_TAG"
;;
help | apps:help)
cat<<EOF
apps, List your apps

View File

@@ -3,6 +3,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
apps_create() {
declare desc="verifies app name and creates an app"
[[ -z $1 ]] && dokku_log_fail "Please specify an app to run the command on"
[[ ! "$1" =~ ^[a-z].* && ! "$1" =~ ^[0-9].* ]] && dokku_log_fail "App name must begin with lowercase alphanumeric character"
[[ -d "$DOKKU_ROOT/$1" ]] && dokku_log_fail "Name is already taken"
@@ -12,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() {
declare 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() {
declare 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 "$@"

11
plugins/apps/subcommands/create Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/apps/functions"
apps_create_cmd() {
declare desc="creates app via command line"
local cmd="apps:create"
apps_create "$2"
}
apps_create_cmd "$@"

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
apps_main_cmd() {
declare desc="lists all apps"
local cmd="apps"
local app
dokku_log_info2_quiet "My Apps"
for app in $(dokku_apps); do
echo "$app"
done
}
apps_main_cmd "$@"

View File

@@ -0,0 +1,16 @@
#!/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() {
declare desc="destroys an app"
local cmd="apps:destroy"
[[ -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"
apps_destroy "$APP"
}
apps_destroy_cmd "$@"

28
plugins/apps/subcommands/rename Executable file
View File

@@ -0,0 +1,28 @@
#!/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() {
declare desc="renames an app"
local cmd="apps:rename"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
[[ -d "$DOKKU_ROOT/$3" ]] && dokku_log_fail "Name is already taken"
local OLD_APP="$2"
local NEW_APP="$3"
mkdir -p "$DOKKU_ROOT/$NEW_APP"
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_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"
ps_rebuild "$NEW_APP"
plugn trigger post-app-rename "$OLD_APP" "$NEW_APP"
echo "Renaming $OLD_APP to $NEW_APP... done"
}
apps_rename_cmd "$@"

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() {
declare 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

@@ -1,170 +1,8 @@
#!/usr/bin/env bash
[[ " certs:add certs:generate certs:info certs:remove certs:update help certs:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help certs: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/certs/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
is_tar_import() {
[[ -t 0 ]] && return 1
return 0
}
is_file_import() {
local CRT_FILE="$1"
local KEY_FILE="$2"
if [[ $CRT_FILE ]] && [[ $KEY_FILE ]]; then
if [[ ! -f $CRT_FILE ]]; then
dokku_log_fail "CRT file specified not found, please check file paths"
elif [[ ! -f $KEY_FILE ]]; then
dokku_log_fail "KEY file specified not found, please check file paths"
else
return 0
fi
fi
return 1
}
certs_set() {
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
local APP="$2"; local CRT_FILE="$3"; local KEY_FILE="$4"; local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
is_file_import "$CRT_FILE" "$KEY_FILE" || is_tar_import || dokku_log_fail "Tar archive containing server.crt and server.key expected on stdin"
if is_tar_import; then
TEMP_DIR=$(mktemp -d -t "dokku_certs_set.XXXX")
pushd "$TEMP_DIR" &> /dev/null
trap 'popd &> /dev/null || true; rm -rf $TEMP_DIR > /dev/null' RETURN
tar xvf - <&0
CRT_FILE_SEARCH=$(find . -not -path '*/\.*' -type f -name "*.crt")
CRT_FILE_COUNT=$(printf "%s" "$CRT_FILE_SEARCH" | grep -c '^')
if [[ $CRT_FILE_COUNT -lt 1 ]]; then
dokku_log_fail "Tar archive is missing .crt file"
elif [[ $CRT_FILE_COUNT -gt 1 ]]; then
dokku_log_fail "Tar archive contains more than one .crt file"
else
CRT_FILE=$CRT_FILE_SEARCH
fi
KEY_FILE_SEARCH=$(find . -not -path '*/\.*' -type f -name "*.key")
KEY_FILE_COUNT=$(printf "%s" "$KEY_FILE_SEARCH" | grep -c '^')
if [[ $KEY_FILE_COUNT -lt 1 ]]; then
dokku_log_fail "Tar archive is missing .key file"
elif [[ $KEY_FILE_COUNT -gt 1 ]]; then
dokku_log_fail "Tar archive contains more than one .key file"
else
KEY_FILE=$KEY_FILE_SEARCH
fi
fi
mkdir -p "$APP_SSL_PATH"
cp "$CRT_FILE" "$APP_SSL_PATH/server.crt"
cp "$KEY_FILE" "$APP_SSL_PATH/server.key"
chmod 750 "$APP_SSL_PATH"
chmod 640 "$APP_SSL_PATH/server.crt" "$APP_SSL_PATH/server.key"
cd "$DOKKU_ROOT"
nginx_build_config "$APP"
}
case "$1" in
certs:add)
certs_set "$@"
;;
certs:generate)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"; DOMAIN="$3"; APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
if [[ ! -f "$APP_SSL_PATH/server.key" ]] && [[ ! -f "$APP_SSL_PATH/server.crt" ]]; then
TMP_WORK_DIR=$(mktemp -d -t "dokku_certs.XXXXXXXXX")
pushd "$TMP_WORK_DIR" > /dev/null
trap 'popd &> /dev/null || true; rm -rf "$TMP_WORK_DIR" > /dev/null' INT TERM EXIT
openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
openssl rsa -passin pass:x -in server.pass.key -out server.key
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
mkdir -p "$APP_SSL_PATH"
dokku_log_info1 "Installing certificate and key..."
mv -f "$TMP_WORK_DIR/server.key" "$TMP_WORK_DIR/server.crt" "$APP_SSL_PATH"
chmod 750 "$APP_SSL_PATH"
chmod 640 "$APP_SSL_PATH/server.key" "$APP_SSL_PATH/server.crt"
[[ -n "$DOMAIN" ]] && (dokku domains:add "$APP" "$DOMAIN" || nginx_build_config "$APP")
dokku_log_info1 "The following is a certificate signing request that can be used"
dokku_log_info1 "to generate an 'officially' signed SSL certificate for $APP at $DOMAIN"
dokku_log_info1 "by a CA of your choosing."
cat server.csr
else
dokku_log_info1 "$APP has an SSL endpoint already defined"
fi
;;
certs:info)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"; SSL_TYPE=$(is_ssl_enabled "$APP")
case "$SSL_TYPE" in
app)
SSL_PATH="$DOKKU_ROOT/$APP/tls"
;;
global)
SSL_PATH="$DOKKU_ROOT/tls"
;;
*)
;;
esac
if [[ -n "$SSL_PATH" ]]; then
dokku_log_info1 "Fetching SSL Endpoint info for $APP..."
dokku_log_info1 "Certificate details:"
dokku_log_info2 "Common Name(s): "
for domain in $(get_ssl_hostnames "$APP" | xargs); do
dokku_log_info2 " $domain"
done
dokku_log_info2 "Expires At: $(openssl x509 -in "$SSL_PATH/server.crt" -noout -text | grep "Not After :" | awk -F " : " '{ print $2 }')"
dokku_log_info2 "Issuer: $(openssl x509 -in "$SSL_PATH/server.crt" -noout -text | grep "Issuer:" | xargs | sed -e "s/Issuer: //g")"
dokku_log_info2 "Starts At: $(openssl x509 -in "$SSL_PATH/server.crt" -noout -text | grep "Not Before:" | awk -F ": " '{ print $2 }')"
dokku_log_info2 "Subject: $(openssl x509 -in "$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 "$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."
else
SSL_SELF_SIGNED="self signed."
fi
dokku_log_info2 "SSL certificate is $SSL_SELF_SIGNED"
else
dokku_log_info1 "$APP does not have an SSL endpoint"
fi
;;
certs:remove)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
APP="$2"; APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
if [[ -d "$APP_SSL_PATH" ]]; then
dokku_log_info1 "Removing SSL endpoint from $APP"
rm -rf "$APP_SSL_PATH"
plugn trigger post-domains-update "$APP"
else
dokku_log_fail "An app-specific SSL endpoint is not defined"
fi
;;
certs:update)
certs_set "$@"
;;
help | certs:help)
cat<<EOF
certs:add <app> CRT KEY, Add an ssl endpoint to an app. Can also import from a tarball on stdin

View File

@@ -2,11 +2,10 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
# returns 'global', 'app', 'false'
# if both are configured, app trumps global
is_ssl_enabled() {
declare 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
@@ -16,6 +15,7 @@ is_ssl_enabled() {
}
get_ssl_hostnames() {
declare desc="returns a string of ssl hostnames extracted from an app's ssl certificate"
local APP=$1; verify_app_name "$APP"
local SSL_PATH="$DOKKU_ROOT/$APP/tls"

76
plugins/certs/subcommands/add Executable file
View File

@@ -0,0 +1,76 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/certs/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
is_tar_import() {
declare desc="determines if we have STDIN open in an attempt to detect a streamed tar import"
[[ -t 0 ]] && return 1
return 0
}
is_file_import() {
declare desc="determines if we have passed in a file and key path for a file import"
local CRT_FILE="$1"
local KEY_FILE="$2"
if [[ $CRT_FILE ]] && [[ $KEY_FILE ]]; then
if [[ ! -f $CRT_FILE ]]; then
dokku_log_fail "CRT file specified not found, please check file paths"
elif [[ ! -f $KEY_FILE ]]; then
dokku_log_fail "KEY file specified not found, please check file paths"
else
return 0
fi
fi
return 1
}
certs_set() {
declare desc="imports an SSL cert/key combo either on STDIN via a tarball or from specified cert/key filenames"
local cmd="$1"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
local APP="$2"; local CRT_FILE="$3"; local KEY_FILE="$4"; local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
is_file_import "$CRT_FILE" "$KEY_FILE" || is_tar_import || dokku_log_fail "Tar archive containing server.crt and server.key expected on stdin"
if is_tar_import; then
local TEMP_DIR=$(mktemp -d -t "dokku_certs_set.XXXX")
pushd "$TEMP_DIR" &> /dev/null
trap 'popd &> /dev/null || true; rm -rf $TEMP_DIR > /dev/null' RETURN
tar xvf - <&0
local CRT_FILE_SEARCH=$(find . -not -path '*/\.*' -type f -name "*.crt")
local CRT_FILE_COUNT=$(printf "%s" "$CRT_FILE_SEARCH" | grep -c '^')
if [[ $CRT_FILE_COUNT -lt 1 ]]; then
dokku_log_fail "Tar archive is missing .crt file"
elif [[ $CRT_FILE_COUNT -gt 1 ]]; then
dokku_log_fail "Tar archive contains more than one .crt file"
else
local CRT_FILE=$CRT_FILE_SEARCH
fi
local KEY_FILE_SEARCH=$(find . -not -path '*/\.*' -type f -name "*.key")
local KEY_FILE_COUNT=$(printf "%s" "$KEY_FILE_SEARCH" | grep -c '^')
if [[ $KEY_FILE_COUNT -lt 1 ]]; then
dokku_log_fail "Tar archive is missing .key file"
elif [[ $KEY_FILE_COUNT -gt 1 ]]; then
dokku_log_fail "Tar archive contains more than one .key file"
else
local KEY_FILE=$KEY_FILE_SEARCH
fi
fi
mkdir -p "$APP_SSL_PATH"
cp "$CRT_FILE" "$APP_SSL_PATH/server.crt"
cp "$KEY_FILE" "$APP_SSL_PATH/server.key"
chmod 750 "$APP_SSL_PATH"
chmod 640 "$APP_SSL_PATH/server.crt" "$APP_SSL_PATH/server.key"
cd "$DOKKU_ROOT"
nginx_build_config "$APP"
}
certs_set "$@"

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
certs_generate_cmd() {
declare desc="generates a self-signed SSL certificate/key combo"
local cmd="certs:generate"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
local APP="$2"; local DOMAIN="$3"; local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
if [[ ! -f "$APP_SSL_PATH/server.key" ]] && [[ ! -f "$APP_SSL_PATH/server.crt" ]]; then
local TMP_WORK_DIR=$(mktemp -d -t "dokku_certs.XXXXXXXXX")
pushd "$TMP_WORK_DIR" > /dev/null
trap 'popd &> /dev/null || true; rm -rf "$TMP_WORK_DIR" > /dev/null' INT TERM EXIT
openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
openssl rsa -passin pass:x -in server.pass.key -out server.key
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
mkdir -p "$APP_SSL_PATH"
dokku_log_info1 "Installing certificate and key..."
mv -f "$TMP_WORK_DIR/server.key" "$TMP_WORK_DIR/server.crt" "$APP_SSL_PATH"
chmod 750 "$APP_SSL_PATH"
chmod 640 "$APP_SSL_PATH/server.key" "$APP_SSL_PATH/server.crt"
[[ -n "$DOMAIN" ]] && (domains_add "$APP" "$DOMAIN" || nginx_build_config "$APP")
dokku_log_info1 "The following is a certificate signing request that can be used"
dokku_log_info1 "to generate an 'officially' signed SSL certificate for $APP at $DOMAIN"
dokku_log_info1 "by a CA of your choosing."
cat server.csr
else
dokku_log_info1 "$APP has an SSL endpoint already defined"
fi
}
certs_generate_cmd "$@"

38
plugins/certs/subcommands/info Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/certs/functions"
certs_info_cmd() {
declare desc="prints SSL certificate info for app"
local cmd="certs:info"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
local APP="$2"; local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
if [[ -n "$APP_SSL_PATH" ]]; then
dokku_log_info1 "Fetching SSL Endpoint info for $APP..."
dokku_log_info1 "Certificate details:"
dokku_log_info2 "Common Name(s): "
for domain in $(get_ssl_hostnames "$APP" | xargs); do
dokku_log_info2 " $domain"
done
dokku_log_info2 "Expires At: $(openssl x509 -in "$APP_SSL_PATH/server.crt" -noout -text | grep "Not After :" | awk -F " : " '{ print $2 }')"
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")"
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
local SSL_SELF_SIGNED="verified by a certificate authority."
else
local SSL_SELF_SIGNED="self signed."
fi
dokku_log_info2 "SSL certificate is $SSL_SELF_SIGNED"
else
dokku_log_info1 "$APP does not have an SSL endpoint"
fi
}
certs_info_cmd "$@"

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
certs_remove_cmd() {
declare desc="removes SSL cert/key from specified app"
local cmd="certs:remove"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
local APP="$2"; local APP_SSL_PATH="$DOKKU_ROOT/$APP/tls"
if [[ -d "$APP_SSL_PATH" ]]; then
dokku_log_info1 "Removing SSL endpoint from $APP"
rm -rf "$APP_SSL_PATH"
plugn trigger post-domains-update "$APP"
else
dokku_log_fail "An app-specific SSL endpoint is not defined"
fi
}
certs_remove_cmd "$@"

View File

@@ -0,0 +1 @@
add

View File

@@ -33,188 +33,200 @@
# 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() {
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() {
declare 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() {
declare desc="cleans up TMPDIR and print container output"
local id="$1"
rm -rf "$TMPDIR"
if [[ $id ]]; then
dokku_log_info2_quiet "$APP $DOKKU_APP_CONTAINER_TYPE container output:"
dokku_container_log_verbose_quiet "$id"
dokku_log_info2_quiet "end $APP $DOKKU_APP_CONTAINER_TYPE container output"
fi
}
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

@@ -1,67 +1,8 @@
#!/usr/bin/env bash
[[ " checks checks:enable checks:disable help ps:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help checks: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"
checks_main() {
local desc="displays app zero-downtime status"
local ALL_APPS=$(dokku_apps)
if [[ -n "$1" ]]; then
local APP="$1"
fi
local APPS=${APP:="$ALL_APPS"}
dokku_col_log_info1_quiet "App Name" "Zero-Downtime Status"
for app in $APPS; do
verify_app_name "$app"
dokku_col_log_msg "$app" "$(is_app_checks_enabled "$app")"
done
}
checks_enable() {
local desc="enable zero-downtime for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_checks_enabled "$APP")" == "false" ]]; then
dokku_log_info1 "Enabling zero downtime for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
# shellcheck disable=SC2086
config_set $CONFIG_SET_ARGS $APP DOKKU_CHECKS_ENABLED=1
else
dokku_log_info1 "zero downtime is already enabled for app ($APP)"
fi
}
checks_disable() {
local desc="disable zero-downtime for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_checks_enabled "$APP")" == "true" ]]; then
dokku_log_info1 "Disabling zero downtime for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
# shellcheck disable=SC2086
config_set $CONFIG_SET_ARGS $APP DOKKU_CHECKS_ENABLED=0
else
dokku_log_info1 "zero downtime is already disable for app ($APP)"
fi
}
case "$1" in
checks)
checks_main "$2"
;;
checks:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
checks_enable "$2" --no-restart
;;
checks:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
checks_disable "$2" --no-restart
;;
help | ps:help)
cat<<EOF
checks <app>, Show zero-downtime status

View File

@@ -4,7 +4,7 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
is_app_checks_enabled() {
local desc="return app zero-downtime checks status"
declare desc="return app zero-downtime checks status"
local APP="$1"; verify_app_name "$APP"
local DOKKU_CHECKS_ENABLED=$(config_get "$APP" DOKKU_CHECKS_ENABLED)

View File

@@ -4,6 +4,7 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
migrate_checks_vars() {
declare desc="migrates deprecated CHECKS config variables to simplified counter part introduced in 0.5.x"
local APPS="$(dokku_apps)"
local GLOBAL_SKIP_ALL_CHECKS=$(dokku config:get --global DOKKU_SKIP_ALL_CHECKS || true)
local GLOBAL_SKIP_DEFAULT_CHECKS=$(dokku config:get --global DOKKU_SKIP_DEFAULT_CHECKS || true)

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
checks_main_cmd() {
declare desc="displays app zero-downtime status"
local cmd="checks"
local ALL_APPS=$(dokku_apps)
if [[ -n "$1" ]]; then
local APP="$1"
fi
local APPS=${APP:="$ALL_APPS"}
dokku_col_log_info1_quiet "App Name" "Zero-Downtime Status"
local app
for app in $APPS; do
verify_app_name "$app"
dokku_col_log_msg "$app" "$(is_app_checks_enabled "$app")"
done
}
checks_main_cmd "$2"

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
checks_disable_cmd() {
declare desc="disable zero-downtime for app"
local cmd="check:disable"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_checks_enabled "$APP")" == "true" ]]; then
dokku_log_info1 "Disabling zero downtime for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
# shellcheck disable=SC2086
config_set $CONFIG_SET_ARGS $APP DOKKU_CHECKS_ENABLED=0
else
dokku_log_info1 "zero downtime is already disable for app ($APP)"
fi
}
checks_disable_cmd "$2" --no-restart

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/checks/functions"
checks_enable_cmd() {
declare desc="enable zero-downtime for app"
local cmd="checks:enable"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_checks_enabled "$APP")" == "false" ]]; then
dokku_log_info1 "Enabling zero downtime for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
# shellcheck disable=SC2086
config_set $CONFIG_SET_ARGS $APP DOKKU_CHECKS_ENABLED=1
else
dokku_log_info1 "zero downtime is already enabled for app ($APP)"
fi
}
checks_enable_cmd "$2" --no-restart

View File

@@ -2,6 +2,7 @@
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
has_tty() {
declare desc="return 0 if we have a tty"
if [[ "$(/usr/bin/tty || true)" == "not a tty" ]]; then
return 1
else
@@ -10,19 +11,23 @@ has_tty() {
}
dokku_apps() {
declare desc="prints list of all local apps"
local INSTALLED_APPS=$(find "$DOKKU_ROOT" -follow -maxdepth 1 -mindepth 1 -type d ! -name 'tls' ! -name '.*' -printf "%f\n" | sort) || (dokku_log_fail "You haven't deployed any applications yet")
[[ $INSTALLED_APPS ]] && echo "$INSTALLED_APPS"
}
dokku_log_info1() {
declare desc="log info1 formatter"
echo "-----> $*"
}
dokku_log_info2() {
declare desc="log info2 formatter"
echo "=====> $*"
}
dokku_log_info1_quiet() {
declare desc="log info1 formatter (with quiet option)"
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
echo "-----> $*"
else
@@ -31,6 +36,7 @@ dokku_log_info1_quiet() {
}
dokku_log_info2_quiet() {
declare desc="log info2 formatter (with quiet option)"
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
echo "=====> $*"
else
@@ -39,10 +45,12 @@ dokku_log_info2_quiet() {
}
dokku_col_log_info1() {
declare desc="columnar log info1 formatter"
printf "%-6s %-18s %-25s %-25s %-25s\n" "----->" "$@"
}
dokku_col_log_info1_quiet() {
declare desc="columnar log info1 formatter (with quiet option)"
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
printf "%-6s %-18s %-25s %-25s %-25s\n" "----->" "$@"
else
@@ -51,10 +59,12 @@ dokku_col_log_info1_quiet() {
}
dokku_col_log_info2() {
declare desc="columnar log info2 formatter"
printf "%-6s %-18s %-25s %-25s %-25s\n" "=====>" "$@"
}
dokku_col_log_info2_quiet() {
declare desc="columnar log info2 formatter (with quiet option)"
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
printf "%-6s %-18s %-25s %-25s %-25s\n" "=====>" "$@"
else
@@ -63,10 +73,12 @@ dokku_col_log_info2_quiet() {
}
dokku_col_log_msg() {
declare desc="columnar log formatter"
printf "%-25s %-25s %-25s %-25s\n" "$@"
}
dokku_col_log_msg_quiet() {
declare desc="columnar log formatter (with quiet option)"
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
printf "%-25s %-25s %-25s %-25s\n" "$@"
else
@@ -75,6 +87,7 @@ dokku_col_log_msg_quiet() {
}
dokku_log_verbose_quiet() {
declare desc="log verbose formatter (with quiet option)"
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
echo " $*"
else
@@ -83,35 +96,41 @@ dokku_log_verbose_quiet() {
}
dokku_log_verbose() {
declare desc="log verbose formatter"
echo " $*"
}
dokku_log_warn() {
declare desc="log warning formatter"
echo " ! $*"
}
dokku_log_fail() {
declare desc="log fail formatter"
echo "$@" 1>&2
exit 1
}
dokku_log_event() {
declare desc="log dokku events"
logger -t dokku -i -- "$@"
}
dokku_log_plugn_trigger_call() {
local l_hook
declare desc="log plugn trigger calls"
l_hook="$1" ; shift
local l_hook="$1" ; shift
dokku_log_event "INVOKED: ${l_hook}( $* ) NAME=$NAME FINGERPRINT=$FINGERPRINT"
}
dokku_container_log_verbose_quiet() {
declare desc="log verbose container output (with quiet option)"
local CID=$1;
shift
OIFS=$IFS
IFS=$'\n'
local line
for line in $(docker logs "$CID" 2>&1); do
dokku_log_verbose_quiet "$line"
done
@@ -119,6 +138,7 @@ dokku_container_log_verbose_quiet() {
}
verify_app_name() {
declare desc="verify app name format and app existence"
local APP="$1"
[[ ! -n "$APP" ]] && dokku_log_fail "(verify_app_name) APP must not be null"
if [[ ! "$APP" =~ ^[a-z].* && ! "$APP" =~ ^[0-9].* ]]; then
@@ -131,6 +151,7 @@ verify_app_name() {
}
verify_image() {
declare desc="verify image existence"
local IMAGE="$1"
if (docker inspect "$IMAGE" &>/dev/null); then
return 0
@@ -140,44 +161,46 @@ verify_image() {
}
get_app_image_repo() {
# central definition of our image repo pattern
declare desc="central definition of image repo pattern"
local APP="$1"; local IMAGE_REPO="dokku/$APP"
[[ -z "$APP" ]] && dokku_log_fail "(get_app_image_repo) APP must not be null"
echo "$IMAGE_REPO"
}
get_app_image_name() {
# return image identifier for a given app, tag tuple. validate if tag is presented
declare desc="return image identifier for a given app, tag tuple. validate if tag is presented"
local APP="$1"; local IMAGE_TAG="$2"; local IMAGE_REPO=$(get_app_image_repo "$APP")
[[ -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"
}
get_running_image_tag() {
# retrieve current image tag for a given app. returns empty string if no deployed containers are found
declare desc="retrieve current image tag for a given app. returns empty string if no deployed containers are found"
local APP="$1"
[[ ! -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"
}
is_image_herokuish_based() {
declare desc="returns true if app image is based on herokuish"
# circleci can't support --rm as they run lxc in lxc
[[ ! -f "/home/ubuntu/.circlerc" ]] && local DOCKER_ARGS="--rm"
docker run "$DOKKU_GLOBAL_RUN_ARGS" --entrypoint="/bin/sh" $DOCKER_ARGS "$@" -c "test -f /exec"
}
is_number() {
declare desc="returns 0 if input is a number"
local NUMBER=$1; local NUM_RE='^[0-9]+$'
if [[ $NUMBER =~ $NUM_RE ]]; then
return 0
@@ -187,8 +210,9 @@ is_number() {
}
is_abs_path() {
declare 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
@@ -196,7 +220,10 @@ is_abs_path() {
}
parse_args() {
declare desc="top-level cli arg parser"
local next_index=1; local skip=false; local args=("$@")
for arg in "$@"; do
$skip && skip=false && continue
case "$arg" in
--quiet)
export DOKKU_QUIET_OUTPUT=1
@@ -210,22 +237,27 @@ parse_args() {
--force)
export DOKKU_APPS_FORCE_DELETE=1
;;
--app)
export DOKKU_APP_NAME=${args[$next_index]}; skip=true
;;
esac
local next_index=$(( next_index + 1 ))
done
return 0
}
copy_from_image() {
declare desc="copy file from named image to destination"
local IMAGE="$1"; local SRC_FILE="$2"; local DST_DIR="$3"
verify_app_name "$APP"
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
@@ -234,31 +266,34 @@ copy_from_image() {
}
get_app_container_ids() {
declare desc="returns list of docker container ids for given app"
local APP="$1"; local CONTAINER_TYPE="$2"
verify_app_name "$APP"
[[ -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"
}
get_app_running_container_ids() {
declare desc="return list of running docker container ids for given apps"
local APP=$1
verify_app_name "$APP"
@@ -274,6 +309,7 @@ get_app_running_container_ids() {
}
get_cmd_from_procfile() {
declare desc="parse cmd from app Procfile"
local APP=$1; local PROC_TYPE=$2; local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
local name; local command;
verify_app_name "$APP"
@@ -283,14 +319,15 @@ 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
}
is_deployed() {
declare desc="return 0 if given app has a running container"
local APP="$1"
if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]] || [[ $(ls "$DOKKU_ROOT/$APP"/CONTAINER.* &> /dev/null; echo $?) -eq 0 ]]; then
return 0
@@ -300,6 +337,7 @@ is_deployed() {
}
is_container_running () {
declare desc="return 0 if given docker container id is in running state"
local CID=$1
local CONTAINER_STATUS=$(docker inspect -f '{{.State.Running}}' "$CID" || true)
@@ -311,6 +349,7 @@ is_container_running () {
}
is_container_status () {
declare desc="return 0 if given docker container id is in given state"
local CID=$1
local TEMPLATE="{{.State.$2}}"
local CONTAINER_STATUS=$(docker inspect -f "$TEMPLATE" "$CID" || true)
@@ -323,6 +362,7 @@ is_container_status () {
}
is_app_running() {
declare desc="return 0 if given app has a running container"
local APP="$1"
verify_app_name "$APP"
@@ -336,20 +376,23 @@ is_app_running() {
}
release_and_deploy() {
declare 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"
if verify_image "$IMAGE"; then
if is_image_herokuish_based "$IMAGE"; then
IMAGE_SOURCE_TYPE="herokuish"
local IMAGE_SOURCE_TYPE="herokuish"
else
IMAGE_SOURCE_TYPE="dockerfile"
local IMAGE_SOURCE_TYPE="dockerfile"
fi
DOKKU_APP_SKIP_DEPLOY="$(dokku config:get "$APP" DOKKU_SKIP_DEPLOY || true)"
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)"
DOKKU_SKIP_DEPLOY=${DOKKU_APP_SKIP_DEPLOY:="$DOKKU_GLOBAL_SKIP_DEPLOY"}
local DOKKU_SKIP_DEPLOY=${DOKKU_APP_SKIP_DEPLOY:="$DOKKU_GLOBAL_SKIP_DEPLOY"}
dokku_log_info1 "Releasing $APP ($IMAGE)..."
dokku release "$APP" "$IMAGE_SOURCE_TYPE" "$IMAGE_TAG"
@@ -358,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
@@ -368,6 +411,7 @@ release_and_deploy() {
}
docker_cleanup() {
declare desc="cleans up all exited/dead containers and removes all dangling images"
# delete all non-running containers
# shellcheck disable=SC2046
docker rm $(docker ps -a -f 'status=exited' -q) &> /dev/null || true
@@ -382,6 +426,7 @@ docker_cleanup() {
}
get_available_port() {
declare desc="returns first currently unused port > 1024"
while true; do
local port=$(shuf -i 1025-65535 -n 1)
if ! nc -z 0.0.0.0 "$port"; then
@@ -394,6 +439,7 @@ get_available_port() {
}
dokku_auth() {
declare desc="calls user-auth plugin trigger"
export SSH_USER=${SSH_USER:=$USER}
export SSH_NAME=${NAME:="default"}
if ! plugn trigger user-auth "$SSH_USER" "$SSH_NAME" "$@" ; then
@@ -403,27 +449,30 @@ dokku_auth() {
}
_ipv4_regex() {
declare desc="ipv4 regex"
echo "([0-9]{1,3}[\.]){3}[0-9]{1,3}"
}
_ipv6_regex() {
declare 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"
}
get_ipv4_regex() {
declare desc="returns ipv4 regex"
local RE_IPV4="$(_ipv4_regex)"
# Ensure the ip address continues to the end of the line
# Fixes using a wildcard dns service such as xip.io which allows for *.<ip address>.xip.io
@@ -431,6 +480,7 @@ get_ipv4_regex() {
}
get_ipv6_regex() {
declare desc="returns ipv6 regex"
local RE_IPV6="$(_ipv6_regex)"
# Ensure the ip address continues to the end of the line
# Fixes using a wildcard dns service such as xip.io which allows for *.<ip address>.xip.io
@@ -438,13 +488,14 @@ get_ipv6_regex() {
}
get_global_vhost() {
local GLOBAL_VHOST_FILE="$DOKKU_ROOT/VHOST"
[[ -f "$GLOBAL_VHOST_FILE" ]] && local GLOBAL_VHOST=$(< "$GLOBAL_VHOST_FILE")
echo "$GLOBAL_VHOST"
declare desc="return global vhost"
local GLOBAL_VHOST_FILE="$DOKKU_ROOT/VHOST"
[[ -f "$GLOBAL_VHOST_FILE" ]] && local GLOBAL_VHOST=$(< "$GLOBAL_VHOST_FILE")
echo "$GLOBAL_VHOST"
}
is_global_vhost_enabled() {
local desc="returns true if we have a valid global vhost set; otherwise returns false"
declare desc="returns true if we have a valid global vhost set; otherwise returns false"
local GLOBAL_VHOST=$(get_global_vhost)
local GLOBAL_VHOST_ENABLED=true
local RE_IPV4="$(get_ipv4_regex)"
@@ -457,9 +508,10 @@ is_global_vhost_enabled() {
}
is_app_vhost_enabled() {
local desc="returns true or false if vhost support is enabled for a given application"
local APP=$1; verify_app_name "$APP"
declare desc="returns true or false if vhost support is enabled for a given application"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
local APP=$1; verify_app_name "$APP"
local NO_VHOST=$(config_get "$APP" NO_VHOST)
local APP_VHOST_ENABLED=true
@@ -471,7 +523,9 @@ is_app_vhost_enabled() {
}
disable_app_vhost() {
local desc="disable vhost support for given application"
declare desc="disable vhost support for given application"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
local APP=$1; verify_app_name "$APP"
local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
local APP_URLS_FILE="$DOKKU_ROOT/$APP/URLS"
@@ -499,7 +553,9 @@ disable_app_vhost() {
}
enable_app_vhost() {
local desc="enable vhost support for given application"
declare desc="enable vhost support for given application"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
local APP=$1; verify_app_name "$APP"
config_unset --no-restart "$APP" DOKKU_NGINX_PORT DOKKU_NGINX_SSL_PORT
@@ -509,11 +565,15 @@ enable_app_vhost() {
}
get_dockerfile_exposed_ports() {
declare desc="return all exposed ports from passed file path"
local DOCKERFILE_PORTS=$(egrep "^EXPOSE " "$1" | awk '{ print $2 }' | xargs) || true
echo "$DOCKERFILE_PORTS"
}
get_app_raw_tcp_ports() {
declare desc="extracts raw tcp port numbers from DOCKERFILE_PORTS config variable"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
local APP="$1"; verify_app_name "$APP"
local DOCKERFILE_PORTS="$(config_get "$APP" DOKKU_DOCKERFILE_PORTS)"
for p in $DOCKERFILE_PORTS; do
@@ -522,11 +582,12 @@ get_app_raw_tcp_ports() {
raw_tcp_ports+="$p "
fi
done
raw_tcp_ports="$(echo "$raw_tcp_ports"| xargs)"
local raw_tcp_ports="$(echo "$raw_tcp_ports"| xargs)"
echo "$raw_tcp_ports"
}
get_container_ports() {
declare desc="returns published ports from app containers"
local APP="$1"; verify_app_name "$APP"
local APP_CIDS="$(get_app_container_ids "$APP")"
local cid
@@ -539,6 +600,10 @@ get_container_ports() {
}
get_app_urls() {
declare 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")"
local URLS_FILE="$DOKKU_ROOT/$APP/URLS"
@@ -603,7 +668,7 @@ get_app_urls() {
}
get_json_value() {
# return value of provided json key from a json stream on stdin
declare desc="return value of provided json key from a json stream on stdin"
# JSON_NODE should be expresses as either a top-level object that has no children
# or in the format of json.node.path
local JSON_NODE="$1"
@@ -613,7 +678,7 @@ get_json_value() {
}
get_json_keys() {
# return space-separated list of json keys from json provided on stdin
declare desc="return space-separated list of json keys from json provided on stdin"
# JSON_NODE should be expressed as json.node.path and is expected to have children
local JSON_NODE="$1"
local JSON_NODE=${JSON_NODE//\./\"][\"}

View File

@@ -1,26 +1,8 @@
#!/usr/bin/env bash
[[ " config config:get config:set config:unset help config:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help config: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/config/functions"
case "$1" in
config)
config_all "$@"
;;
config:get)
config_get "$@"
;;
config:set)
config_set "$@"
;;
config:unset)
config_unset "$@"
;;
help | config:help)
cat<<EOF
config (<app>|--global), Display all global or app-specific config vars

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() {
declare 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

@@ -3,6 +3,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
config_export() {
declare desc="returns export command for config variable of specified type (app/global)"
local CONFIG_TYPE="$1"
local APP="$2"
local ENV_FILE="$DOKKU_ROOT/$APP/ENV"
@@ -17,6 +18,7 @@ config_export() {
}
config_parse_args() {
declare desc="parse config plugin args"
unset APP ENV_FILE DOKKU_CONFIG_TYPE DOKKU_CONFIG_RESTART
case "$2" in
--global)
@@ -48,11 +50,13 @@ config_parse_args() {
}
config_create () {
declare desc="create config env file"
local ENV_FILE=$1
[[ -f $ENV_FILE ]] || touch "$ENV_FILE"
}
config_styled_hash () {
declare desc="internal config hash"
local vars="$1"
local prefix="$2"
local longest=""
@@ -79,6 +83,7 @@ config_styled_hash () {
}
config_write() {
declare desc="writes config vars out to appropriate file path"
local ENV_TEMP="$1"
local ENV_FILE_TEMP="${ENV_FILE}.tmp"
@@ -91,6 +96,7 @@ config_write() {
}
is_config_export() {
declare desc="return 0 if we're supposed to export"
for var in "$@"; do
if [[ "$var" == "--export" ]]; then
return 0
@@ -100,6 +106,7 @@ is_config_export() {
}
config_all() {
declare desc="print or export config vars"
[[ "$1" == "config" ]] || set -- "config" "$@"
config_parse_args "$@"
@@ -123,6 +130,7 @@ config_all() {
}
config_get() {
declare desc="get value of given config var"
[[ "$1" == "config:get" ]] || set -- "config:get" "$@"
config_parse_args "$@"
@@ -143,6 +151,7 @@ config_get() {
}
config_set() {
declare desc="set value of given config var"
[[ "$1" == "config:set" ]] || set -- "config:set" "$@"
config_parse_args "$@"
[[ "$2" = "--no-restart" ]] && set -- "${@:1:1}" "${@:3}"
@@ -200,6 +209,7 @@ ${var}"
}
config_unset() {
declare desc="unset given config var"
[[ "$1" == "config:unset" ]] || set -- "config:unset" "$@"
config_parse_args "$@"
[[ "$2" = "--no-restart" ]] && set -- "${@:1:1}" "${@:3}"

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/config/functions"
config_main_cmd() {
declare desc="print config vars for app via command line"
local cmd="config"
config_all "$@"
}
config_main_cmd "$@"

11
plugins/config/subcommands/get Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/config/functions"
config_get_cmd() {
declare desc="get specified config vars from app via command line"
local cmd="config:get"
config_get "$@"
}
config_get_cmd "$@"

11
plugins/config/subcommands/set Executable file
View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/config/functions"
config_set_cmd() {
declare desc="set specified config vars for app via command line"
local cmd="config:set"
config_set "$@"
}
config_set_cmd "$@"

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/config/functions"
config_unset_cmd() {
declare desc="unset specified config vars for app via command line"
local cmd="config:unset"
config_unset "$@"
}
config_unset_cmd "$@"

View File

@@ -1,43 +1,8 @@
#!/usr/bin/env bash
[[ " docker-options docker-options:add docker-options:remove help docker-options:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help docker-options: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/docker-options/functions"
declare APP # global assigned in case
case "$1" in
# Display applications docker options
docker-options)
verify_app_name "$2" && APP="$2"
read -ra passed_phases <<< "$(get_phases "$3")"
if [[ ! "${passed_phases[@]}" ]]; then
display_all_phases_options
else
display_passed_phases_options passed_phases[@]
fi
;;
# Add a docker option to application
docker-options:add)
verify_app_name "$2" && APP="$2"
read -ra passed_phases <<< "$(get_phases "$3")"
shift 3 # everything else passed is the docker option
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[@]}"
;;
# Remove a docker option from application
docker-options:remove)
verify_app_name "$2" && APP="$2"
read -ra passed_phases <<< "$(get_phases "$3")"
shift 3 # everything else passed is the docker option
[[ -z ${passed_docker_option="$@"} ]] && dokku_log_fail "Please specify docker options to add to the phase"
remove_passed_docker_option passed_phases[@] "${passed_docker_option[@]}"
;;
# Display usage help
help | docker-options:help)
cat<<EOF
docker-options <app>, Display app's Docker options for all phases

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() {
declare 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

@@ -5,6 +5,7 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
AVAILABLE_PHASES=(build deploy run)
get_phase_file_path() {
declare desc="return docker-options config file path for specified phase"
local phase_file_prefix="DOCKER_OPTIONS_"
local phase=$1
[[ "$DOKKU_ROOT" && "$APP" && "$phase_file_prefix" && "$phase" ]] || dokku_log_fail "Error: phase_file_path is incomplete."
@@ -12,6 +13,7 @@ get_phase_file_path() {
}
get_phases() {
declare desc="returns array of passed passes if all are in allowed array"
local passed_phases_list="$1"
local -r phases_allowed=$(sed -e 's/ /\|/g' <<< "${AVAILABLE_PHASES[@]}")
local phase
@@ -28,6 +30,7 @@ get_phases() {
}
create_phase_file_if_required() {
declare desc="create phase file"
local phase_file_path="$1"
[[ -f "$phase_file_path" ]] || {
touch "$phase_file_path"
@@ -35,6 +38,7 @@ create_phase_file_if_required() {
}
display_phase_options() {
declare desc="print docker-options for specified phase"
local phase="$1"
local phase_file_path="$2"
echo "${phase^} options:"
@@ -42,10 +46,10 @@ display_phase_options() {
}
display_all_phases_options() {
declare 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
@@ -53,11 +57,11 @@ display_all_phases_options() {
}
display_passed_phases_options() {
declare desc="print docker options for list of specified phases"
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
@@ -67,31 +71,31 @@ display_passed_phases_options() {
}
add_passed_docker_option() {
declare desc="adds docker option to specified phases"
local passed_phases=("${!1}")
shift
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
}
remove_passed_docker_option() {
declare desc="removes docker option from specified phases"
local passed_phases=("${!1}")
shift
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

@@ -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/docker-options/functions"
docker_options_add_cmd() {
declare desc="Add a docker option to application"
local cmd="docker-options:add"
verify_app_name "$2" && local APP="$2"
read -ra passed_phases <<< "$(get_phases "$3")"
shift 3 # everything else passed is the 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[@]}"
}
docker_options_add_cmd "$@"

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/docker-options/functions"
docker_options_main_cmd() {
declare desc="Display applications docker options"
local cmd="docker-options"
verify_app_name "$2" && local APP="$2"
read -ra passed_phases <<< "$(get_phases "$3")"
if [[ ! "${passed_phases[@]}" ]]; then
display_all_phases_options
else
display_passed_phases_options passed_phases[@]
fi
}
docker_options_main_cmd "$@"

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/docker-options/functions"
docker_options_remove_cmd() {
declare desc="Remove a docker option from application"
local cmd="docker-options:remove"
verify_app_name "$2" && local APP="$2"
read -ra passed_phases <<< "$(get_phases "$3")"
shift 3 # everything else passed is the docker option
[[ -z ${passed_docker_option="$@"} ]] && dokku_log_fail "Please specify docker options to add to the phase"
remove_passed_docker_option passed_phases[@] "${passed_docker_option[@]}"
}
docker_options_remove_cmd "$@"

View File

@@ -1,65 +1,8 @@
#!/usr/bin/env bash
[[ " domains domains:setup domains:add domains:clear domains:remove domains:disable domains:enable domains:set-global help domains:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help domains: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/domains/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
case "$1" in
domains)
domains_main "$2"
;;
domains:setup)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_setup "$2"
;;
domains:add)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
if [[ -z "${*:3}" ]]; then
echo "Usage: dokku $1 $2 DOMAIN [DOMAIN ...]"
echo "Must specify DOMAIN."
exit 1
fi
shift 1
domains_add "$@"
;;
domains:clear)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_clear "$2"
;;
domains:remove)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
if [[ -z "${*:3}" ]]; then
echo "Usage: dokku $1 $2 DOMAIN [DOMAIN ...]"
echo "Must specify DOMAIN."
exit 1
fi
shift 1
domains_remove "$@"
;;
domains:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_disable "$2"
;;
domains:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_enable "$2"
;;
domains:set-global)
[[ -z $2 ]] && dokku_log_fail "Please specify a global domain name"
domains_set_global "$2"
;;
help | domains:help)
cat<<EOF
domains [<app>], List domains

View File

@@ -3,7 +3,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
get_app_domains() {
local desc="return app domains"
declare desc="return app domains"
verify_app_name "$1"
local APP=$1; local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
@@ -21,7 +21,7 @@ get_app_domains() {
}
get_default_vhost() {
local desc="return default vhost"
declare desc="return default vhost"
verify_app_name "$1"
local APP="$1"; local RE_IPV4="$(get_ipv4_regex)"; local RE_IPV6="$(get_ipv6_regex)"
@@ -44,7 +44,7 @@ get_default_vhost() {
}
domains_setup() {
local desc="setup domains to default state"
declare desc="setup domains to default state"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"; local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
local RE_IPV4="$(get_ipv4_regex)"; local RE_IPV6="$(get_ipv6_regex)"
@@ -61,27 +61,8 @@ domains_setup() {
fi
}
domains_main() {
local desc="print app domains"
local APP="$1"
if [[ "$(is_global_vhost_enabled)" == "true" ]]; then
dokku_log_info2_quiet "Global Domain Name"
get_global_vhost
fi
if [[ -n "$APP" ]]; then
verify_app_name "$APP"
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info2_quiet "$APP Domain Names"
get_app_domains "$APP"
else
dokku_log_fail "No domain names set for $APP"
fi
fi
}
domains_add() {
local desc="add list of domains to app"
declare desc="add list of domains to app"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
@@ -103,19 +84,8 @@ domains_add() {
plugn trigger post-domains-update "$APP" "add" "$@"
}
domains_clear() {
local desc="clear all app domains"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
rm -f "$APP_VHOST_PATH"
domains_setup "$APP"
plugn trigger post-domains-update "$APP" "clear"
dokku_log_info1 "Cleared domains in $APP"
}
domains_remove() {
local desc="remove list of app domains"
declare desc="remove list of app domains"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
local DEFAULT_VHOST="$(get_default_vhost "$APP")"
@@ -129,7 +99,7 @@ domains_remove() {
}
domains_disable() {
local desc="disable domains/VHOST support"
declare desc="disable domains/VHOST support"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
@@ -141,7 +111,7 @@ domains_disable() {
}
domains_enable() {
local desc="enable domains/VHOST support"
declare desc="enable domains/VHOST support"
verify_app_name "$1"
local APP="$1"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
local DEFAULT_VHOST="$(get_default_vhost "$APP")"
@@ -158,7 +128,7 @@ domains_enable() {
}
domains_set_global() {
local desc="set global domain name"
declare desc="set global domain name"
local NEW_GLOBAL_VHOST="$1"; local GLOBAL_VHOST_PATH="$DOKKU_ROOT/VHOST"
if [[ -n "$NEW_GLOBAL_VHOST" ]]; then

View File

@@ -1,8 +1,9 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
shopt -s nullglob
for app in $DOKKU_ROOT/*/CONTAINER; do
APP=$(basename "$(dirname "$app")");
dokku domains:setup "$APP"
domains_setup "$APP"
done

20
plugins/domains/subcommands/add Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
domains_add_cmd() {
declare desc="adds domain to app via command line"
local cmd="domains:add"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
if [[ -z "${*:3}" ]]; then
echo "Usage: dokku $1 $2 DOMAIN [DOMAIN ...]"
echo "Must specify DOMAIN."
exit 1
fi
shift 1
domains_add "$@"
}
domains_add_cmd "$@"

View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
domains_clear_cmd() {
declare desc="clear all app domains"
local cmd="domains:clear"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
verify_app_name "$2"
local APP="$2"; local APP_VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"
rm -f "$APP_VHOST_PATH"
domains_setup "$APP"
plugn trigger post-domains-update "$APP" "clear"
dokku_log_info1 "Cleared domains in $APP"
}
domains_clear_cmd "$@"

View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
domains_main_cmd() {
declare desc="print app domains"
local cmd="domains"
local APP="$2"
if [[ "$(is_global_vhost_enabled)" == "true" ]]; then
dokku_log_info2_quiet "Global Domain Name"
get_global_vhost
fi
if [[ -n "$APP" ]]; then
verify_app_name "$APP"
if [[ -f "$DOKKU_ROOT/$APP/VHOST" ]]; then
dokku_log_info2_quiet "$APP Domain Names"
get_app_domains "$APP"
else
dokku_log_fail "No domain names set for $APP"
fi
fi
}
domains_main_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"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
domains_disable_cmd() {
declare desc="disable domains/VHOST support via command line"
local cmd="domains:disable"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_disable "$2"
}
domains_disable_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"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
domains_enable_cmd() {
declare desc="enable domains/VHOST support via command line"
local cmd="domains:enable"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_enable "$2"
}
domains_enable_cmd "$@"

View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
domains_remove_cmd() {
declare desc="removes domains from app via command line"
local cmd="domains:remove"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
if [[ -z "${*:3}" ]]; then
echo "Usage: dokku $1 $2 DOMAIN [DOMAIN ...]"
echo "Must specify DOMAIN."
exit 1
fi
shift 1
domains_remove "$@"
}
domains_remove_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"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
domains_set_global_cmd() {
declare desc="set global domain name from command line"
local cmd="domains:set-global"
[[ -z $2 ]] && dokku_log_fail "Please specify a global domain name"
domains_set_global "$2"
}
domains_set_global_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"
source "$PLUGIN_AVAILABLE_PATH/domains/functions"
domains_setup_cmd() {
declare desc="setup domains to default state via command line"
local cmd="domains:setup"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
domains_setup "$2"
}
domains_setup_cmd "$@"

View File

@@ -1,38 +1,8 @@
#!/usr/bin/env bash
[[ " enter help enter:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help enter:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
case "$1" in
enter)
APP="$2"; CONTAINER_TYPE="$3"; IMAGE_TAG=$(get_running_image_tag "$APP"); IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP"
[[ ! -n "$3" ]] && dokku_log_fail "No container id specified"
if [[ "$3" == "--container-id" ]]; then
[[ ! -n "$4" ]] && dokku_log_fail "No container id specified"
DOKKU_APP_CIDS=( $(get_app_container_ids "$APP") )
printf -- '%s\n' "${DOKKU_APP_CIDS[@]}" | grep -q -e "^$4" || dokku_log_fail "Invalid container id for app"
ID=$(printf -- '%s\n' "${DOKKU_APP_CIDS[@]}" | grep -e "^$4")
shift 4
else
DOKKU_APP_CIDS=( $(get_app_container_ids "$APP" "$CONTAINER_TYPE") )
ID=${DOKKU_APP_CIDS[0]}
[[ ! -n $ID ]] && dokku_log_fail "No containers found for type '$CONTAINER_TYPE'"
shift 3
fi
docker ps -aq --no-trunc | grep -e "^$ID" > /dev/null || dokku_log_fail "Container does not exist"
docker ps -q --no-trunc | grep -e "^$ID" > /dev/null || dokku_log_fail "Container is not running"
EXEC_CMD=""
has_tty && DOKKU_RUN_OPTS+=" -i -t"
is_image_herokuish_based "$IMAGE" && EXEC_CMD="/exec"
docker exec "$DOKKU_RUN_OPTS" $ID $EXEC_CMD "${@:-/bin/bash}"
;;
help | enter:help)
cat<<EOF
enter <app> [<container-type> || --container-id <container-id>], Connect to a specific app container

View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
enter_default_cmd() {
declare desc="enters running app container of specified proc type"
local cmd="enter"
local APP="$2"; local CONTAINER_TYPE="$3"; local IMAGE_TAG=$(get_running_image_tag "$APP"); local IMAGE=$(get_app_image_name "$APP" "$IMAGE_TAG")
verify_app_name "$APP"
[[ ! -n "$3" ]] && dokku_log_fail "No container id specified"
if [[ "$3" == "--container-id" ]]; then
[[ ! -n "$4" ]] && dokku_log_fail "No container id specified"
local DOKKU_APP_CIDS=( $(get_app_container_ids "$APP") )
printf -- '%s\n' "${DOKKU_APP_CIDS[@]}" | grep -q -e "^$4" || dokku_log_fail "Invalid container id for app"
local ID=$(printf -- '%s\n' "${DOKKU_APP_CIDS[@]}" | grep -e "^$4")
shift 4
else
local DOKKU_APP_CIDS=( $(get_app_container_ids "$APP" "$CONTAINER_TYPE") )
local ID=${DOKKU_APP_CIDS[0]}
[[ ! -n $ID ]] && dokku_log_fail "No containers found for type '$CONTAINER_TYPE'"
shift 3
fi
docker ps -aq --no-trunc | grep -e "^$ID" > /dev/null || dokku_log_fail "Container does not exist"
docker ps -q --no-trunc | grep -e "^$ID" > /dev/null || dokku_log_fail "Container is not running"
local EXEC_CMD=""
has_tty && local DOKKU_RUN_OPTS+=" -i -t"
is_image_herokuish_based "$IMAGE" && local EXEC_CMD="/exec"
# shellcheck disable=SC2086
docker exec $DOKKU_RUN_OPTS $ID $EXEC_CMD "${@:-/bin/bash}"
}
enter_default_cmd "$@"

View File

@@ -4,18 +4,19 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/apps/functions"
git_build_app_repo() {
declare desc="builds local git app repo for app"
verify_app_name "$1"
APP="$1"; REV="$2"
local APP="$1"; local REV="$2"
# clean up after ourselves
TMP_WORK_DIR=$(mktemp -d -t "dokku_git.XXXX")
local TMP_WORK_DIR=$(mktemp -d -t "dokku_git.XXXX")
trap 'rm -rf "$TMP_WORK_DIR" > /dev/null' RETURN INT TERM EXIT
# git clone - this method creates a new git repository and adds the primary
# repo as a remote, then does a fetch depth=1 to avoid cloning
# the entire repo
TMP_TAG="dokku/$REV"
local TMP_TAG="dokku/$REV"
chmod 755 "$TMP_WORK_DIR"
unset GIT_DIR GIT_WORK_TREE
pushd "$TMP_WORK_DIR" > /dev/null
@@ -40,78 +41,109 @@ git_build_app_repo() {
fi
}
case "$1" in
git-hook)
APP=$2
git_hook_cmd() {
declare 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() {
declare 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() {
declare 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() {
declare 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() {
declare 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(){
declare 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,67 +1,19 @@
#!/usr/bin/env bash
[[ " logs help logs:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help logs:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$(dirname "$0")/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
usage() {
declare desc="logs specific usage"
echo "Usage: dokku logs <app>"
echo " display recent log output"
echo ""
echo " -n, --num NUM # the number of lines to display"
echo " -p, --ps PS # only display logs from the given process"
echo " -t, --tail # continually stream logs"
echo " -q, --quiet # display raw logs without colors, time and names"
}
case "$1" in
logs)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
APP="$2"; verify_app_name "$2"
APP_ROOT="$DOKKU_ROOT/$APP"
COLORS=(36 33 32 35 31)
if ! (is_deployed "$APP"); then
echo "Application's container not found"
exit 1
fi
shift 2;
TEMP=$(getopt -o htqn:p: --long help,tail,quiet,num:,ps: -n 'dokku logs' -- "$@")
if [[ $? != 0 ]]; then usage >&2 ; exit 1 ; fi
eval set -- "$TEMP"
DOKKU_LOGS_LINE_NUMBERS="100"
while true; do
case "$1" in
-t|--tail) DOKKU_LOGS_ARGS+="--follow "; shift ;;
-n|--num) DOKKU_LOGS_LINE_NUMBERS="$2"; shift 2 ;;
-p|--ps) DOKKU_LOGS_ONLY_PROCESS="$2"; shift 2 ;;
-q|--quiet) DOKKU_LOGS_NO_PRETTY_PRINT="true"; shift ;;
--) shift; break ;;
*) echo "Internal error"; exit 1;;
esac
done
if [[ -n $DOKKU_LOGS_ONLY_PROCESS ]]; then
CONTAINERS=("$APP_ROOT/CONTAINER.$DOKKU_LOGS_ONLY_PROCESS".*)
else
CONTAINERS=("$APP_ROOT"/CONTAINER.*)
fi
[[ -z $(stat -t "${CONTAINERS[0]}" 2>/dev/null) ]] && exit 0
DOKKU_LOGS_ARGS+="--tail $DOKKU_LOGS_LINE_NUMBERS"
((MAX_INDEX=${#CONTAINERS[*]} - 1)) || true
for i in ${!CONTAINERS[*]}; do
DYNO=$(echo "${CONTAINERS[i]}" | sed -r 's/.*CONTAINER\.(.*)/\1/')
CID=$(< "${CONTAINERS[i]}")
COLOR=${COLORS[i % ${#COLORS[*]}]}
if [[ $DOKKU_LOGS_NO_PRETTY_PRINT == "true" ]]; then
DOKKU_LOGS_CMD+="(docker logs $DOKKU_LOGS_ARGS $CID 2>&1)"
else
DOKKU_LOGS_PRETTY_PRINT_CMD="sed -r 's/^([^Z]+Z )/\x1b[${COLOR}m\1app[$DYNO]:\x1b[0m /gm'"
DOKKU_LOGS_CMD+="(docker logs -t $DOKKU_LOGS_ARGS $CID 2>&1 | $DOKKU_LOGS_PRETTY_PRINT_CMD)"
fi
if [[ $i != "$MAX_INDEX" ]]; then
DOKKU_LOGS_CMD+="& "
else
DOKKU_LOGS_CMD+="; "
fi
done
bash -c "($DOKKU_LOGS_CMD)"
;;
logs:help)
usage
;;

View File

@@ -1,12 +0,0 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
usage() {
echo "Usage: dokku logs <app>"
echo " display recent log output"
echo ""
echo " -n, --num NUM # the number of lines to display"
echo " -p, --ps PS # only display logs from the given process"
echo " -t, --tail # continually stream logs"
echo " -q, --quiet # display raw logs without colors, time and names"
}

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
logs_default_cmd() {
declare desc="shows the last logs for an app via command line"
local cmd="logs"
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
local APP="$2"; verify_app_name "$2"
local APP_ROOT="$DOKKU_ROOT/$APP"
local COLORS=(36 33 32 35 31)
if ! (is_deployed "$APP"); then
echo "Application's container not found"
exit 1
fi
shift 2;
local TEMP=$(getopt -o htqn:p: --long help,tail,quiet,num:,ps: -n 'dokku logs' -- "$@")
if [[ $? != 0 ]]; then usage >&2 ; exit 1 ; fi
eval set -- "$TEMP"
local DOKKU_LOGS_LINE_NUMBERS="100"
while true; do
case "$1" in
-t|--tail) local DOKKU_LOGS_ARGS+="--follow "; shift ;;
-n|--num) local DOKKU_LOGS_LINE_NUMBERS="$2"; shift 2 ;;
-p|--ps) local DOKKU_LOGS_ONLY_PROCESS="$2"; shift 2 ;;
-q|--quiet) local DOKKU_LOGS_NO_PRETTY_PRINT="true"; shift ;;
--) shift; break ;;
*) echo "Internal error"; exit 1;;
esac
done
if [[ -n $DOKKU_LOGS_ONLY_PROCESS ]]; then
local CONTAINERS=("$APP_ROOT/CONTAINER.$DOKKU_LOGS_ONLY_PROCESS".*)
else
local CONTAINERS=("$APP_ROOT"/CONTAINER.*)
fi
[[ -z $(stat -t "${CONTAINERS[0]}" 2>/dev/null) ]] && exit 0
local DOKKU_LOGS_ARGS+="--tail $DOKKU_LOGS_LINE_NUMBERS"
((MAX_INDEX=${#CONTAINERS[*]} - 1)) || true
for i in ${!CONTAINERS[*]}; do
local DYNO=$(echo "${CONTAINERS[i]}" | sed -r 's/.*CONTAINER\.(.*)/\1/')
local CID=$(< "${CONTAINERS[i]}")
local COLOR=${COLORS[i % ${#COLORS[*]}]}
if [[ $DOKKU_LOGS_NO_PRETTY_PRINT == "true" ]]; then
local DOKKU_LOGS_CMD+="(docker logs $DOKKU_LOGS_ARGS $CID 2>&1)"
else
local DOKKU_LOGS_PRETTY_PRINT_CMD="sed -r 's/^([^Z]+Z )/\x1b[${COLOR}m\1app[$DYNO]:\x1b[0m /gm'"
local DOKKU_LOGS_CMD+="(docker logs -t $DOKKU_LOGS_ARGS $CID 2>&1 | $DOKKU_LOGS_PRETTY_PRINT_CMD)"
fi
if [[ $i != "$MAX_INDEX" ]]; then
local DOKKU_LOGS_CMD+="& "
else
local DOKKU_LOGS_CMD+="; "
fi
done
bash -c "($DOKKU_LOGS_CMD)"
}
logs_default_cmd "$@"

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() {
declare 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

@@ -1,21 +1,8 @@
#!/usr/bin/env bash
[[ " nginx:build-config nginx:access-logs nginx:error-logs help nginx:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help nginx: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/config/functions"
source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
case "$1" in
nginx:build-config)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
nginx_build_config "$2"
;;
nginx:access-logs|nginx:error-logs)
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
nginx_logs "$@"
;;
help | nginx:help)
cat<<EOF
nginx:build-config <app>, (Re)builds nginx config for given app

View File

@@ -7,7 +7,7 @@ source "$PLUGIN_AVAILABLE_PATH/domains/functions"
source "$PLUGIN_AVAILABLE_PATH/ps/functions"
validate_nginx() {
local desc="validate entire nginx config"
declare desc="validate entire nginx config"
set +e
sudo /usr/sbin/nginx -t > /dev/null 2>&1
local exit_code=$?
@@ -19,7 +19,7 @@ validate_nginx() {
}
restart_nginx() {
local desc="restart nginx for given distros"
declare desc="restart nginx for given distros"
case "$DOKKU_DISTRO" in
debian)
sudo /usr/sbin/invoke-rc.d nginx reload > /dev/null
@@ -40,23 +40,23 @@ restart_nginx() {
}
nginx_logs() {
local desc="display app nginx logs"
declare desc="display app nginx logs"
local APP="$2"; verify_app_name "$APP"
local NGINX_LOGS_TYPE=${1#nginx:}
local NGINX_LOGS_TYPE=${NGINX_LOGS_TYPE%-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"
}
configure_nginx_ports() {
local desc="configure nginx listening ports"
declare desc="configure nginx listening ports"
local APP=$1; verify_app_name "$APP"
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")"
local DOKKU_NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT)
@@ -89,7 +89,7 @@ configure_nginx_ports() {
}
validate_ssl_domains() {
local desc="check configured domains against SSL cert contents and show warning if mismatched"
declare desc="check configured domains against SSL cert contents and show warning if mismatched"
local APP=$1; verify_app_name "$APP"
local SSL_HOSTNAME=$(get_ssl_hostnames "$APP")
local SSL_HOSTNAME_REGEX=$(echo "$SSL_HOSTNAME" | xargs | sed 's|\.|\\.|g' | sed 's/\*/\[^\.\]\*/g' | sed 's/ /|/g')
@@ -110,6 +110,7 @@ validate_ssl_domains() {
}
get_custom_nginx_template() {
declare desc="attempts to copy custom nginx template from app image"
local APP="$1"; verify_app_name "$APP"
local DESTINATION="$2"
local IMAGE_TAG="$(get_running_image_tag "$APP")"
@@ -120,7 +121,7 @@ get_custom_nginx_template() {
}
nginx_build_config() {
local desc="build nginx config to proxy app containers using sigil"
declare desc="build nginx config to proxy app containers using sigil"
local APP="$1"; verify_app_name "$APP"
local DOKKU_APP_LISTEN_PORT="$2"; local DOKKU_APP_LISTEN_IP="$3"
local VHOST_PATH="$DOKKU_ROOT/$APP/VHOST"; local URLS_PATH="$DOKKU_ROOT/$APP/URLS"

View File

@@ -6,6 +6,8 @@ source "$PLUGIN_AVAILABLE_PATH/nginx-vhosts/functions"
source "$PLUGIN_AVAILABLE_PATH/proxy/functions"
nginx_post_deploy() {
declare 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() {
declare 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() {
local desc="disable nginx proxy"
nginx_proxy_disable() {
declare 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() {
local desc="enable nginx proxy"
nginx_proxy_enable() {
declare 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

@@ -0,0 +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/nginx-vhosts/functions"
nginx_logs_cmd() {
declare desc="display app nginx logs from command line"
local cmd="$1"
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
nginx_logs "$@"
}
nginx_logs_cmd "$@"

View File

@@ -0,0 +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/nginx-vhosts/functions"
nginx_build_config_cmd() {
declare desc="build nginx config to proxy app containers from command line"
local cmd="nginx:build-config"
[[ -z $2 ]] && echo "Please specify an app to run the command on" && exit 1
nginx_build_config "$2"
}
nginx_build_config_cmd "$@"

View File

@@ -0,0 +1 @@
access-logs

View File

@@ -1,66 +1,8 @@
#!/usr/bin/env bash
[[ " plugin plugin:install plugin:install-dependencies plugin:update plugin:disable plugin:enable plugin:uninstall help plugin:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help plugin: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/plugin/functions"
case "$1" in
plugin)
plugn version
plugn list
;;
plugin:install)
case "$2" in
--core)
[[ "$#" -gt 2 ]] && dokku_log_info1_quiet "Cannot install additional core plugins, running core plugin install trigger"
PLUGIN_PATH="$PLUGIN_CORE_PATH" plugn trigger install
;;
https:*|git*|ssh:*)
shift
download_and_enable_plugin "$@"
plugn trigger install
;;
*)
plugn trigger install
;;
esac
;;
plugin:install-dependencies)
if [[ $2 == "--core" ]]; then
export PLUGIN_PATH="$PLUGIN_CORE_PATH"
fi
plugn trigger dependencies
;;
plugin:update)
if [[ -n "$2" ]]; then
PLUGIN="$2"
PLUGIN_COMMITTISH="$3"
plugn update "$PLUGIN" "$PLUGIN_COMMITTISH"
fi
plugn trigger update
;;
plugin:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify a plugin to disable"
PLUGIN="$2"
disable_plugin "$PLUGIN"
;;
plugin:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify a plugin to enable"
PLUGIN="$2"
enable_plugin "$PLUGIN"
;;
plugin:uninstall)
[[ -z $2 ]] && dokku_log_fail "Please specify a plugin to enable"
PLUGIN="$2"
uninstall_plugin "$PLUGIN"
;;
help | plugin:help)
cat<<EOF
plugin, Print active plugins

View File

@@ -3,6 +3,7 @@ set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
disable_plugin() {
declare desc="disables specified plugin name"
local PLUGIN="$1"
[[ -e $PLUGIN_CORE_AVAILABLE_PATH/$PLUGIN ]] && dokku_log_fail "Cannot disable a core plugin"
[[ ! -e $PLUGIN_ENABLED_PATH/$PLUGIN ]] && dokku_log_fail "Plugin already disabled"
@@ -12,6 +13,7 @@ disable_plugin() {
}
enable_plugin() {
declare desc="enables specified plugin name"
local PLUGIN="$1"
[[ -e $PLUGIN_ENABLED_PATH/$PLUGIN ]] && dokku_log_fail "Plugin already enabled"
[[ ! -e $PLUGIN_AVAILABLE_PATH/$PLUGIN ]] && dokku_log_fail "Plugin does not exist"
@@ -20,12 +22,14 @@ enable_plugin() {
}
download_plugin() {
declare desc="download plugin from URL and set name"
local PLUGIN_GIT_URL="$1"
local PLUGIN_NAME="$2"
plugn install "$PLUGIN_GIT_URL" "$PLUGIN_NAME"
}
download_and_enable_plugin() {
declare desc="wrapper to download and enable specified version of plugin"
local PLUGIN_GIT_URL="$1"
shift
while getopts ":-:" opt "$@"; do
@@ -54,6 +58,7 @@ download_and_enable_plugin() {
}
update_plugin() {
declare desc="update plugin"
local PLUGIN="$1"
local PLUGIN_COMMITTISH="$2"
[[ ! -e $PLUGIN_AVAILABLE_PATH/$PLUGIN ]] && dokku_log_fail "Plugin ($PLUGIN) is not currently installed"
@@ -61,6 +66,7 @@ update_plugin() {
}
uninstall_plugin() {
declare desc="uninstall plugin"
local PLUGIN="$1"
[[ -e $PLUGIN_CORE_AVAILABLE_PATH/$PLUGIN ]] && dokku_log_fail "Cannot uninstall a core plugin"
[[ ! -e $PLUGIN_AVAILABLE_PATH/$PLUGIN ]] && dokku_log_fail "Plugin ($PLUGIN) is not currently installed"
@@ -69,6 +75,7 @@ uninstall_plugin() {
}
plugin_name() {
declare desc="default plugin name"
local PLUGIN_GIT_URL="$1"
echo "$PLUGIN_GIT_URL" | awk -F '/' '{ print $NF }' | sed -e "s:.git::g" | sed 's:^dokku-::'
}

View File

@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
plugin_main_cmd() {
declare desc="shows details about locally installed plugins"
local cmd="plugin"
plugn version
plugn list
}
plugin_main_cmd "$@"

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/plugin/functions"
plugin_disable_cmd() {
declare desc="disables plugin via command line"
local cmd="plugin:disable"
[[ -z $2 ]] && dokku_log_fail "Please specify a plugin to disable"
local PLUGIN="$2"
disable_plugin "$PLUGIN"
}
plugin_disable_cmd "$@"

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/plugin/functions"
plugin_enable_cmd() {
declare desc="enables plugin via command line"
local cmd="plugin:enable"
[[ -z $2 ]] && dokku_log_fail "Please specify a plugin to enable"
local PLUGIN="$2"
enable_plugin "$PLUGIN"
}
plugin_enable_cmd "$@"

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/plugin/functions"
plugin_install_cmd() {
declare desc="installs a plugin from URL and calls install plugin trigger via command line"
local cmd="plugin:install"
case "$2" in
--core)
[[ "$#" -gt 2 ]] && dokku_log_info1_quiet "Cannot install additional core plugins, running core plugin install trigger"
PLUGIN_PATH="$PLUGIN_CORE_PATH" plugn trigger install
;;
https:*|git*|ssh:*)
shift
download_and_enable_plugin "$@"
plugn trigger install
;;
*)
plugn trigger install
;;
esac
}
plugin_install_cmd "$@"

View File

@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
plugin_install_dependencies_cmd() {
declare desc="calls dependencies plugin trigger via command line"
local cmd="plugin:install-dependencies"
if [[ $2 == "--core" ]]; then
export PLUGIN_PATH="$PLUGIN_CORE_PATH"
fi
plugn trigger dependencies
}
plugin_install_dependencies_cmd "$@"

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/plugin/functions"
plugin_uninstall_cmd() {
declare desc="uninstalls plugin via command line"
local cmd="plugin:uninstall"
[[ -z $2 ]] && dokku_log_fail "Please specify a plugin to enable"
local PLUGIN="$2"
uninstall_plugin "$PLUGIN"
}
plugin_uninstall_cmd "$@"

View File

@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
plugin_update_cmd() {
declare desc="updates plugin to optional committish and calls update plugin trigger via command line"
local cmd="plugin:update"
if [[ -n "$2" ]]; then
local PLUGIN="$2"
local PLUGIN_COMMITTISH="$3"
plugn update "$PLUGIN" "$PLUGIN_COMMITTISH"
fi
plugn trigger update
}
plugin_update_cmd "$@"

View File

@@ -1,29 +1,8 @@
#!/usr/bin/env bash
[[ " proxy proxy:set proxy:enable proxy:disable help proxy:help " == *" $1 "* ]] || exit "$DOKKU_NOT_IMPLEMENTED_EXIT"
[[ " help proxy: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/proxy/functions"
case "$1" in
proxy)
proxy_main "$2"
;;
proxy:set)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_set "$2"
;;
proxy:enable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_enable "$2" --no-restart
;;
proxy:disable)
[[ -z $2 ]] && dokku_log_fail "Please specify an app to run the command on"
proxy_disable "$2" --no-restart
;;
help | proxy:help)
cat<<EOF
proxy <app>, Show proxy for app

View File

@@ -4,7 +4,7 @@ source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
is_app_proxy_enabled() {
local desc="return true if proxy is enabled; otherwise return false"
declare desc="return true if proxy is enabled; otherwise return false"
local APP="$1"; verify_app_name "$APP"
local APP_PROXY_ENABLED=true
@@ -16,61 +16,9 @@ is_app_proxy_enabled() {
}
get_app_proxy_type() {
local desc="return app proxy type"
declare desc="return app proxy type"
local APP="$1"; verify_app_name "$APP"
local APP_PROXY_TYPE="nginx"
echo $APP_PROXY_TYPE
}
proxy_main() {
local desc="displays app proxy implementation"
local ALL_APPS=$(dokku_apps)
if [[ -n "$1" ]]; then
local APP="$1"
fi
local APPS=${APP:="$ALL_APPS"}
dokku_col_log_info1_quiet "App Name" "Proxy Type"
for app in $APPS; do
verify_app_name "$app"
dokku_col_log_msg "$app" "$(get_app_proxy_type "$app")"
done
}
proxy_set() {
local desc="enable proxy for app"
local APP="$1"; verify_app_name "$APP"
dokku_log_info1 "proxy:set not implemented"
}
proxy_enable() {
local desc="enable proxy for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_proxy_enabled "$APP")" == "false" ]]; then
dokku_log_info1 "Enabling proxy for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
# shellcheck disable=SC2086
config_unset $CONFIG_SET_ARGS $APP DOKKU_DISABLE_PROXY
plugn trigger proxy-enable "$APP"
else
dokku_log_info1 "proxy is already enabled for app ($APP)"
fi
}
proxy_disable() {
local desc="disable proxy for app"
local APP="$1"; verify_app_name "$APP"
if [[ "$(is_app_proxy_enabled "$APP")" == "true" ]]; then
dokku_log_info1 "Disabling proxy for app ($APP)"
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
# shellcheck disable=SC2086
config_set $CONFIG_SET_ARGS $APP DOKKU_DISABLE_PROXY=1
plugn trigger proxy-disable "$APP"
else
dokku_log_info1 "proxy is already disable for app ($APP)"
fi
}

Some files were not shown because too many files have changed in this diff Show More