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>
This commit is contained in:
+163
@@ -0,0 +1,163 @@
|
||||
#!/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"
|
||||
Reference in New Issue
Block a user