Files
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

86 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Self-test: curve logic, NVML read, API (dry-run). Full fan write needs sudo.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
STACK_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
cd "${STACK_DIR}"
mkdir -p config
cp -n curve.default.json config/curve.json 2>/dev/null || true
export CURVE_PATH="${STACK_DIR}/config/curve.json"
export DRY_RUN=true
export GPU_FAN_PORT=18090
echo "=== 1. Curve logic ==="
.venv/bin/python -c "
from fan_controller import parse_curve, interpolate_speed
pts = parse_curve({'30':50,'40':65,'50':80,'55':90,'60':100,'70':100})
assert interpolate_speed(45, pts) in (72, 73)
assert interpolate_speed(70, pts) == 100
print('OK')
"
echo "=== 2. NVML read ==="
.venv/bin/python -c "
import pynvml
pynvml.nvmlInit()
h = pynvml.nvmlDeviceGetHandleByIndex(0)
t = pynvml.nvmlDeviceGetTemperature(h, pynvml.NVML_TEMPERATURE_GPU)
print(f'GPU temp: {t}C')
pynvml.nvmlShutdown()
print('OK')
"
echo "=== 3. API dry-run (background) ==="
.venv/bin/python app.py &
APP_PID=$!
trap 'kill $APP_PID 2>/dev/null || true' EXIT
sleep 2
STATUS=$(curl -sf "http://127.0.0.1:${GPU_FAN_PORT}/api/status")
echo "$STATUS" | .venv/bin/python -m json.tool | head -20
TARGET=$(echo "$STATUS" | .venv/bin/python -c "import sys,json; print(json.load(sys.stdin)['target_speed_pct'])")
TEMP=$(echo "$STATUS" | .venv/bin/python -c "import sys,json; print(json.load(sys.stdin)['temperature_c'])")
echo "Temp=${TEMP}C target=${TARGET}%"
curl -sf -X PUT "http://127.0.0.1:${GPU_FAN_PORT}/api/curve" \
-H 'Content-Type: application/json' \
-d '{"points":[{"temp":30,"speed":50},{"temp":40,"speed":65},{"temp":50,"speed":80},{"temp":55,"speed":90},{"temp":60,"speed":100},{"temp":70,"speed":100}]}' \
| .venv/bin/python -m json.tool >/dev/null
echo "Curve PUT: OK"
curl -sf -X POST "http://127.0.0.1:${GPU_FAN_PORT}/api/mode" \
-H 'Content-Type: application/json' \
-d '{"mode":"manual","speed":100}' >/dev/null
echo "Mode manual 100%: OK"
kill $APP_PID 2>/dev/null || true
trap - EXIT
echo ""
if sudo -n true 2>/dev/null; then
echo "=== 4. Fan write (root) ==="
sudo -n env CURVE_PATH="$CURVE_PATH" .venv/bin/python -c "
from pathlib import Path
from fan_controller import FanController
c = FanController(Path('$CURVE_PATH'), 0, 2.0)
c.init_nvml()
c.set_mode('manual', 50)
m = c.update_once()
print(f\"Applied: {m['temperature_c']}C -> {m['target_speed_pct']}%\")
c.set_mode('auto')
c.update_once()
c.shutdown()
print('OK')
"
else
echo "=== 4. Fan write (root) — SKIP (sudo needs password) ==="
echo " Run: sudo scripts/install.sh && sudo systemctl start gpu-fan"
fi
echo ""
echo "All automated checks passed."