This isn't super useful outside of branding. Users that rely on this information may wish to turn on event logging to trace output that way.
266 lines
8.0 KiB
Bash
Executable File
266 lines
8.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -eo pipefail
|
|
[[ $DOKKU_TRACE ]] && set -x
|
|
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
|
|
source "$PLUGIN_AVAILABLE_PATH/config/functions"
|
|
|
|
get_cmd_from_procfile() {
|
|
declare desc="parse cmd from app Procfile"
|
|
declare APP="$1" PROC_TYPE="$2" PORT="$3"
|
|
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
|
|
local COMMAND
|
|
verify_app_name "$APP"
|
|
|
|
[[ ! -f $DOKKU_PROCFILE ]] && return
|
|
procfile-util show --procfile "$DOKKU_PROCFILE" --process-type "$PROC_TYPE" --default-port "$PORT"
|
|
}
|
|
|
|
print_dokku_scale_file() {
|
|
declare desc="prints contents of DOKKU_SCALE file"
|
|
local APP="$1"
|
|
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
|
|
dokku_log_verbose_quiet "DOKKU_SCALE declares scale -> $(xargs <"$DOKKU_SCALE_FILE")"
|
|
}
|
|
|
|
extract_procfile() {
|
|
declare desc="extracts procfile from app image"
|
|
local APP="$1"
|
|
local IMAGE_TAG="$2"
|
|
local IMAGE="$(get_deploying_app_image_name "$APP" "$IMAGE_TAG")"
|
|
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
|
|
verify_app_name "$APP"
|
|
|
|
remove_procfile "$APP"
|
|
copy_from_image "$IMAGE" "Procfile" "$DOKKU_PROCFILE" 2>/dev/null || true
|
|
if [[ -f "$DOKKU_PROCFILE" ]]; then
|
|
dokku_log_info1_quiet "App Procfile file found"
|
|
# shellcheck disable=SC2069
|
|
PROCFILE_ERRORS="$(procfile-util check --procfile "$DOKKU_PROCFILE" 2>&1 >/dev/null || true)"
|
|
if [[ -n "$PROCFILE_ERRORS" ]]; then
|
|
dokku_log_fail "${PROCFILE_ERRORS}"
|
|
fi
|
|
else
|
|
dokku_log_info1_quiet "No Procfile found in app image"
|
|
fi
|
|
}
|
|
|
|
remove_procfile() {
|
|
declare desc="removes DOKKU_PROCFILE"
|
|
local APP="$1"
|
|
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
|
|
if [[ -f "$DOKKU_PROCFILE" ]]; then
|
|
rm -f "$DOKKU_PROCFILE"
|
|
fi
|
|
}
|
|
|
|
generate_scale_file() {
|
|
declare desc="generates DOKKU_SCALE file"
|
|
local APP="$1"
|
|
local IMAGE_TAG="$2"
|
|
local IMAGE=$(get_deploying_app_image_name "$APP" "$IMAGE_TAG")
|
|
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
|
|
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
|
|
verify_app_name "$APP"
|
|
|
|
if copy_from_image "$IMAGE" "DOKKU_SCALE" "$DOKKU_SCALE_FILE" 2>/dev/null; then
|
|
cp "$DOKKU_SCALE_FILE" "${DOKKU_SCALE_FILE}.extracted"
|
|
else
|
|
rm -f "${DOKKU_SCALE_FILE}.extracted"
|
|
fi
|
|
|
|
if [[ ! -f $DOKKU_SCALE_FILE ]]; then
|
|
dokku_log_info1_quiet "DOKKU_SCALE file not found in app image. Generating one based on Procfile..."
|
|
|
|
local GENERATE_SCALE_FILE_TMP_WORK_DIR=$(mktemp -d "/tmp/dokku-${DOKKU_PID}-${FUNCNAME[0]}.XXXXXX")
|
|
trap "rm -rf '$GENERATE_SCALE_FILE_TMP_WORK_DIR' >/dev/null" RETURN
|
|
|
|
if [[ -f $DOKKU_PROCFILE ]]; then
|
|
while read -r line || [[ -n "$line" ]]; do
|
|
if [[ -z "$line" ]] || [[ "$line" == "#"* ]]; then
|
|
continue
|
|
fi
|
|
local NAME=${line%%:*}
|
|
local NUM_PROCS=0
|
|
[[ "$NAME" == "web" ]] && NUM_PROCS=1
|
|
[[ -n "$NAME" ]] && echo "$NAME=$NUM_PROCS" >>"$DOKKU_SCALE_FILE"
|
|
done < <(grep -v -E "^#" "$DOKKU_PROCFILE" | grep ':' | awk -F ':' '{ print $1 }' | sort | uniq)
|
|
else
|
|
echo "web=1" >>"$DOKKU_SCALE_FILE"
|
|
fi
|
|
fi
|
|
print_dokku_scale_file "$APP"
|
|
}
|
|
|
|
set_scale() {
|
|
declare desc="sets app proc type scaling"
|
|
declare APP="$1"
|
|
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
|
|
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
|
|
shift 1
|
|
|
|
extract_procfile "$APP" "$IMAGE_TAG" >/dev/null
|
|
trap "remove_procfile $APP" RETURN INT TERM EXIT
|
|
|
|
local SCALE_SETTINGS=("$@")
|
|
for procscale in "${SCALE_SETTINGS[@]}"; do
|
|
local PROC_NAME=${procscale%%=*}
|
|
local PROC_COUNT=${procscale#*=}
|
|
if [[ -f "$DOKKU_PROCFILE" ]] && [[ "$PROC_COUNT" != "0" ]] && ! procfile-util exists --procfile "$DOKKU_PROCFILE" --process-type "$PROC_NAME" >/dev/null 2>&1; then
|
|
dokku_log_fail "${PROC_NAME} is not a valid process name"
|
|
fi
|
|
is_number "$PROC_COUNT" || dokku_log_fail "ps:scale $PROC_COUNT is not a number"
|
|
dokku_log_info1_quiet "Scaling $APP:$PROC_NAME to $PROC_COUNT"
|
|
if (grep -q -E "^${PROC_NAME}=" "$DOKKU_SCALE_FILE" >/dev/null 2>&1); then
|
|
sed --in-place "s:^${PROC_NAME}=.*:$PROC_NAME=$PROC_COUNT:g" "$DOKKU_SCALE_FILE"
|
|
else
|
|
echo "$PROC_NAME=$PROC_COUNT" >>"$DOKKU_SCALE_FILE"
|
|
fi
|
|
done
|
|
}
|
|
|
|
ps_restore() {
|
|
declare desc="restores app"
|
|
local APP="$1"
|
|
|
|
ps_start "$APP"
|
|
}
|
|
|
|
ps_start() {
|
|
declare desc="starts app"
|
|
local APP="$1"
|
|
verify_app_name "$APP"
|
|
local IMAGE_TAG=$(get_running_image_tag "$APP")
|
|
local RUNNING
|
|
|
|
if (is_deployed "$APP"); then
|
|
plugn trigger pre-start "$APP"
|
|
RUNNING="$(fn-ps-is-app-running "$APP")"
|
|
|
|
if [[ "$RUNNING" == "mixed" ]]; then
|
|
dokku_log_warn "App is running in mixed mode, releasing"
|
|
fi
|
|
|
|
if [[ "$RUNNING" != "true" ]]; then
|
|
release_and_deploy "$APP" "$IMAGE_TAG"
|
|
else
|
|
dokku_log_warn "App $APP already running"
|
|
fi
|
|
plugn trigger proxy-build-config "$APP"
|
|
else
|
|
dokku_log_warn "App $APP has not been deployed"
|
|
fi
|
|
}
|
|
|
|
ps_stop() {
|
|
declare desc="stops app"
|
|
local APP="$1"
|
|
verify_app_name "$APP"
|
|
|
|
! (is_deployed "$APP") && dokku_log_warn "App $APP has not been deployed" && exit 0
|
|
|
|
dokku_log_quiet "Stopping $APP ..."
|
|
local DOKKU_SCHEDULER=$(get_app_scheduler "$APP")
|
|
plugn trigger scheduler-stop "$DOKKU_SCHEDULER" "$APP"
|
|
plugn trigger post-stop "$APP"
|
|
}
|
|
|
|
ps_rebuild() {
|
|
declare desc="rebuilds app from base image"
|
|
local APP="$1"
|
|
verify_app_name "$APP"
|
|
|
|
plugn trigger receive-app "$APP"
|
|
}
|
|
|
|
ps_restart() {
|
|
declare desc="restarts app"
|
|
local APP="$1"
|
|
verify_app_name "$APP"
|
|
local IMAGE_TAG=$(get_running_image_tag "$APP")
|
|
|
|
if (is_deployed "$APP"); then
|
|
release_and_deploy "$APP" "$IMAGE_TAG"
|
|
else
|
|
dokku_log_warn "App $APP has not been deployed"
|
|
fi
|
|
}
|
|
|
|
ps_scale() {
|
|
declare desc="sets app scaling config according arguments; otherwise according to DOKKU_SCALE file"
|
|
local APP="$1"
|
|
verify_app_name "$APP"
|
|
local IMAGE_TAG=$(get_running_image_tag "$APP")
|
|
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
|
|
local DOKKU_PROCFILE="$DOKKU_ROOT/$APP/DOKKU_PROCFILE"
|
|
shift 1
|
|
|
|
# shellcheck disable=SC2015
|
|
[[ ! -e $DOKKU_PROCFILE ]] && extract_procfile "$APP" "$IMAGE_TAG" >/dev/null 2>&1 || true
|
|
if [[ ! -e $DOKKU_SCALE_FILE ]] ; then
|
|
generate_scale_file "$APP" "$IMAGE_TAG" >/dev/null 2>&1
|
|
elif [[ -e $DOKKU_PROCFILE ]] ; then
|
|
for PROC_NAME in $(procfile-util list --procfile "$DOKKU_PROCFILE"); do
|
|
if ! grep -qE "^${PROC_NAME}=" "$DOKKU_SCALE_FILE"; then
|
|
echo "$PROC_NAME=0" >> "$DOKKU_SCALE_FILE"
|
|
fi
|
|
done
|
|
fi
|
|
if [[ -z "$@" ]]; then
|
|
dokku_log_info1_quiet "Scaling for $APP"
|
|
dokku_col_log_msg_quiet "proctype" "qty"
|
|
dokku_col_log_msg_quiet "--------" "---"
|
|
while read -r line || [[ -n "$line" ]]; do
|
|
[[ -z "$line" ]] && continue
|
|
local PROC_NAME=${line%%=*}
|
|
local PROC_COUNT=${line#*=}
|
|
dokku_col_log_msg "${PROC_NAME}:" "$PROC_COUNT"
|
|
done <"$DOKKU_SCALE_FILE"
|
|
else
|
|
if [[ "$(fn-ps-can-scale "$APP")" == "true" ]]; then
|
|
set_scale "$APP" "$@"
|
|
release_and_deploy "$APP" "$IMAGE_TAG"
|
|
else
|
|
dokku_log_fail "App contains DOKKU_SCALE file and cannot be manually scaled"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
get_raw_restart_policies() {
|
|
declare desc="strips docker options and prints raw restart policies"
|
|
local -r phase_file_path=$1
|
|
[[ -r "$phase_file_path" ]] && sed -e '/^--restart=/!d' <"$phase_file_path"
|
|
}
|
|
|
|
get_restart_policies() {
|
|
declare desc="strips docker options and prints restart policies"
|
|
local -r phase_file_path=$1
|
|
get_raw_restart_policies "$phase_file_path" | sed -e 's/^--restart=//g'
|
|
}
|
|
|
|
fn-ps-app-status() {
|
|
declare APP="$1"
|
|
|
|
local DOKKU_SCHEDULER=$(get_app_scheduler "$APP")
|
|
plugn trigger scheduler-app-status "$DOKKU_SCHEDULER" "$APP"
|
|
}
|
|
|
|
fn-ps-is-app-running() {
|
|
declare APP="$1"
|
|
APP_STATUS=$(fn-ps-app-status "$APP")
|
|
echo "$APP_STATUS" | cut -d ' ' -f 2
|
|
}
|
|
|
|
fn-ps-can-scale() {
|
|
declare APP="$1"
|
|
local IMAGE_TAG=$(get_running_image_tag "$APP")
|
|
local DOKKU_SCALE_FILE="$DOKKU_ROOT/$APP/DOKKU_SCALE"
|
|
local CAN_SCALE=false
|
|
|
|
[[ ! -e $DOKKU_SCALE_FILE ]] && generate_scale_file "$APP" "$IMAGE_TAG" >/dev/null 2>&1
|
|
if [[ ! -f "${DOKKU_SCALE_FILE}.extracted" ]]; then
|
|
CAN_SCALE=true
|
|
fi
|
|
|
|
echo "$CAN_SCALE"
|
|
}
|