Files
dokku/plugins/common/functions

688 lines
20 KiB
Plaintext
Raw Normal View History

#!/usr/bin/env bash
set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x
has_tty() {
local desc="return 0 if we have a tty"
if [[ "$(/usr/bin/tty || true)" == "not a tty" ]]; then
return 1
else
return 0
fi
}
dokku_apps() {
local desc="prints list of all local apps"
2016-02-22 10:16:57 -08:00
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() {
local desc="log info1 formatter"
echo "-----> $*"
}
dokku_log_info2() {
local desc="log info2 formatter"
echo "=====> $*"
}
dokku_log_info1_quiet() {
local desc="log info1 formatter (with quiet option)"
2015-09-14 21:20:35 -07:00
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
echo "-----> $*"
else
return 0
fi
}
dokku_log_info2_quiet() {
local desc="log info2 formatter (with quiet option)"
2015-09-14 21:20:35 -07:00
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
echo "=====> $*"
else
return 0
fi
}
dokku_col_log_info1() {
local desc="columnar log info1 formatter"
printf "%-6s %-18s %-25s %-25s %-25s\n" "----->" "$@"
}
dokku_col_log_info1_quiet() {
local desc="columnar log info1 formatter (with quiet option)"
2015-09-14 21:20:35 -07:00
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
printf "%-6s %-18s %-25s %-25s %-25s\n" "----->" "$@"
else
return 0
fi
}
dokku_col_log_info2() {
local desc="columnar log info2 formatter"
printf "%-6s %-18s %-25s %-25s %-25s\n" "=====>" "$@"
}
dokku_col_log_info2_quiet() {
local desc="columnar log info2 formatter (with quiet option)"
2015-09-14 21:20:35 -07:00
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
printf "%-6s %-18s %-25s %-25s %-25s\n" "=====>" "$@"
else
return 0
fi
}
dokku_col_log_msg() {
local desc="columnar log formatter"
printf "%-25s %-25s %-25s %-25s\n" "$@"
}
dokku_col_log_msg_quiet() {
local desc="columnar log formatter (with quiet option)"
2015-09-14 21:20:35 -07:00
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
printf "%-25s %-25s %-25s %-25s\n" "$@"
else
return 0
fi
}
dokku_log_verbose_quiet() {
local desc="log verbose formatter (with quiet option)"
2015-09-14 21:20:35 -07:00
if [[ -z "$DOKKU_QUIET_OUTPUT" ]]; then
echo " $*"
else
return 0
fi
}
dokku_log_verbose() {
local desc="log verbose formatter"
echo " $*"
}
dokku_log_warn() {
local desc="log warning formatter"
echo " ! $*"
}
dokku_log_fail() {
local desc="log fail formatter"
echo "$@" 1>&2
exit 1
}
dokku_log_event() {
local desc="log dokku events"
2015-06-26 15:14:51 +01:00
logger -t dokku -i -- "$@"
}
2015-09-07 03:55:37 -04:00
dokku_log_plugn_trigger_call() {
local desc="log plugn trigger calls"
local l_hook
l_hook="$1" ; shift
dokku_log_event "INVOKED: ${l_hook}( $* ) NAME=$NAME FINGERPRINT=$FINGERPRINT"
}
dokku_container_log_verbose_quiet() {
local desc="log verbose container output (with quiet option)"
2015-09-03 18:55:52 -07:00
local CID=$1;
shift
OIFS=$IFS
IFS=$'\n'
2016-02-22 10:16:57 -08:00
for line in $(docker logs "$CID" 2>&1); do
dokku_log_verbose_quiet "$line"
done
IFS=$OIFS
}
verify_app_name() {
local 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
[[ -d "$DOKKU_ROOT/$APP" ]] && rm -rf "$DOKKU_ROOT/$APP"
dokku_log_fail "App name must begin with lowercase alphanumeric character"
fi
[[ ! -d "$DOKKU_ROOT/$APP" ]] && dokku_log_fail "App $APP does not exist"
return 0
}
verify_image() {
local desc="verify image existence"
local IMAGE="$1"
if (docker inspect "$IMAGE" &>/dev/null); then
2015-04-18 15:39:08 -07:00
return 0
else
return 1
fi
}
get_app_image_repo() {
local desc="central definition of image repo pattern"
2015-09-03 18:55:52 -07:00
local APP="$1"; local IMAGE_REPO="dokku/$APP"
[[ -z "$APP" ]] && dokku_log_fail "(get_app_image_repo) APP must not be null"
2016-02-22 10:16:57 -08:00
echo "$IMAGE_REPO"
}
get_app_image_name() {
local desc="return image identifier for a given app, tag tuple. validate if tag is presented"
2016-02-22 10:16:57 -08: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"
if [[ -n "$IMAGE_TAG" ]]; then
IMAGE="$IMAGE_REPO:$IMAGE_TAG"
verify_image "$IMAGE" || dokku_log_fail "app image ($IMAGE) not found"
else
IMAGE="$IMAGE_REPO:latest"
fi
2016-02-22 10:16:57 -08:00
echo "$IMAGE"
}
get_running_image_tag() {
local 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"
2016-02-22 10:16:57 -08:00
CIDS=( $(get_app_container_ids "$APP") )
RUNNING_IMAGE_TAG=$(docker inspect -f '{{ .Config.Image }}' ${CIDS[0]} 2>/dev/null | awk -F: '{ print $2 }' || echo '')
2016-02-22 10:16:57 -08:00
echo "$RUNNING_IMAGE_TAG"
}
is_image_herokuish_based() {
local desc="returns true if app image is based on herokuish"
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"
2016-02-22 10:16:57 -08:00
docker run "$DOKKU_GLOBAL_RUN_ARGS" --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 desc="returns 0 if input is a number"
2015-04-18 15:39:08 -07:00
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
}
is_abs_path() {
local desc="returns 0 if input path is absolute"
local TEST_PATH=$1
if [[ "$TEST_PATH" = /* ]]; then
return 0
else
return 1
fi
}
parse_args() {
local 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
;;
--trace)
export DOKKU_TRACE=1
;;
--rm-container|--rm)
export DOKKU_RM_CONTAINER=1
;;
--force)
export DOKKU_APPS_FORCE_DELETE=1
;;
--app)
export DOKKU_APP_NAME=${args[$next_index]}; skip=true
;;
esac
next_index=$(( next_index + 1 ))
done
return 0
}
copy_from_image() {
local desc="copy file from named image to destination"
2015-09-03 18:55:52 -07:00
local IMAGE="$1"; local SRC_FILE="$2"; local DST_DIR="$3"
2016-02-22 10:16:57 -08:00
verify_app_name "$APP"
if verify_image "$IMAGE"; then
2016-02-22 10:16:57 -08:00
if ! is_abs_path "$SRC_FILE"; then
local WORKDIR=$(docker inspect -f '{{.Config.WorkingDir}}' "$IMAGE")
[[ -z "$WORKDIR" ]] && WORKDIR=/app
SRC_FILE="$WORKDIR/$SRC_FILE"
fi
2016-02-22 10:16:57 -08:00
CID=$(docker run "$DOKKU_GLOBAL_RUN_ARGS" -d "$IMAGE" bash)
2015-04-18 10:37:17 -07:00
docker cp "$CID:$SRC_FILE" "$DST_DIR"
docker rm -f "$CID" &> /dev/null
else
return 1
fi
}
get_app_container_ids() {
local desc="returns list of docker container ids for given app"
2015-09-03 18:55:52 -07:00
local APP="$1"; local CONTAINER_TYPE="$2"
2016-02-22 10:16:57 -08:00
verify_app_name "$APP"
[[ -f $DOKKU_ROOT/$APP/CONTAINER ]] && DOKKU_CIDS+=$(< "$DOKKU_ROOT/$APP/CONTAINER")
if [[ -n "$CONTAINER_TYPE" ]]; then
2015-08-25 23:31:53 -04:00
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE.*"
if [[ $CONTAINER_TYPE == *.* ]]; then
2015-08-25 23:31:53 -04:00
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.$CONTAINER_TYPE"
[[ ! -f $CONTAINER_PATTERN ]] && echo "" && return 0
fi
else
2015-08-25 23:31:53 -04:00
CONTAINER_PATTERN="$DOKKU_ROOT/$APP/CONTAINER.*"
fi
shopt -s nullglob
for DOKKU_CID_FILE in $CONTAINER_PATTERN; do
DOKKU_CIDS+=" "
2016-02-22 10:16:57 -08:00
DOKKU_CIDS+=$(< "$DOKKU_CID_FILE")
DOKKU_CIDS+=" "
done
shopt -u nullglob
2016-02-22 10:16:57 -08:00
echo "$DOKKU_CIDS"
}
get_app_running_container_ids() {
local desc="return list of running docker container ids for given apps"
local APP=$1
2016-02-22 10:16:57 -08:00
verify_app_name "$APP"
2016-02-22 10:16:57 -08:00
! (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
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"
}
get_cmd_from_procfile() {
local 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;
2016-02-22 10:16:57 -08:00
verify_app_name "$APP"
if [[ -f $DOKKU_PROCFILE ]]; then
while read line || [[ -n "$line" ]]; do
if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then
continue
fi
name="${line%%:*}"
command="${line#*:[[:space:]]}"
[[ "$name" == "$PROC_TYPE" ]] && echo "$command" && break
2016-02-22 10:16:57 -08:00
done < "$DOKKU_PROCFILE"
fi
}
is_deployed() {
local desc="return 0 if given app has a running container"
2015-09-03 18:55:52 -07:00
local APP="$1"
2016-02-22 10:16:57 -08:00
if [[ -f "$DOKKU_ROOT/$APP/CONTAINER" ]] || [[ $(ls "$DOKKU_ROOT/$APP"/CONTAINER.* &> /dev/null; echo $?) -eq 0 ]]; then
return 0
else
return 1
fi
}
is_container_running () {
local 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)
if [[ "$CONTAINER_STATUS" == "true" ]]; then
return 0
else
return 1
fi
}
is_container_status () {
local 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)
if [[ "$CONTAINER_STATUS" == "true" ]]; then
return 0
else
return 1
fi
}
is_app_running() {
local desc="return 0 if given app has a running container"
local APP="$1"
2016-02-22 10:16:57 -08:00
verify_app_name "$APP"
2016-02-22 10:16:57 -08:00
local APP_RUNNING_CONTAINER_IDS=$(get_app_running_container_ids "$APP")
if [[ -n "$APP_RUNNING_CONTAINER_IDS" ]]; then
return 0
else
return 1
fi
}
release_and_deploy() {
local desc="main function for releasing and deploying an app"
2016-02-22 10:16:57 -08:00
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
local IMAGE_SOURCE_TYPE="herokuish"
else
local IMAGE_SOURCE_TYPE="dockerfile"
fi
local DOKKU_APP_SKIP_DEPLOY="$(dokku config:get "$APP" DOKKU_SKIP_DEPLOY || true)"
local DOKKU_GLOBAL_SKIP_DEPLOY="$(dokku config:get --global DOKKU_SKIP_DEPLOY || true)"
2015-12-17 21:07:58 +01:00
local DOKKU_SKIP_DEPLOY=${DOKKU_APP_SKIP_DEPLOY:="$DOKKU_GLOBAL_SKIP_DEPLOY"}
2015-12-17 21:07:58 +01:00
dokku_log_info1 "Releasing $APP ($IMAGE)..."
dokku release "$APP" "$IMAGE_SOURCE_TYPE" "$IMAGE_TAG"
2015-12-17 21:07:58 +01:00
if [[ "$DOKKU_SKIP_DEPLOY" != "true" ]]; then
dokku_log_info1 "Deploying $APP ($IMAGE)..."
dokku deploy "$APP" "$IMAGE_TAG"
dokku_log_info2 "Application deployed:"
2016-02-22 10:16:57 -08:00
dokku urls "$APP" | sed "s/^/ /"
2015-12-17 21:07:58 +01:00
else
dokku_log_info1 "Skipping deployment"
fi
echo
fi
}
docker_cleanup() {
local 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
2015-10-15 13:49:42 +02:00
# delete all dead containers
# shellcheck disable=SC2046
docker rm $(docker ps -a -f 'status=dead' -q) &> /dev/null || true
# delete unused images
# shellcheck disable=SC2046
docker rmi $(docker images -f 'dangling=true' -q) &> /dev/null &
}
get_available_port() {
local desc="returns first currently unused port > 1024"
while true; do
local port=$(shuf -i 1025-65535 -n 1)
2016-02-22 10:16:57 -08:00
if ! nc -z 0.0.0.0 "$port"; then
echo "$port"
return 0
else
continue
fi
done
}
dokku_auth() {
local desc="calls user-auth plugin trigger"
export SSH_USER=${SSH_USER:=$USER}
export SSH_NAME=${NAME:="default"}
2016-02-22 10:16:57 -08:00
if ! plugn trigger user-auth "$SSH_USER" "$SSH_NAME" "$@" ; then
return 1
fi
return 0
}
_ipv4_regex() {
local desc="ipv4 regex"
echo "([0-9]{1,3}[\.]){3}[0-9]{1,3}"
}
_ipv6_regex() {
local desc="ipv6 regex"
local RE_IPV4="$(_ipv4_regex)"
local RE_IPV6="([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|" # TEST: 1:2:3:4:5:6:7:8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,7}:|" # TEST: 1:: 1:2:3:4:5:6:7::
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|" # TEST: 1::8 1:2:3:4:5:6::8 1:2:3:4:5:6::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|" # TEST: 1::7:8 1:2:3:4:5::7:8 1:2:3:4:5::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|" # TEST: 1::6:7:8 1:2:3:4::6:7:8 1:2:3:4::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|" # TEST: 1::5:6:7:8 1:2:3::5:6:7:8 1:2:3::8
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|" # TEST: 1::4:5:6:7:8 1:2::4:5:6:7:8 1:2::8
RE_IPV6="${RE_IPV6}[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|" # TEST: 1::3:4:5:6:7:8 1::3:4:5:6:7:8 1::8
RE_IPV6="${RE_IPV6}:((:[0-9a-fA-F]{1,4}){1,7}|:)|" # TEST: ::2:3:4:5:6:7:8 ::2:3:4:5:6:7:8 ::8 ::
RE_IPV6="${RE_IPV6}fe08:(:[0-9a-fA-F]{1,4}){2,2}%[0-9a-zA-Z]{1,}|" # TEST: fe08::7:8%eth0 fe08::7:8%1 (link-local IPv6 addresses with zone index)
RE_IPV6="${RE_IPV6}::(ffff(:0{1,4}){0,1}:){0,1}${RE_IPV4}|" # TEST: ::255.255.255.255 ::ffff:255.255.255.255 ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
RE_IPV6="${RE_IPV6}([0-9a-fA-F]{1,4}:){1,4}:${RE_IPV4}" # TEST: 2001:db8:3:4::192.0.2.33 64:ff9b::192.0.2.33
echo "$RE_IPV6"
}
get_ipv4_regex() {
local 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
echo "${RE_IPV4}\$"
}
get_ipv6_regex() {
local desc="returns ipv6 regex"
2016-01-14 23:30:10 +09:00
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
echo "${RE_IPV6}\$"
}
2016-02-14 18:43:40 -08:00
get_global_vhost() {
local desc="return global vhost"
local GLOBAL_VHOST_FILE="$DOKKU_ROOT/VHOST"
[[ -f "$GLOBAL_VHOST_FILE" ]] && local GLOBAL_VHOST=$(< "$GLOBAL_VHOST_FILE")
echo "$GLOBAL_VHOST"
2016-02-14 18:43:40 -08:00
}
is_global_vhost_enabled() {
local 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)"
local RE_IPV6="$(get_ipv6_regex)"
if [[ -z "$GLOBAL_VHOST" ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV4 ]] || [[ "$GLOBAL_VHOST" =~ $RE_IPV6 ]]; then
local GLOBAL_VHOST_ENABLED=false
fi
echo $GLOBAL_VHOST_ENABLED
}
is_app_vhost_enabled() {
local desc="returns true or false if vhost support is enabled for a given application"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
2016-02-14 18:43:40 -08:00
local APP=$1; verify_app_name "$APP"
2016-02-22 10:16:57 -08:00
local NO_VHOST=$(config_get "$APP" NO_VHOST)
2016-02-14 18:43:40 -08:00
local APP_VHOST_ENABLED=true
if [[ "$NO_VHOST" == "1" ]]; then
local APP_VHOST_ENABLED=false
fi
echo $APP_VHOST_ENABLED
}
disable_app_vhost() {
local desc="disable vhost support for given application"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
2016-02-22 10:16:57 -08:00
local APP=$1; verify_app_name "$APP"
2016-02-14 18:43:40 -08:00
local APP_VHOST_FILE="$DOKKU_ROOT/$APP/VHOST"
local APP_URLS_FILE="$DOKKU_ROOT/$APP/URLS"
2016-02-22 10:16:57 -08:00
local DOKKU_NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT)
local DOKKU_NGINX_SSL_PORT=$(config_get "$APP" DOKKU_NGINX_SSL_PORT)
2016-02-14 18:43:40 -08:00
if [[ -f "$APP_VHOST_FILE" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/VHOST"
rm "$APP_VHOST_FILE"
fi
if [[ -f "$APP_URLS_FILE" ]]; then
dokku_log_info1 "VHOST support disabled, deleting $APP/URLS"
rm "$APP_URLS_FILE"
fi
if [[ "$DOKKU_NGINX_PORT" == "80" ]]; then
2016-02-22 10:16:57 -08:00
config_unset --no-restart "$APP" DOKKU_NGINX_PORT
2016-02-14 18:43:40 -08:00
fi
if [[ "$DOKKU_NGINX_SSL_PORT" == "443" ]]; then
2016-02-22 10:16:57 -08:00
config_unset --no-restart "$APP" DOKKU_NGINX_SSL_PORT
2016-02-14 18:43:40 -08:00
fi
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
2016-02-22 10:16:57 -08:00
# shellcheck disable=SC2086
2016-02-14 18:43:40 -08:00
config_set $CONFIG_SET_ARGS $APP NO_VHOST=1
}
enable_app_vhost() {
local desc="enable vhost support for given application"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
2016-02-22 10:16:57 -08:00
local APP=$1; verify_app_name "$APP"
2016-02-14 18:43:40 -08:00
2016-02-22 10:16:57 -08:00
config_unset --no-restart "$APP" DOKKU_NGINX_PORT DOKKU_NGINX_SSL_PORT
2016-02-14 18:43:40 -08:00
[[ "$2" == "--no-restart" ]] && local CONFIG_SET_ARGS=$2
2016-02-22 10:16:57 -08:00
# shellcheck disable=SC2086
config_set $CONFIG_SET_ARGS "$APP" NO_VHOST=0
2016-02-14 18:43:40 -08:00
}
get_dockerfile_exposed_ports() {
local desc="return all exposed ports from passed file path"
2016-02-22 10:16:57 -08:00
local DOCKERFILE_PORTS=$(egrep "^EXPOSE " "$1" | awk '{ print $2 }' | xargs) || true
2016-02-14 18:43:40 -08:00
echo "$DOCKERFILE_PORTS"
}
get_app_raw_tcp_ports() {
local desc="extracts raw tcp port numbers from DOCKERFILE_PORTS config variable"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
2016-02-14 18:43:40 -08:00
local APP="$1"; verify_app_name "$APP"
2016-02-22 10:16:57 -08:00
local DOCKERFILE_PORTS="$(config_get "$APP" DOKKU_DOCKERFILE_PORTS)"
2016-02-14 18:43:40 -08:00
for p in $DOCKERFILE_PORTS; do
if [[ ! "$p" =~ .*udp.* ]]; then
p=${p//\/tcp}
raw_tcp_ports+="$p "
fi
done
local raw_tcp_ports="$(echo "$raw_tcp_ports"| xargs)"
2016-02-14 18:43:40 -08:00
echo "$raw_tcp_ports"
}
get_container_ports() {
local desc="returns published ports from app containers"
2016-02-14 18:43:40 -08:00
local APP="$1"; verify_app_name "$APP"
2016-02-22 10:16:57 -08:00
local APP_CIDS="$(get_app_container_ids "$APP")"
2016-02-14 18:43:40 -08:00
local cid
for cid in $APP_CIDS; do
2016-02-22 10:16:57 -08:00
local container_ports="$(docker port "$cid" | awk '{ print $3 "->" $1}' | awk -F ":" '{ print $2 }')"
2016-02-14 18:43:40 -08:00
done
2016-02-22 10:16:57 -08:00
echo "$container_ports"
2016-02-14 18:43:40 -08:00
}
get_app_urls() {
local desc="print an app's available urls"
source "$PLUGIN_AVAILABLE_PATH/config/functions"
2016-02-14 18:43:40 -08:00
local APP="$2"; verify_app_name "$APP"
2016-02-22 10:16:57 -08:00
local RAW_TCP_PORTS="$(get_app_raw_tcp_ports "$APP")"
2016-02-14 18:43:40 -08:00
local URLS_FILE="$DOKKU_ROOT/$APP/URLS"
if [[ -s "$URLS_FILE" ]]; then
2016-02-22 10:16:57 -08:00
local app_urls="$(egrep -v "^#" "$URLS_FILE")"
2016-02-14 18:43:40 -08:00
if [[ -n "$RAW_TCP_PORTS" ]]; then
for url in ${app_urls[*]}; do
for p in $RAW_TCP_PORTS; do
local port_urls+="$url:$p "
done
done
2016-02-22 10:16:57 -08:00
local port_urls="$(echo "$port_urls"| xargs)"
2016-02-14 18:43:40 -08:00
fi
local URLS=${port_urls:=$app_urls}
case "$1" in
url)
echo "$URLS" | tr ' ' '\n' | head -n1
;;
urls)
echo "$URLS" | tr ' ' '\n'
;;
esac
else
local SCHEME="http"; local SSL="$DOKKU_ROOT/$APP/tls"
2016-02-22 10:16:57 -08:00
local DOKKU_NGINX_PORT=$(config_get "$APP" DOKKU_NGINX_PORT || true)
local DOKKU_NGINX_SSL_PORT=$(config_get "$APP" DOKKU_NGINX_SSL_PORT || true)
2016-02-14 18:43:40 -08:00
if [[ -e "$SSL/server.crt" && -e "$SSL/server.key" ]]; then
local SCHEME="https"
fi
2016-02-22 10:16:57 -08:00
if [[ "$(is_app_proxy_enabled "$APP")" == "false" ]]; then
2016-02-14 18:43:40 -08:00
if [[ -n "$RAW_TCP_PORTS" ]]; then
2016-02-22 10:16:57 -08:00
local APP_CONTAINER_PORTS="$(get_container_ports "$APP")"
2016-02-14 18:43:40 -08:00
local app_port
for app_port in $APP_CONTAINER_PORTS; do
echo "$(< "$DOKKU_ROOT/HOSTNAME"):$app_port (container)"
done
else
shopt -s nullglob
for PORT_FILE in $DOKKU_ROOT/$APP/PORT.*; do
echo "$SCHEME://$(< "$DOKKU_ROOT/HOSTNAME"):$(< "$PORT_FILE") (container)"
done
shopt -u nullglob
fi
elif [[ -n "$DOKKU_NGINX_PORT" ]] || [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
if [[ -n "$DOKKU_NGINX_PORT" ]];then
2016-02-22 10:16:57 -08:00
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_PORT ($(get_app_proxy_type "$APP"))"
2016-02-14 18:43:40 -08:00
fi
if [[ -n "$DOKKU_NGINX_SSL_PORT" ]]; then
2016-02-22 10:16:57 -08:00
echo "https://$(< "$DOKKU_ROOT/HOSTNAME"):$DOKKU_NGINX_SSL_PORT ($(get_app_proxy_type "$APP")-ssl)"
2016-02-14 18:43:40 -08:00
fi
elif [[ -n "$RAW_TCP_PORTS" ]]; then
for p in $RAW_TCP_PORTS; do
echo "http://$(< "$DOKKU_ROOT/HOSTNAME"):$p"
done
else
echo "$SCHEME://$(< "$DOKKU_ROOT/VHOST")"
fi
fi
}
get_json_value() {
local 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"
local JSON_NODE=${JSON_NODE//\./\"][\"}
local JSON_NODE="[\"${JSON_NODE}\"]"
cat | python -c 'import json,sys;obj=json.load(sys.stdin);print json.dumps(obj'"${JSON_NODE}"').strip("\"")';
}
get_json_keys() {
local 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//\./\"][\"}
local JSON_NODE="[\"${JSON_NODE}\"]"
if [[ "$JSON_NODE" == "[\"\"]" ]]; then
cat | python -c 'import json,sys;obj=json.load(sys.stdin);print " ".join(obj.keys())';
else
cat | python -c 'import json,sys;obj=json.load(sys.stdin);print " ".join(obj'"${JSON_NODE}"'.keys())';
fi
}