#!/usr/bin/env bash # Standard include for Prole etc scripts. # - Loads environment from env.sh (if available) # - Loads values from PROLE_CONF/prole.cfg (INI-style) # - Does not override already-set env vars if [[ "${_PROLE_CFG_LOADED:-}" == "1" ]]; then return 0 2>/dev/null || true fi _PROLE_CFG_LOADED=1 _prole_cfg_script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) _prole_cfg_home_guess=$(cd "$_prole_cfg_script_dir/.." && pwd) # 1. Try to load env.sh to establish base PROLE_HOME/PROLE_CONF if [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/env.sh" ]]; then # shellcheck disable=SC1090 source "$PROLE_HOME/env.sh" elif [[ -f "$HOME/.prole/env.sh" ]]; then # shellcheck disable=SC1090 source "$HOME/.prole/env.sh" elif [[ -f "$_prole_cfg_home_guess/env.sh" ]]; then # shellcheck disable=SC1090 source "$_prole_cfg_home_guess/env.sh" fi _prole_trim() { local s="$1" s="${s#"${s%%[![:space:]]*}"}" s="${s%"${s##*[![:space:]]}"}" printf '%s' "$s" } _PROLE_CFG_SET_VARS="|" _prole_cfg_set_default() { local key="$1" value="$2" token="|$key|" # Only set if currently empty OR if we were the ones who set it from config previously if [[ -z "${!key:-}" || "$_PROLE_CFG_SET_VARS" == *"$token"* ]]; then printf -v "$key" '%s' "$value" export "$key" if [[ "$_PROLE_CFG_SET_VARS" != *"$token"* ]]; then _PROLE_CFG_SET_VARS="${_PROLE_CFG_SET_VARS}${key}|" fi fi } _prole_read_cfg() { local cfg="$1" line key value while IFS= read -r line || [[ -n "$line" ]]; do line="$(_prole_trim "$line")" [[ -z "$line" ]] && continue case "$line" in \#*|\;*|\[*\]) continue ;; esac if [[ "$line" == *"="* ]]; then key="$(_prole_trim "${line%%=*}")" value="$(_prole_trim "${line#*=}")" [[ -z "$key" ]] && continue # Replace dots with underscores for shell compatibility key="${key//./_}" _prole_cfg_set_default "$key" "$value" fi done <"$cfg" } _prole_cfg_extract_key() { local cfg="$1" key="$2" local value value=$(awk -F= -v k="$key" ' /^[[:space:]]*;/ {next} /^[[:space:]]*#/ {next} /^[[:space:]]*\\[/ {next} $1 ~ "^[[:space:]]*" k "[[:space:]]*$" { v=$2 sub(/^[[:space:]]+/, "", v) sub(/[[:space:]]+$/, "", v) val=v } END { print val } ' "$cfg" 2>/dev/null || true) printf '%s' "$value" } prole_normalize_mode() { local s s=$(printf '%s' "${1:-}" | tr 'A-Z' 'a-z') case "$s" in dev|k3d|k3d-*) echo "k3d"; return 0 ;; service|k3s|k3s-*) echo "k3s"; return 0 ;; prod|production|k8s|k8s-*) echo "k8s"; return 0 ;; prole-dev-cluster|k3d-prole-dev-cluster) echo "k3d"; return 0 ;; prole-service-cluster) echo "k3s"; return 0 ;; prole-prod-cluster) echo "k8s"; return 0 ;; esac echo "$s" } prole_set_mode() { local raw="$1" if [[ -z "$raw" ]]; then echo "ERROR: --mode requires a value (k3d, k3s, k8s)" >&2 exit 2 fi local norm norm=$(prole_normalize_mode "$raw") case "$norm" in k3d|k3s|k8s) PROLE_MODE="$norm" export PROLE_MODE ;; *) echo "ERROR: Unsupported mode '$raw' (use k3d, k3s, or k8s)" >&2 exit 2 ;; esac } prole_render_manifest() { local src="$1" if [[ "${PROLE_MODE:-}" != "k3d" ]]; then cat "$src" return 0 fi local renderer="" if [[ -n "${PROLE_SERVICE:-}" && -f "$PROLE_SERVICE/render_manifest.py" ]]; then renderer="$PROLE_SERVICE/render_manifest.py" elif [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/etc/render_manifest.py" ]]; then renderer="$PROLE_HOME/etc/render_manifest.py" fi if [[ -n "$renderer" ]]; then python3 "$renderer" "$src" return $? fi cat "$src" } _prole_cfg_file="" if [[ -n "${PROLE_CONF:-}" && -f "$PROLE_CONF/prole.cfg" ]]; then _prole_cfg_file="$PROLE_CONF/prole.cfg" elif [[ -n "${PROLE_HOME:-}" && -f "$PROLE_HOME/conf/prole.cfg" ]]; then _prole_cfg_file="$PROLE_HOME/conf/prole.cfg" elif [[ -f "$_prole_cfg_home_guess/conf/prole.cfg" ]]; then _prole_cfg_file="$_prole_cfg_home_guess/conf/prole.cfg" fi if [[ -n "$_prole_cfg_file" ]]; then if [[ -z "${PROLE_CONF:-}" ]]; then PROLE_CONF=$(cd "$(dirname "$_prole_cfg_file")" && pwd) export PROLE_CONF fi _prole_read_cfg "$_prole_cfg_file" # Prefer namespace from config unless explicitly overridden by env. if [[ "${PROLE_NAMESPACE_PREFER_ENV:-0}" != "1" ]]; then _cfg_ns=$(_prole_cfg_extract_key "$_prole_cfg_file" "NAMESPACE") if [[ -n "$_cfg_ns" ]]; then export NAMESPACE="$_cfg_ns" fi unset _cfg_ns fi fi if [[ -z "${PROLE_HOME:-}" && -d "$_prole_cfg_home_guess" ]]; then PROLE_HOME="$_prole_cfg_home_guess" export PROLE_HOME fi # Final check for critical variables if [[ -z "${PROLE_SERVICE:-}" && -n "${PROLE_HOME:-}" ]]; then export PROLE_SERVICE="$PROLE_HOME/etc" fi # Ensure NAMESPACE is set, defaulting to 'default' if not in config/env if [[ -z "${NAMESPACE:-}" ]]; then # Try to detect from current context if not set anywhere NAMESPACE=$(kubectl config view --minify --output 'jsonpath={..namespace}' 2>/dev/null) fi export NAMESPACE=${NAMESPACE:-default} if [[ -z "${PROLE_MODE:-}" ]]; then if [[ -n "${DEPLOYMENT_MODE:-}" ]]; then _prole_mode_guess=$(prole_normalize_mode "$DEPLOYMENT_MODE") case "$_prole_mode_guess" in k3d|k3s|k8s) PROLE_MODE="$_prole_mode_guess"; export PROLE_MODE ;; esac unset _prole_mode_guess elif [[ -n "${CLUSTER_ENV:-}" ]]; then _prole_mode_guess=$(prole_normalize_mode "$CLUSTER_ENV") case "$_prole_mode_guess" in k3d|k3s|k8s) PROLE_MODE="$_prole_mode_guess"; export PROLE_MODE ;; esac unset _prole_mode_guess fi fi unset _prole_cfg_script_dir unset _prole_cfg_home_guess unset _prole_cfg_file unset _PROLE_CFG_SET_VARS