feat: kit-connect + syno-balance SPK builds, busfleet hub registration endpoint

- kit-connect SPK (ipq806x): postinst with hub registration, start-stop-status,
  connect-daemon management, Tailscale + reverse SSH tunnel integration
- syno-balance SPK (noarch, test build): SmartWAN-aware dual-WAN load
  balancer with 6-factor scoring engine, syno-daemon lifecycle
- Busfleet hub: register.sh (port pool 2230-2299), Python HTTP server,
  systemd service, port-registry.json with x4078/x5925 assignments
- .gitignore: exclude SSH keys (*_id_ed25519), SPK artifacts (*.spk)

Gitea releases:
- kit-connect v0.1-0001 → x5925-kit-connect-v1 (production)
- syno-balance v0.1-0001 → syno-balance-test-v1 (prerelease)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 00:55:32 +00:00
parent f207c09920
commit 0c68fb2461
25 changed files with 501 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
#!/bin/sh
# busfleet-hub register.sh — Device registration endpoint
# Called with DEVICE_ID as $1. Returns JSON on stdout.
# Port pool: 2230-2299
DEVICE_ID="${1:-unknown}"
REGISTRY="/opt/busfleet-hub/port-registry.json"
PORT_POOL_START="${PORT_POOL_START:-2230}"
PORT_POOL_END="${PORT_POOL_END:-2299}"
TAILSCALE_AUTH_KEY="${TAILSCALE_AUTH_KEY:-tskey-auth-kJz8wqNVo211CNTRL-GNL5EFjp5aWQcaWPSVn2aW9TNworKUNBV}"
# Init registry if missing
if [ ! -f "$REGISTRY" ]; then
echo '{}' > "$REGISTRY"
fi
# Check if device already registered
EXISTING_PORT=$(python3 -c "
import json
with open('$REGISTRY') as f:
reg = json.load(f)
print(reg.get('$DEVICE_ID', {}).get('tunnel_port', ''))
" 2>/dev/null)
if [ -n "$EXISTING_PORT" ]; then
cat <<EOF
{"device_id": "${DEVICE_ID}", "tunnel_port": ${EXISTING_PORT}, "tailscale_auth_key": "${TAILSCALE_AUTH_KEY}", "status": "existing"}
EOF
exit 0
fi
# Find next available port
ASSIGNED_PORT=$(python3 -c "
import json
with open('$REGISTRY') as f:
reg = json.load(f)
used = set(v['tunnel_port'] for v in reg.values())
for port in range($PORT_POOL_START, $PORT_POOL_END + 1):
if port not in used:
print(port)
break
" 2>/dev/null)
if [ -z "$ASSIGNED_PORT" ]; then
cat <<EOF
{"device_id": "${DEVICE_ID}", "error": "no ports available in pool ${PORT_POOL_START}-${PORT_POOL_END}"}
EOF
exit 1
fi
# Record assignment
TODAY=$(date +%Y-%m-%d)
python3 -c "
import json
with open('$REGISTRY') as f:
reg = json.load(f)
reg['$DEVICE_ID'] = {'tunnel_port': $ASSIGNED_PORT, 'assigned': '$TODAY'}
with open('$REGISTRY', 'w') as f:
json.dump(reg, f, indent=2)
" 2>/dev/null
cat <<EOF
{"device_id": "${DEVICE_ID}", "tunnel_port": ${ASSIGNED_PORT}, "tailscale_auth_key": "${TAILSCALE_AUTH_KEY}", "status": "new"}
EOF
exit 0