LibrePortal/scripts/network/variables/variables_init_app.sh
librelad 5d47a6bad5 fix(routing): honour HOST_NAME for app subdomain; add @ apex hosting
HOST_NAME was read but ignored — the FQDN was built from app_name, so 8
apps (vault, cloud, search, notes, social, meet, board, bookmark) routed at
the wrong host and Traefik disagreed with DNS. Build host_setup from
HOST_NAME (falling back to app_name); treat HOST_NAME="@"/"root" as the
domain apex (root-of-domain hosting, previously impossible). Document @ in
the Hostname field tooltip.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-22 00:45:01 +01:00

168 lines
6.7 KiB
Bash
Executable File

#!/bin/bash
# Default app variable setups
initializeAppVariables()
{
app_name="$1"
if [[ "$app_name" == "" ]]; then
isError "Something went wrong...No app name provided..."
if [[ "$initial_command2" == "terminal" ]]; then
resetToMenu;
fi
fi
# Build variable names based on app_name
host_name_var="CFG_${app_name^^}_HOST_NAME"
compose_setup_var="CFG_${app_name^^}_COMPOSE_FILE"
domain_var="CFG_${app_name^^}_DOMAIN"
whitelist_var="CFG_${app_name^^}_WHITELIST"
healthcheck_var="CFG_${app_name^^}_HEALTHCHECK"
authelia_var="CFG_${app_name^^}_AUTHELIA"
headscale_var="CFG_${app_name^^}_HEADSCALE"
app_category_var="CFG_${app_name^^}_CATEGORY"
app_title_var="CFG_${app_name^^}_TITLE"
# Access the variables using variable indirection
host_name="${!host_name_var}"
compose_setup="${!compose_setup_var}"
domain="${!domain_var}"
whitelist="${!whitelist_var}"
healthcheck="${!healthcheck_var}"
authelia_setup="${!authelia_var}"
headscale_setup="${!headscale_var}"
app_category="${!app_category_var}"
app_title="${!app_title_var}"
domain_var_name="CFG_DOMAIN_${domain}"
domain_full="${!domain_var_name}"
# FQDN for this app's Traefik Host() rule (also feeds the app URL and
# trusted-domains):
# HOST_NAME="@" or "root" -> <domain> (apex / root of domain)
# HOST_NAME set -> <HOST_NAME>.<domain> (custom subdomain)
# HOST_NAME empty -> <app_name>.<domain> (fallback default)
if [[ "$host_name" == "@" || "$host_name" == "root" ]]; then
host_setup="${domain_full}"
else
host_setup="${host_name:-$app_name}.${domain_full}"
fi
ssl_key=${domain_full}.key
ssl_crt=${domain_full}.crt
# Port configuration variables
port_config_vars=()
port_config_data=()
# Arrays to hold parsed port configuration data
port_service_names=()
port_parent_services=()
port_data_tags=()
port_external_ports=()
port_internal_ports=()
port_access_types=()
port_protocols=()
port_traefik_managed=()
port_url_accessibles=()
port_login_requireds=()
port_labels=()
port_url_paths=()
port_subdomains=()
port_recommendeds=()
for i in {1..20}; do
port_config_vars+=("CFG_${app_name^^}_PORT_$i")
# Store actual config data for port allocation
local port_config_var="CFG_${app_name^^}_PORT_$i"
local port_config_value="${!port_config_var}"
if [[ -n "$port_config_value" ]]; then
port_config_data+=("$port_config_value")
# 12-col: parent|name|ext:int|access|proto|login|traefik|webui|label|url_path|subdomain|recommended
# 10-col: parent|name|ext:int|access|proto|login|traefik|webui|label|url_path
# 9-col: parent|name|ext:int|access|proto|login|traefik|webui|label
# Legacy 8-col: parent|name|ext:int|access|proto|traefik|webui|label (login defaults to false)
# Legacy 7-col: name|ext:int|access|proto|traefik|webui|label (no parent, login defaults to false)
local parts=(${port_config_value//|/ })
if [[ ${#parts[@]} -ge 9 ]]; then
local external_port="${parts[2]%%:*}"
local internal_port="${parts[2]##*:}"
port_parent_services+=("${parts[0]}")
port_service_names+=("${parts[1]}")
port_data_tags+=("PORTS_TAG_$i")
port_external_ports+=("$external_port")
port_internal_ports+=("$internal_port")
port_access_types+=("${parts[3]}")
port_protocols+=("${parts[4]}")
port_login_requireds+=("${parts[5]}")
port_traefik_managed+=("${parts[6]}")
port_url_accessibles+=("${parts[7]}")
port_labels+=("${parts[8]}")
port_url_paths+=("${parts[9]:-}")
port_subdomains+=("${parts[10]:-}")
# Recommended defaults to the webui flag when the column isn't present —
# matches the panel's expectation that webui ports are primary by default.
if [[ ${#parts[@]} -ge 12 ]]; then
port_recommendeds+=("${parts[11]}")
else
port_recommendeds+=("${parts[7]}")
fi
elif [[ ${#parts[@]} -ge 8 ]]; then
local external_port="${parts[2]%%:*}"
local internal_port="${parts[2]##*:}"
port_parent_services+=("${parts[0]}")
port_service_names+=("${parts[1]}")
port_data_tags+=("PORTS_TAG_$i")
port_external_ports+=("$external_port")
port_internal_ports+=("$internal_port")
port_access_types+=("${parts[3]}")
port_protocols+=("${parts[4]}")
port_traefik_managed+=("${parts[5]}")
port_url_accessibles+=("${parts[6]}")
port_login_requireds+=("false")
port_labels+=("${parts[7]}")
port_url_paths+=("")
port_subdomains+=("")
port_recommendeds+=("${parts[6]}")
elif [[ ${#parts[@]} -ge 7 ]]; then
local external_port="${parts[1]%%:*}"
local internal_port="${parts[1]##*:}"
port_parent_services+=("")
port_service_names+=("${parts[0]}")
port_data_tags+=("PORTS_TAG_$i")
port_external_ports+=("$external_port")
port_internal_ports+=("$internal_port")
port_access_types+=("${parts[2]}")
port_protocols+=("${parts[3]}")
port_traefik_managed+=("${parts[4]}")
port_url_accessibles+=("${parts[5]}")
port_login_requireds+=("false")
port_labels+=("${parts[6]}")
port_url_paths+=("")
port_subdomains+=("")
port_recommendeds+=("${parts[5]}")
fi
fi
done
# Default Empty config options
if [ "$authelia_setup" == "" ]; then
authelia_setup=false
fi
if [ "$headscale_setup" == "" ]; then
headscale_setup=false
fi
if [ "$whitelist" == "" ]; then
whitelist=false
fi
if [ "$healthcheck" == "" ]; then
healthcheck=true
fi
# $public is derived from the port config — true iff any of this app's
# PORT_<n> rows have field 7 (traefik) == "true". Replaces the legacy
# CFG_<APP>_PUBLIC field, which was redundant with the per-port flag.
public="false"
local _t
for _t in "${port_traefik_managed[@]}"; do
[[ "$_t" == "true" ]] && { public="true"; break; }
done
}