Files
ubuntu-bare-metal/stacks/server-ui/scripts/install-control-plane.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

164 lines
4.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Unified installer: gpu-fan (native only) + Server UI (native or Docker).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
GPU_FAN_DIR="$(cd "${STACK_DIR}/../gpu-fan" && pwd)"
GPU_FAN_CHOICE=""
SERVER_UI_CHOICE=""
NON_INTERACTIVE=false
usage() {
cat <<'EOF'
Usage: install-control-plane.sh [options]
Options:
--gpu-fan=yes|no|skip Install gpu-fan host agent (native only; no Docker)
--server-ui=native|docker|skip
-y, --non-interactive Use defaults: gpu-fan=yes, server-ui=native
-h, --help
Recommended: run without flags for interactive menu.
gpu-fan cannot run in Docker (NVML requires root on host). See ADR-001.
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--gpu-fan=*) GPU_FAN_CHOICE="${1#*=}"; NON_INTERACTIVE=true; shift ;;
--server-ui=*) SERVER_UI_CHOICE="${1#*=}"; NON_INTERACTIVE=true; shift ;;
-y|--non-interactive) NON_INTERACTIVE=true; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown option: $1"; usage; exit 1 ;;
esac
done
if [[ "${EUID}" -ne 0 ]]; then
echo "Run as root: sudo ${SCRIPT_DIR}/install-control-plane.sh"
exit 1
fi
prompt_gpu_fan() {
if [[ -n "${GPU_FAN_CHOICE}" ]]; then
return
fi
echo ""
echo "=== 1) gpu-fan (agent NVML na hoście) ==="
echo " Sterowanie wentylatorami GPU wymaga root + NVML na hoście."
echo " Docker NIE jest obsługiwany (ADR-001)."
echo ""
read -r -p "Zainstalować gpu-fan native? [Y/n]: " ans
ans="${ans:-Y}"
case "${ans^^}" in
Y|YES|TAK) GPU_FAN_CHOICE="yes" ;;
*) GPU_FAN_CHOICE="no" ;;
esac
}
prompt_server_ui() {
if [[ -n "${SERVER_UI_CHOICE}" ]]; then
return
fi
echo ""
echo "=== 2) Server UI (panel stacków Docker + GPU Fan) ==="
echo " [1] Native — systemd na hoście (zalecane)"
echo " [2] Docker — kontener + docker.sock"
echo " [3] Pomiń"
echo ""
read -r -p "Wybór [1]: " ans
ans="${ans:-1}"
case "${ans}" in
1) SERVER_UI_CHOICE="native" ;;
2) SERVER_UI_CHOICE="docker" ;;
3) SERVER_UI_CHOICE="skip" ;;
*) echo "Nieprawidłowy wybór"; exit 1 ;;
esac
}
if [[ "${NON_INTERACTIVE}" == true && -z "${GPU_FAN_CHOICE}" ]]; then
GPU_FAN_CHOICE="yes"
fi
if [[ "${NON_INTERACTIVE}" == true && -z "${SERVER_UI_CHOICE}" ]]; then
SERVER_UI_CHOICE="native"
fi
echo "=== GMKtec Control Plane — instalacja ==="
bash "${SCRIPT_DIR}/setup-control-plane-env.sh"
prompt_gpu_fan
prompt_server_ui
echo ""
echo "Plan:"
echo " gpu-fan: ${GPU_FAN_CHOICE}"
echo " server-ui: ${SERVER_UI_CHOICE}"
echo ""
case "${GPU_FAN_CHOICE,,}" in
yes|y|true|1)
if [[ ! -x "${GPU_FAN_DIR}/scripts/install.sh" ]]; then
echo "ERROR: ${GPU_FAN_DIR}/scripts/install.sh not found"
exit 1
fi
echo "--- Installing gpu-fan (native) ---"
bash "${GPU_FAN_DIR}/scripts/install.sh"
;;
skip|no|n|false|0)
echo "Skipping gpu-fan."
;;
*)
echo "ERROR: invalid --gpu-fan value: ${GPU_FAN_CHOICE}"
exit 1
;;
esac
case "${SERVER_UI_CHOICE,,}" in
native|systemd|1)
echo "--- Installing Server UI (native / systemd) ---"
# Stop Docker deployment if running
if [[ -f "${STACK_DIR}/docker-compose.yml" ]]; then
(cd "${STACK_DIR}" && docker compose --profile server-ui down 2>/dev/null) || true
fi
bash "${SCRIPT_DIR}/install.sh"
;;
docker|container|2)
echo "--- Installing Server UI (Docker) ---"
bash "${SCRIPT_DIR}/install-docker.sh"
;;
skip|no|3)
echo "Skipping Server UI."
;;
*)
echo "ERROR: invalid --server-ui value: ${SERVER_UI_CHOICE}"
exit 1
;;
esac
LAN_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
UI_PORT=8091
echo ""
echo "=============================================="
echo " Instalacja zakończona"
echo "=============================================="
echo ""
echo "Server UI i gpu-fan NIE pojawią się w 'docker ps' gdy działają jako systemd."
echo "W docker ps widać tylko workloady (ComfyUI, LocalAI, NPMPlus, …)."
echo ""
echo "Sprawdzenie:"
echo " systemctl status gpu-fan server-ui # native"
echo " docker compose --profile server-ui ps # docker"
echo " ss -tln | grep -E '8091|18090'"
echo ""
if [[ "${SERVER_UI_CHOICE,,}" != "skip" ]]; then
# shellcheck source=print-api-key-instructions.sh
source "${SCRIPT_DIR}/print-api-key-instructions.sh"
print_api_key_instructions "/opt/control-plane/.env" "${UI_PORT}"
fi
echo "Tutorial: manual-tutorial/08-server-ui-install.md"
echo "Klucz API (szczegóły): manual-tutorial/04a-api-key.md"