359afb3a59
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>
173 lines
6.1 KiB
Bash
Executable File
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)"
|