Files
ubuntu-bare-metal/stacks/server-ui/scripts/setup-control-plane-env.sh
T
tomasz-syn-grzegorza 359afb3a59 Initial import: bare-metal stacks, Server UI, GPU fan, tutorials.
Infrastructure configs for GMKtec K11 (Docker, vLLM, LocalAI, ComfyUI,
control-plane, gpu-fan agent, Server UI with CLI/file explorer/GPU fan curve).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 12:02:04 +00:00

173 lines
6.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Create /opt/control-plane/.env and migrate from legacy per-service .env files.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
REPO_ROOT="$(cd "${STACK_DIR}/../.." && pwd)"
CONTROL_PLANE_DIR="/opt/control-plane"
ENV_FILE="${CONTROL_PLANE_DIR}/.env"
EXAMPLE="${REPO_ROOT}/stacks/control-plane/.env.example"
LEGACY_SUI="/opt/server-ui/.env"
LEGACY_GF="/opt/gpu-fan/.env"
LEGACY_REPO_SUI="${REPO_ROOT}/stacks/server-ui/.env"
DEV_ENV="${REPO_ROOT}/stacks/control-plane/.env"
TIMESTAMP="$(date +%Y%m%d%H%M%S)"
if [[ "${EUID}" -ne 0 ]]; then
echo "Run as root: sudo ${SCRIPT_DIR}/setup-control-plane-env.sh"
exit 1
fi
set_env_var() {
local file="$1" key="$2" val="$3"
if grep -q "^${key}=" "${file}"; then
sed -i "s|^${key}=.*|${key}=${val}|" "${file}"
else
echo "${key}=${val}" >> "${file}"
fi
}
get_env_var() {
local file="$1" key="$2"
grep "^${key}=" "${file}" 2>/dev/null | cut -d= -f2- || true
}
remove_deprecated_keys() {
local file="$1"
[[ -f "${file}" ]] || return 0
cp -a "${file}" "${file}.bak.${TIMESTAMP}"
grep -v -E '^(API_KEY|GPU_FAN_AGENT_KEY)=' "${file}" > "${file}.tmp.${TIMESTAMP}" || true
{
echo "# API_KEY: use /opt/control-plane/.env (prod) or stacks/control-plane/.env (dev)"
echo "# Run: sudo bash stacks/server-ui/scripts/setup-control-plane-env.sh"
cat "${file}.tmp.${TIMESTAMP}"
} > "${file}"
rm -f "${file}.tmp.${TIMESTAMP}"
echo "Removed API_KEY / GPU_FAN_AGENT_KEY from ${file} (backup: ${file}.bak.${TIMESTAMP})"
}
sync_dev_env_from_prod() {
local prod_key repo_root_val
prod_key="$(get_env_var "${ENV_FILE}" API_KEY)"
repo_root_val="$(get_env_var "${ENV_FILE}" REPO_ROOT)"
[[ -n "${repo_root_val}" ]] || repo_root_val="${REPO_ROOT}"
if [[ ! -f "${DEV_ENV}" && -f "${EXAMPLE}" ]]; then
cp "${EXAMPLE}" "${DEV_ENV}"
echo "Created dev env: ${DEV_ENV}"
fi
if [[ ! -f "${DEV_ENV}" ]]; then
echo "WARN: dev env missing: ${DEV_ENV}"
return 0
fi
if [[ -n "${prod_key}" ]]; then
set_env_var "${DEV_ENV}" "API_KEY" "${prod_key}"
fi
set_env_var "${DEV_ENV}" "REPO_ROOT" "${repo_root_val}"
local ui_port
ui_port="$(get_env_var "${ENV_FILE}" SERVER_UI_PORT)"
[[ -n "${ui_port}" ]] && set_env_var "${DEV_ENV}" "SERVER_UI_PORT" "${ui_port}"
echo "Synced dev env: ${DEV_ENV} (API_KEY matches ${ENV_FILE})"
}
merge_env_file() {
local src="$1"
[[ -f "${src}" ]] || return 0
while IFS= read -r line || [[ -n "${line}" ]]; do
line="${line%%#*}"
line="$(echo "${line}" | xargs)"
[[ -n "${line}" && "${line}" == *=* ]] || continue
local key="${line%%=*}"
local val="${line#*=}"
key="$(echo "${key}" | xargs)"
[[ -n "${val}" ]] || continue
# Skip deprecated duplicate key
[[ "${key}" == "GPU_FAN_AGENT_KEY" ]] && continue
set_env_var "${ENV_FILE}" "${key}" "${val}"
done < "${src}"
}
echo "=== Control plane env setup ==="
mkdir -p "${CONTROL_PLANE_DIR}"
# Deploy env_loader for production Python imports
if [[ -f "${REPO_ROOT}/stacks/control-plane/env_loader.py" ]]; then
install -m 644 "${REPO_ROOT}/stacks/control-plane/env_loader.py" "${CONTROL_PLANE_DIR}/env_loader.py"
fi
if [[ ! -f "${ENV_FILE}" ]]; then
if [[ -f "${EXAMPLE}" ]]; then
cp "${EXAMPLE}" "${ENV_FILE}"
echo "Created ${ENV_FILE} from example"
else
touch "${ENV_FILE}"
echo "Created empty ${ENV_FILE}"
fi
fi
# Migrate legacy files (non-destructive: backup first)
SUI_KEY=""
GF_KEY=""
[[ -f "${LEGACY_SUI}" ]] && SUI_KEY="$(get_env_var "${LEGACY_SUI}" API_KEY)"
[[ -f "${LEGACY_GF}" ]] && GF_KEY="$(get_env_var "${LEGACY_GF}" API_KEY)"
for legacy in "${LEGACY_SUI}" "${LEGACY_GF}"; do
if [[ -f "${legacy}" ]]; then
cp -a "${legacy}" "${legacy}.bak.${TIMESTAMP}"
echo "Backed up ${legacy}${legacy}.bak.${TIMESTAMP}"
merge_env_file "${legacy}"
fi
done
if [[ -n "${SUI_KEY}" && -n "${GF_KEY}" && "${SUI_KEY}" != "${GF_KEY}" ]]; then
echo "WARN: API_KEY differed in legacy files — merged value: $(get_env_var "${ENV_FILE}" API_KEY)"
echo " After install, use one key everywhere: grep ^API_KEY= ${ENV_FILE}"
fi
# Defaults
set_env_var "${ENV_FILE}" "GPU_FAN_AGENT_URL" "$(get_env_var "${ENV_FILE}" GPU_FAN_AGENT_URL || echo http://127.0.0.1:18090)"
[[ -n "$(get_env_var "${ENV_FILE}" GPU_FAN_AGENT_URL)" ]] || set_env_var "${ENV_FILE}" "GPU_FAN_AGENT_URL" "http://127.0.0.1:18090"
set_env_var "${ENV_FILE}" "GPU_FAN_API_HOST" "$(get_env_var "${ENV_FILE}" GPU_FAN_API_HOST || echo 127.0.0.1)"
[[ -n "$(get_env_var "${ENV_FILE}" GPU_FAN_API_HOST)" ]] || set_env_var "${ENV_FILE}" "GPU_FAN_API_HOST" "127.0.0.1"
set_env_var "${ENV_FILE}" "GPU_FAN_API_PORT" "$(get_env_var "${ENV_FILE}" GPU_FAN_API_PORT || echo 18090)"
[[ -n "$(get_env_var "${ENV_FILE}" GPU_FAN_API_PORT)" ]] || set_env_var "${ENV_FILE}" "GPU_FAN_API_PORT" "18090"
set_env_var "${ENV_FILE}" "CURVE_PATH" "$(get_env_var "${ENV_FILE}" CURVE_PATH || echo /etc/gpu-fan/curve.json)"
[[ -n "$(get_env_var "${ENV_FILE}" CURVE_PATH)" ]] || set_env_var "${ENV_FILE}" "CURVE_PATH" "/etc/gpu-fan/curve.json"
# REPO_ROOT default
if [[ -z "$(get_env_var "${ENV_FILE}" REPO_ROOT)" ]]; then
set_env_var "${ENV_FILE}" "REPO_ROOT" "${REPO_ROOT}"
fi
# Generate API_KEY if missing or placeholder
API_KEY_VAL="$(get_env_var "${ENV_FILE}" API_KEY)"
if [[ -z "${API_KEY_VAL}" || "${API_KEY_VAL}" == change-me* ]]; then
KEY="$(openssl rand -hex 16)"
set_env_var "${ENV_FILE}" "API_KEY" "${KEY}"
echo "Generated API_KEY in ${ENV_FILE}"
fi
chmod 600 "${ENV_FILE}"
# Always sync dev copy to production key
sync_dev_env_from_prod
# Remove duplicate API keys from legacy per-service env files
for legacy in "${LEGACY_SUI}" "${LEGACY_GF}" "${LEGACY_REPO_SUI}"; do
if [[ -f "${legacy}" ]] && grep -qE '^(API_KEY|GPU_FAN_AGENT_KEY)=' "${legacy}" 2>/dev/null; then
remove_deprecated_keys "${legacy}"
fi
done
echo ""
echo "Control plane env: ${ENV_FILE}"
echo "Dev copy: ${DEV_ENV}"
echo ""
# shellcheck source=print-api-key-instructions.sh
source "${SCRIPT_DIR}/print-api-key-instructions.sh"
print_api_key_instructions "${ENV_FILE}" "$(get_env_var "${ENV_FILE}" SERVER_UI_PORT || echo 8091)"