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:
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
CONTROL_PLANE_ENV="${STACK_DIR}/../control-plane/.env"
|
||||
EXAMPLE="${STACK_DIR}/../control-plane/.env.example"
|
||||
|
||||
cd "${STACK_DIR}"
|
||||
|
||||
if [[ ! -f "${CONTROL_PLANE_ENV}" ]]; then
|
||||
cp "${EXAMPLE}" "${CONTROL_PLANE_ENV}"
|
||||
echo "Created ${CONTROL_PLANE_ENV} from example"
|
||||
fi
|
||||
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
source "${CONTROL_PLANE_ENV}"
|
||||
set +a
|
||||
|
||||
export CONTROL_PLANE_ENV="${CONTROL_PLANE_ENV}"
|
||||
|
||||
CURVE_PATH="${CURVE_PATH:-/etc/gpu-fan/curve.json}"
|
||||
export CURVE_PATH
|
||||
|
||||
if [[ ! -f "${CURVE_PATH}" ]]; then
|
||||
if [[ "${EUID}" -eq 0 ]]; then
|
||||
mkdir -p "$(dirname "${CURVE_PATH}")"
|
||||
cp curve.default.json "${CURVE_PATH}"
|
||||
else
|
||||
mkdir -p "${STACK_DIR}/config"
|
||||
CURVE_PATH="${STACK_DIR}/config/curve.json"
|
||||
export CURVE_PATH
|
||||
[[ -f "${CURVE_PATH}" ]] || cp curve.default.json "${CURVE_PATH}"
|
||||
echo "Using local curve: ${CURVE_PATH}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! -d .venv ]]; then
|
||||
python3 -m venv .venv
|
||||
.venv/bin/pip install -q -r requirements.txt
|
||||
fi
|
||||
|
||||
if [[ "${EUID}" -ne 0 ]]; then
|
||||
echo "ERROR: Fan control requires root. Use:"
|
||||
echo " sudo -E ${SCRIPT_DIR}/start.sh"
|
||||
echo "Or install system-wide:"
|
||||
echo " sudo ${SCRIPT_DIR}/install.sh && sudo systemctl start gpu-fan"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if systemctl is-active --quiet gpu-fan 2>/dev/null; then
|
||||
echo "ERROR: gpu-fan.service is already running (systemd)."
|
||||
echo " Use: sudo systemctl stop gpu-fan"
|
||||
echo " Or: sudo journalctl -u gpu-fan -f"
|
||||
echo ""
|
||||
echo "Do not run scripts/start.sh alongside systemd — one instance only."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PORT="${GPU_FAN_API_PORT:-18090}"
|
||||
HOST="${GPU_FAN_API_HOST:-127.0.0.1}"
|
||||
|
||||
if ss -tln "sport = :${PORT}" 2>/dev/null | grep -q LISTEN; then
|
||||
echo "ERROR: Port ${PORT} is already in use."
|
||||
echo ""
|
||||
ss -tlnp "sport = :${PORT}" 2>/dev/null || ss -tln "sport = :${PORT}"
|
||||
echo ""
|
||||
echo "Common causes:"
|
||||
echo " - Suspended foreground start (Ctrl+Z) — run: jobs -l && kill %<n>"
|
||||
echo " - Orphan process — run: sudo ${SCRIPT_DIR}/status.sh"
|
||||
echo " - systemd still stopping — wait a few seconds"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== GPU Fan Control (foreground) ==="
|
||||
echo "Agent API: http://${HOST}:${PORT}"
|
||||
echo "Curve: ${CURVE_PATH}"
|
||||
echo ""
|
||||
echo "Stop with Ctrl+C (not Ctrl+Z — suspended process keeps the port)."
|
||||
echo ""
|
||||
|
||||
exec .venv/bin/python app.py
|
||||
Reference in New Issue
Block a user