2015-02-05 11:32:46 -08:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
has_tty() {
|
2015-02-05 11:32:46 -08:00
|
|
|
if [[ "$(/usr/bin/tty || true)" == "not a tty" ]]; then
|
|
|
|
|
return 1
|
|
|
|
|
else
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
dokku_log_info1() {
|
2015-02-05 11:32:46 -08:00
|
|
|
echo "-----> $@"
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
dokku_log_info2() {
|
2015-02-05 11:32:46 -08:00
|
|
|
echo "=====> $@"
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
dokku_log_info1_quiet() {
|
2015-09-14 21:20:35 -07:00
|
|
|
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
|
2015-02-05 12:38:59 -08:00
|
|
|
echo "-----> $@"
|
|
|
|
|
else
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
dokku_log_info2_quiet() {
|
2015-09-14 21:20:35 -07:00
|
|
|
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
|
2015-02-05 12:38:59 -08:00
|
|
|
echo "=====> $@"
|
|
|
|
|
else
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-24 10:49:18 -07:00
|
|
|
dokku_col_log_info1() {
|
|
|
|
|
printf "%-25s %-25s %-25s %-25s\n" "-----> $@"
|
2015-02-07 14:09:39 -08:00
|
|
|
}
|
|
|
|
|
|
2015-04-24 10:49:18 -07:00
|
|
|
dokku_col_log_info1_quiet() {
|
2015-09-14 21:20:35 -07:00
|
|
|
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
|
2015-04-24 10:49:18 -07:00
|
|
|
printf "%-25s %-25s %-25s %-25s\n" "-----> $@"
|
2015-02-07 14:09:39 -08:00
|
|
|
else
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-24 10:49:18 -07:00
|
|
|
dokku_col_log_info2() {
|
|
|
|
|
printf "%-25s %-25s %-25s %-25s\n" "=====> $@"
|
2015-02-07 14:09:39 -08:00
|
|
|
}
|
|
|
|
|
|
2015-04-24 10:49:18 -07:00
|
|
|
dokku_col_log_info2_quiet() {
|
2015-09-14 21:20:35 -07:00
|
|
|
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
|
2015-04-24 10:49:18 -07:00
|
|
|
printf "%-25s %-25s %-25s %-25s\n" "=====> $@"
|
2015-02-07 14:09:39 -08:00
|
|
|
else
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-24 10:49:18 -07:00
|
|
|
dokku_col_log_msg() {
|
|
|
|
|
printf "%-25s %-25s %-25s %-25s\n" "$@"
|
2015-02-07 14:09:39 -08:00
|
|
|
}
|
|
|
|
|
|
2015-04-24 10:49:18 -07:00
|
|
|
dokku_col_log_msg_quiet() {
|
2015-09-14 21:20:35 -07:00
|
|
|
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
|
2015-04-24 10:49:18 -07:00
|
|
|
printf "%-25s %-25s %-25s %-25s\n" "$@"
|
2015-02-07 14:09:39 -08:00
|
|
|
else
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-20 08:29:35 -07:00
|
|
|
dokku_log_verbose_quiet() {
|
2015-09-14 21:20:35 -07:00
|
|
|
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
|
2015-03-20 08:29:35 -07:00
|
|
|
echo " $@"
|
|
|
|
|
else
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
dokku_log_verbose() {
|
2015-02-05 11:32:46 -08:00
|
|
|
echo " $@"
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
dokku_log_warn() {
|
2015-09-06 19:40:44 -04:00
|
|
|
echo " ! $@"
|
2015-02-05 11:32:46 -08:00
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
dokku_log_fail() {
|
2015-02-05 11:32:46 -08:00
|
|
|
echo "$@" 1>&2
|
|
|
|
|
exit 1
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-26 13:14:04 +01:00
|
|
|
dokku_log_event() {
|
2015-06-26 15:14:51 +01:00
|
|
|
logger -t dokku -i -- "$@"
|
2015-06-26 13:14:04 +01:00
|
|
|
}
|
|
|
|
|
|
2015-09-07 03:55:37 -04:00
|
|
|
dokku_log_plugn_trigger_call() {
|
2015-06-26 13:14:04 +01:00
|
|
|
local l_hook
|
|
|
|
|
|
|
|
|
|
l_hook="$1" ; shift
|
|
|
|
|
dokku_log_event "INVOKED: ${l_hook}( $@ )"
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-20 08:29:35 -07:00
|
|
|
dokku_container_log_verbose_quiet() {
|
2015-09-03 18:55:52 -07:00
|
|
|
local CID=$1;
|
2015-03-20 08:29:35 -07:00
|
|
|
shift
|
|
|
|
|
|
|
|
|
|
OIFS=$IFS
|
|
|
|
|
IFS=$'\n'
|
|
|
|
|
for line in $(docker logs $CID 2>&1); do
|
|
|
|
|
dokku_log_verbose_quiet "$line"
|
|
|
|
|
done
|
|
|
|
|
IFS=$OIFS
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
verify_app_name() {
|
2015-09-03 16:07:23 -07:00
|
|
|
local APP="$1"
|
2015-04-21 10:58:11 -07:00
|
|
|
[[ ! -n "$APP" ]] && dokku_log_fail "(verify_app_name) APP must not be null"
|
2015-02-06 08:28:14 -08:00
|
|
|
[[ ! -d "$DOKKU_ROOT/$APP" ]] && dokku_log_fail "App $APP does not exist"
|
2015-06-10 14:21:47 -07:00
|
|
|
|
2015-02-05 11:32:46 -08:00
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-21 20:25:05 -07:00
|
|
|
verify_image() {
|
|
|
|
|
local IMAGE="$1"
|
2015-06-10 14:21:47 -07:00
|
|
|
if (docker inspect "$IMAGE" &>/dev/null); then
|
2015-04-18 15:39:08 -07:00
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-03 17:05:49 -07:00
|
|
|
get_app_image_repo() {
|
|
|
|
|
# central definition of our image repo pattern
|
2015-09-03 18:55:52 -07:00
|
|
|
local APP="$1"; local IMAGE_REPO="dokku/$APP"
|
2015-09-03 17:05:49 -07:00
|
|
|
[[ -z "$APP" ]] && dokku_log_fail "(get_app_image_repo) APP must not be null"
|
|
|
|
|
echo $IMAGE_REPO
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get_app_image_name() {
|
2015-09-03 16:07:23 -07:00
|
|
|
# return image identifier for a given app, tag tuple. validate if tag is presented
|
2015-09-03 17:05:49 -07:00
|
|
|
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"
|
2015-09-03 16:07:23 -07:00
|
|
|
|
|
|
|
|
if [[ -n "$IMAGE_TAG" ]]; then
|
2015-09-03 17:05:49 -07:00
|
|
|
IMAGE="$IMAGE_REPO:$IMAGE_TAG"
|
2015-09-03 16:07:23 -07:00
|
|
|
verify_image "$IMAGE" || dokku_log_fail "app image ($IMAGE) not found"
|
|
|
|
|
else
|
2015-09-03 17:05:49 -07:00
|
|
|
IMAGE="$IMAGE_REPO:latest"
|
2015-09-03 16:07:23 -07:00
|
|
|
fi
|
|
|
|
|
echo $IMAGE
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-10 14:21:47 -07:00
|
|
|
get_running_image_tag() {
|
2015-09-03 16:07:23 -07:00
|
|
|
# retrieve current image tag for a given app. returns empty string if no deployed containers are found
|
2015-06-10 14:21:47 -07:00
|
|
|
local APP="$1"
|
|
|
|
|
[[ ! -n "$APP" ]] && dokku_log_fail "(get_running_image_tag) APP must not be null"
|
|
|
|
|
verify_app_name "$APP"
|
|
|
|
|
|
2015-09-03 16:07:23 -07:00
|
|
|
CIDS=( $(get_app_container_ids $APP) )
|
2015-06-10 14:21:47 -07:00
|
|
|
RUNNING_IMAGE_TAG=$(docker ps -a --no-trunc | egrep ${CIDS[0]} 2>/dev/null | awk '{ print $2 }' | awk -F: '{ print $2 }' || echo '')
|
|
|
|
|
echo $RUNNING_IMAGE_TAG
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-20 16:32:18 -07:00
|
|
|
is_image_herokuish_based() {
|
2015-02-07 10:47:04 -08:00
|
|
|
# circleci can't support --rm as they run lxc in lxc
|
|
|
|
|
[[ ! -f "/home/ubuntu/.circlerc" ]] && local DOCKER_ARGS="--rm"
|
2015-08-03 11:40:30 -07:00
|
|
|
docker run --entrypoint="/bin/sh" $DOCKER_ARGS "$@" -c "test -f /exec"
|
2015-02-07 10:47:04 -08:00
|
|
|
}
|
|
|
|
|
|
2015-04-18 15:39:08 -07:00
|
|
|
is_number() {
|
|
|
|
|
local NUMBER=$1; local NUM_RE='^[0-9]+$'
|
2015-09-14 21:20:35 -07:00
|
|
|
if [[ $NUMBER =~ $NUM_RE ]]; then
|
2015-04-18 15:39:08 -07:00
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-07 10:57:30 -08:00
|
|
|
parse_args() {
|
2015-02-05 11:32:46 -08:00
|
|
|
for arg in "$@"; do
|
|
|
|
|
case "$arg" in
|
2015-02-09 16:59:07 -08:00
|
|
|
--quiet)
|
2015-02-05 11:32:46 -08:00
|
|
|
export DOKKU_QUIET_OUTPUT=1
|
|
|
|
|
;;
|
2015-02-09 16:59:07 -08:00
|
|
|
--trace)
|
2015-02-05 11:32:46 -08:00
|
|
|
export DOKKU_TRACE=1
|
|
|
|
|
;;
|
2015-02-07 09:26:22 -08:00
|
|
|
--rm-container|--rm)
|
2015-02-05 11:32:46 -08:00
|
|
|
export DOKKU_RM_CONTAINER=1
|
|
|
|
|
;;
|
2015-02-09 16:59:07 -08:00
|
|
|
--force)
|
2015-02-05 11:32:46 -08:00
|
|
|
export DOKKU_APPS_FORCE_DELETE=1
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
done
|
|
|
|
|
return 0
|
|
|
|
|
}
|
2015-04-17 15:23:59 -07:00
|
|
|
|
|
|
|
|
copy_from_image() {
|
2015-09-03 18:55:52 -07:00
|
|
|
local IMAGE="$1"; local SRC_FILE="$2"; local DST_DIR="$3"
|
|
|
|
|
verify_app_name $APP
|
2015-04-17 15:23:59 -07:00
|
|
|
|
2015-04-21 20:25:05 -07:00
|
|
|
if verify_image "$IMAGE"; then
|
2015-04-18 10:37:17 -07:00
|
|
|
CID=$(docker run -d $IMAGE bash)
|
|
|
|
|
docker cp "$CID:$SRC_FILE" "$DST_DIR"
|
|
|
|
|
docker rm -f "$CID" &> /dev/null
|
|
|
|
|
else
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
2015-04-17 15:23:59 -07:00
|
|
|
}
|
2015-04-17 18:57:37 -07:00
|
|
|
|
2015-07-13 08:24:46 -07:00
|
|
|
get_app_container_ids() {
|
2015-09-03 18:55:52 -07:00
|
|
|
local APP="$1"; local CONTAINER_TYPE="$2"
|
2015-04-17 18:57:37 -07:00
|
|
|
verify_app_name $APP
|
|
|
|
|
[[ -f $DOKKU_ROOT/$APP/CONTAINER ]] && DOKKU_CIDS+=$(< $DOKKU_ROOT/$APP/CONTAINER)
|
|
|
|
|
|
2015-08-25 23:00:49 -04:00
|
|
|
if [[ -n "$CONTAINER_TYPE" ]]; then
|
2015-08-25 23:31:53 -04:00
|
|
|
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE.*"
|
2015-08-25 23:00:49 -04:00
|
|
|
if [[ $CONTAINER_TYPE == *.* ]]; then
|
2015-08-25 23:31:53 -04:00
|
|
|
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE"
|
2015-08-25 23:00:49 -04:00
|
|
|
[[ ! -f $CONTAINER_PATTERN ]] && echo "" && return 0
|
|
|
|
|
fi
|
|
|
|
|
else
|
2015-08-25 23:31:53 -04:00
|
|
|
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.*"
|
2015-08-25 23:00:49 -04:00
|
|
|
fi
|
|
|
|
|
|
2015-04-17 18:57:37 -07:00
|
|
|
shopt -s nullglob
|
2015-08-25 23:00:49 -04:00
|
|
|
for DOKKU_CID_FILE in $CONTAINER_PATTERN; do
|
2015-04-17 18:57:37 -07:00
|
|
|
DOKKU_CIDS+=" "
|
|
|
|
|
DOKKU_CIDS+=$(< $DOKKU_CID_FILE)
|
|
|
|
|
DOKKU_CIDS+=" "
|
|
|
|
|
done
|
|
|
|
|
shopt -u nullglob
|
|
|
|
|
echo $DOKKU_CIDS
|
|
|
|
|
}
|
2015-07-12 15:56:52 -07:00
|
|
|
|
|
|
|
|
get_dockerfile_exposed_port() {
|
|
|
|
|
local DOCKERFILE_PORT=$(grep "^EXPOSE \+[[:digit:]]\+\(\/tcp\)\? *$" $1 | head -1 | sed 's/EXPOSE \+\([[:digit:]]\+\)\(\/tcp\)\?.*/\1/' || true)
|
2015-07-13 08:24:46 -07:00
|
|
|
echo "$DOCKERFILE_PORT"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get_app_running_container_ids() {
|
|
|
|
|
local APP=$1
|
|
|
|
|
verify_app_name $APP
|
|
|
|
|
|
|
|
|
|
! (is_deployed $APP) && dokku_log_fail "App $APP has not been deployed"
|
|
|
|
|
local CIDS=$(get_app_container_ids $APP)
|
|
|
|
|
|
2015-09-14 21:20:35 -07:00
|
|
|
for CID in $CIDS; do
|
2015-07-13 08:24:46 -07:00
|
|
|
local APP_CONTAINER_STATUS=$(docker inspect -f '{{.State.Running}}' "$CID" || true)
|
|
|
|
|
[[ "$APP_CONTAINER_STATUS" == "true" ]] && local APP_RUNNING_CONTAINER_IDS+="$CID "
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
echo "$APP_RUNNING_CONTAINER_IDS"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
is_deployed() {
|
2015-09-03 18:55:52 -07:00
|
|
|
local APP="$1"
|
2015-09-14 21:20:35 -07:00
|
|
|
if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]] || [[ $(ls $DOKKU_ROOT/$APP/CONTAINER.* &> /dev/null; echo $?) -eq 0 ]]; then
|
2015-07-13 08:24:46 -07:00
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
is_container_running () {
|
|
|
|
|
local CID=$1
|
|
|
|
|
local CONTAINER_STATUS=$(docker inspect -f '{{.State.Running}}' "$CID" || true)
|
|
|
|
|
|
|
|
|
|
if [[ "$CONTAINER_STATUS" == "true" ]]; then
|
|
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-29 02:31:03 -04:00
|
|
|
is_container_status () {
|
|
|
|
|
local CID=$1
|
|
|
|
|
local TEMPLATE="{{.State.$2}}"
|
|
|
|
|
local CONTAINER_STATUS=$(docker inspect -f "$TEMPLATE" "$CID" || true)
|
|
|
|
|
|
|
|
|
|
if [[ "$CONTAINER_STATUS" == "true" ]]; then
|
|
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
return 1
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-13 08:24:46 -07:00
|
|
|
is_app_running() {
|
|
|
|
|
local APP="$1"
|
|
|
|
|
verify_app_name $APP
|
|
|
|
|
|
|
|
|
|
local APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids $APP)
|
|
|
|
|
|
|
|
|
|
if [[ -n "$APP_RUNNING_CONTAINER_IDS" ]]; then
|
|
|
|
|
return 0
|
2015-07-12 15:56:52 -07:00
|
|
|
else
|
2015-07-13 08:24:46 -07:00
|
|
|
return 1
|
2015-07-12 15:56:52 -07:00
|
|
|
fi
|
|
|
|
|
}
|
2015-06-10 14:21:47 -07:00
|
|
|
|
|
|
|
|
release_and_deploy() {
|
2015-09-03 18:55:52 -07:00
|
|
|
local APP="$1"; local IMAGE_TAG="$2"; local IMAGE=$(get_app_image_name $APP $IMAGE_TAG)
|
2015-09-03 16:07:23 -07:00
|
|
|
verify_app_name "$APP"
|
2015-06-10 14:21:47 -07:00
|
|
|
|
|
|
|
|
if verify_image "$IMAGE"; then
|
|
|
|
|
if is_image_herokuish_based "$IMAGE"; then
|
|
|
|
|
IMAGE_SOURCE_TYPE="herokuish"
|
|
|
|
|
else
|
|
|
|
|
IMAGE_SOURCE_TYPE="dockerfile"
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
dokku_log_info1 "Releasing $APP ($IMAGE)..."
|
2015-09-03 16:07:23 -07:00
|
|
|
dokku release "$APP" "$IMAGE_SOURCE_TYPE" "$IMAGE_TAG"
|
2015-06-10 14:21:47 -07:00
|
|
|
dokku_log_info1 "Deploying $APP ($IMAGE)..."
|
2015-09-03 16:07:23 -07:00
|
|
|
dokku deploy "$APP" "$IMAGE_TAG"
|
2015-06-10 14:21:47 -07:00
|
|
|
dokku_log_info2 "Application deployed:"
|
2015-09-03 16:07:23 -07:00
|
|
|
dokku urls $APP | sed "s/^/ /"
|
2015-06-10 14:21:47 -07:00
|
|
|
echo
|
|
|
|
|
fi
|
|
|
|
|
}
|
2015-09-06 19:21:12 -04:00
|
|
|
|
|
|
|
|
docker_cleanup() {
|
2015-09-06 19:23:15 -04:00
|
|
|
# delete all non-running containers
|
2015-09-06 19:21:12 -04:00
|
|
|
# shellcheck disable=SC2046
|
2015-09-08 14:35:00 -04:00
|
|
|
docker rm $(docker ps -a -f 'status=exited' -q) &> /dev/null || true
|
2015-09-08 11:21:38 -04:00
|
|
|
|
2015-09-06 19:21:12 -04:00
|
|
|
# delete unused images
|
|
|
|
|
# shellcheck disable=SC2046
|
|
|
|
|
docker rmi $(docker images -f 'dangling=true' -q) &> /dev/null &
|
|
|
|
|
}
|
2015-09-17 19:09:29 -07:00
|
|
|
|
|
|
|
|
get_open_port() {
|
|
|
|
|
while true; do
|
|
|
|
|
local port=$(shuf -i 1025-65535 -n 1)
|
|
|
|
|
if ! nc -z 0.0.0.0 $port; then
|
|
|
|
|
echo $port
|
|
|
|
|
return 0
|
|
|
|
|
else
|
|
|
|
|
continue
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
}
|