Files
dokku/plugins/builder-dockerfile/internal-functions
Jose Diaz-Gonzalez f8ccf52079 refactor: only use detected port mapping if override is not specified
Previously, we would always set the port mapping during a dockerfile build, making it difficult for users to override mappings. We also only _sometimes_ updated the detected port mapping, further confusing issues when users were migrating from Dockerfile to Buildpacks for builds.

Now, we always detect the port mapping during the build process, and only use that detected port mapping if an override is not specified. This greatly simplifies the experience around port mapping, as now a user can create an app, set a port mapping, and that first deploy will respect the port mapping without an additional deploy.

The builder always has the best context for what the app should be listening on, and thus we can always specify a "default" port mapping at this stage. Users can override this map as desired later.

This change also results in the removal of a ton of internal code that is now centralized in the ports plugin.

Closes #4067
2023-08-05 10:58:57 -04:00

138 lines
4.1 KiB
Bash
Executable File

#!/usr/bin/env bash
source "$PLUGIN_CORE_AVAILABLE_PATH/common/functions"
source "$PLUGIN_CORE_AVAILABLE_PATH/common/property-functions"
set -eo pipefail
[[ $DOKKU_TRACE ]] && set -x
cmd-builder-dockerfile-report() {
declare desc="displays a builder-dockerfile report for one or more apps"
declare cmd="builder-dockerfile:report"
[[ "$1" == "$cmd" ]] && shift 1
declare APP="$1" INFO_FLAG="$2"
if [[ -n "$APP" ]] && [[ "$APP" == --* ]]; then
INFO_FLAG="$APP"
APP=""
fi
if [[ -z "$APP" ]] && [[ -z "$INFO_FLAG" ]]; then
INFO_FLAG="true"
fi
if [[ -z "$APP" ]]; then
for app in $(dokku_apps); do
cmd-builder-dockerfile-report-single "$app" "$INFO_FLAG" | tee || true
done
else
cmd-builder-dockerfile-report-single "$APP" "$INFO_FLAG"
fi
}
cmd-builder-dockerfile-report-single() {
declare APP="$1" INFO_FLAG="$2"
if [[ "$INFO_FLAG" == "true" ]]; then
INFO_FLAG=""
fi
verify_app_name "$APP"
local flag_map=(
"--builder-dockerfile-computed-dockerfile-path: $(fn-builder-dockerfile-computed-dockerfile-path "$APP")"
"--builder-dockerfile-global-dockerfile-path: $(fn-builder-dockerfile-global-dockerfile-path "$APP")"
"--builder-dockerfile-dockerfile-path: $(fn-builder-dockerfile-dockerfile-path "$APP")"
)
if [[ -z "$INFO_FLAG" ]]; then
dokku_log_info2_quiet "${APP} builder-dockerfile information"
for flag in "${flag_map[@]}"; do
key="$(echo "${flag#--}" | cut -f1 -d' ' | tr - ' ')"
dokku_log_verbose "$(printf "%-30s %-25s" "${key^}" "${flag#*: }")"
done
else
local match=false
local value_exists=false
for flag in "${flag_map[@]}"; do
valid_flags="${valid_flags} $(echo "$flag" | cut -d':' -f1)"
if [[ "$flag" == "${INFO_FLAG}:"* ]]; then
value=${flag#*: }
size="${#value}"
if [[ "$size" -ne 0 ]]; then
echo "$value" && match=true && value_exists=true
else
match=true
fi
fi
done
[[ "$match" == "true" ]] || dokku_log_fail "Invalid flag passed, valid flags:${valid_flags}"
[[ "$value_exists" == "true" ]] || dokku_log_fail "not deployed"
fi
}
fn-builder-dockerfile-computed-dockerfile-path() {
declare APP="$1"
file="$(fn-builder-dockerfile-dockerfile-path "$APP")"
if [[ "$file" == "" ]]; then
file="$(fn-builder-dockerfile-global-dockerfile-path "$APP")"
fi
echo "$file"
}
fn-builder-dockerfile-global-dockerfile-path() {
declare APP="$1"
fn-plugin-property-get-default "builder-dockerfile" "--global" "dockerfile-path" "Dockerfile"
}
fn-builder-dockerfile-dockerfile-path() {
declare APP="$1"
fn-plugin-property-get-default "builder-dockerfile" "$APP" "dockerfile-path" ""
}
fn-builder-dockerfile-get-ports-from-dockerfile() {
declare desc="return all exposed ports from passed file path"
declare DOCKERFILE_PATH="$1"
suppress_output dos2unix "$DOCKERFILE_PATH"
local ports="$(grep -E "^EXPOSE " "$DOCKERFILE_PATH" | awk '{ print $2 }' | xargs)" || true
echo "$ports"
}
fn-builder-dockerfile-get-ports-from-image() {
declare desc="return all exposed ports from passed image name"
declare IMAGE="$1"
# shellcheck disable=SC2016
local ports="$("$DOCKER_BIN" image inspect --format '{{range $key, $value := .Config.ExposedPorts}}{{$key}} {{end}}' "$IMAGE" | xargs)" || true
echo "$ports"
}
fn-builder-dockerfile-get-detect-port-map() {
declare desc="extracts and echos a port mapping from the app"
declare APP="$1" IMAGE="$2" DOCKERFILE_PATH="$3"
local detected_ports=$(fn-builder-dockerfile-get-ports-from-dockerfile "$DOCKERFILE_PATH")
if [[ -z "$detected_ports" ]]; then
local detected_ports=$(fn-builder-dockerfile-get-ports-from-image "$IMAGE")
fi
if [[ -n "$detected_ports" ]]; then
local port_map=""
for p in $detected_ports; do
if [[ "$p" =~ .*udp.* ]]; then
p=${p//\/udp/}
port_map+="udp:$p:$p "
else
p=${p//\/tcp/}
port_map+="http:$p:$p "
fi
done
echo "$port_map" | xargs
else
# ensure we have a port mapping
plugn trigger ports-configure "$APP"
echo "http:$(plugn trigger ports-get-property "$APP" proxy-port):5000"
fi
}