feat: GL kit-connect ipk + one-button wizard + web dashboard for both platforms

Synology kit-connect (SPK):
- wizard.sh — one-button Keylink IT fleet setup (auto-runs on install)
- www/index.html — dark-themed local dashboard (same design as busrouter)
- bin/serve-dashboard.sh — busybox httpd on port 8089 with CGI endpoints
- start-stop-status updated to manage dashboard alongside daemon
- INFO updated: RT2600ac + RT6600ax compatibility noted
- postinst now runs wizard --auto for first-time setup

GL kit-connect (OpenWrt ipk):
- Makefile — DEPENDS: +curl +openssh-client +tailscale
- procd init — USE_PROCD=1, respawn with 5s delay
- connect-daemon.sh — Tailscale + reverse SSH (same as Synology version)
- connect-wizard.sh — one-button setup, idempotent, UCI config
- connect-register.sh — standalone hub registration
- www/kitconnect/index.html — dark-themed dashboard with wizard button
- www/kitconnect/wizard.cgi — web-triggered wizard endpoint
- UCI config at /etc/config/kitconnect

Both platforms share: same hub protocol, same Tailscale key, same port pool.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 03:10:32 +00:00
parent 0c68fb2461
commit 52e7e478e4
16 changed files with 1241 additions and 77 deletions
+26 -30
View File
@@ -1,43 +1,39 @@
#!/bin/sh
# kit-connect postinst — register with hub, set up config
# kit-connect postinst — run setup wizard, register with hub, set up config.
# Idempotent — safe to run on upgrades too.
PKG_DIR="/var/packages/kit-connect/target"
CONF="/etc/kit-connect/connect.conf"
LOG_TAG="kit-connect"
log() { logger -t "$LOG_TAG" -p local0.warn "$*"; }
mkdir -p /etc/kit-connect "$PKG_DIR/var"
mkdir -p /etc/kit-connect /etc/busrouter "$PKG_DIR/var"
# If config doesn't exist, create from template
if [ ! -f "$CONF" ]; then
cp "$PKG_DIR/conf/connect.conf" "$CONF"
fi
# Make scripts and wizard executable
chmod +x "$PKG_DIR/wizard.sh" 2>/dev/null || true
chmod +x "$PKG_DIR/bin/serve-dashboard.sh" 2>/dev/null || true
chmod 600 "$PKG_DIR/bin/connect_id_ed25519" 2>/dev/null || true
# Prompt for device ID if not set
DEVICE_ID=$(cat /etc/busrouter/device-id 2>/dev/null || echo "")
if [ -z "$DEVICE_ID" ]; then
DEVICE_ID=$(hostname 2>/dev/null || echo "unknown")
fi
# Run the Keylink IT setup wizard (non-interactive)
# This detects device ID, writes config, registers with hub, starts Tailscale.
if [ -x "$PKG_DIR/wizard.sh" ]; then
log "Running Keylink IT fleet setup wizard..."
"$PKG_DIR/wizard.sh" --auto 2>&1 | while read -r line; do log "$line"; done
else
# Fallback: minimal config
DEVICE_ID=$(cat /etc/busrouter/device-id 2>/dev/null || hostname 2>/dev/null || echo "unknown")
echo "$DEVICE_ID" > /etc/busrouter/device-id
# Write device ID into config
sed -i "s/^DEVICE_ID=.*/DEVICE_ID=$DEVICE_ID/" "$CONF" 2>/dev/null
# Set hostname for Tailscale
sed -i "s/^TAILSCALE_HOSTNAME=.*/TAILSCALE_HOSTNAME=$DEVICE_ID/" "$CONF" 2>/dev/null
# Install tailscale binaries if not present
if [ ! -f /usr/local/bin/tailscale ]; then
if [ -f "$PKG_DIR/bin/tailscale" ]; then
cp "$PKG_DIR/bin/tailscale" "$PKG_DIR/bin/tailscaled" /usr/local/bin/ 2>/dev/null
chmod +x /usr/local/bin/tailscale /usr/local/bin/tailscaled 2>/dev/null
CONF="/etc/kit-connect/connect.conf"
if [ ! -f "$CONF" ]; then
cp "$PKG_DIR/conf/connect.conf" "$CONF" 2>/dev/null || touch "$CONF"
fi
sed -i "s/^DEVICE_ID=.*/DEVICE_ID=${DEVICE_ID}/" "$CONF" 2>/dev/null
sed -i "s/^TAILSCALE_HOSTNAME=.*/TAILSCALE_HOSTNAME=${DEVICE_ID}/" "$CONF" 2>/dev/null
# Try hub registration
curl -s --connect-timeout 10 "http://162.243.83.36:8080/api/register/${DEVICE_ID}" 2>/dev/null || true
fi
# Set key permissions
chmod 600 "$PKG_DIR/bin/connect_id_ed25519" 2>/dev/null
# Try hub registration (non-fatal — daemon retries)
curl -s --connect-timeout 10 "http://162.243.83.36:8080/api/register/${DEVICE_ID}" 2>/dev/null || true
log "postinst complete — device=${DEVICE_ID}"
log "postinst complete — device_id=$(cat /etc/busrouter/device-id 2>/dev/null || echo unknown)"
exit 0
+42 -6
View File
@@ -4,28 +4,64 @@ PKG="kit-connect"
PKG_DIR="/var/packages/${PKG}/target"
DAEMON="${PKG_DIR}/bin/connect-daemon.sh"
DAEMON_PID="${PKG_DIR}/var/daemon.pid"
DASHBOARD="${PKG_DIR}/bin/serve-dashboard.sh"
DASHBOARD_PID="${PKG_DIR}/var/dashboard.pid"
case "$1" in
start)
mkdir -p "${PKG_DIR}/var"
# Start main daemon
if [ -f "$DAEMON_PID" ] && kill -0 "$(cat "$DAEMON_PID")" 2>/dev/null; then
echo "Already running"
exit 0
echo "Daemon already running"
else
setsid "$DAEMON" &
echo $! > "$DAEMON_PID"
echo "Daemon started"
fi
# Start dashboard server (port 8089)
if [ -x "$DASHBOARD" ] && command -v busybox >/dev/null 2>&1; then
if [ -f "$DASHBOARD_PID" ] && kill -0 "$(cat "$DASHBOARD_PID")" 2>/dev/null; then
echo "Dashboard already running"
else
"$DASHBOARD" 8089 &
echo $! > "$DASHBOARD_PID"
echo "Dashboard started on port 8089"
fi
fi
setsid "$DAEMON" &
echo $! > "$DAEMON_PID"
echo "Started"
;;
stop)
# Stop dashboard
if [ -f "$DASHBOARD_PID" ]; then
kill "$(cat "$DASHBOARD_PID")" 2>/dev/null
sleep 1
kill -9 "$(cat "$DASHBOARD_PID")" 2>/dev/null
rm -f "$DASHBOARD_PID"
echo "Dashboard stopped"
fi
# Stop daemon
if [ -f "$DAEMON_PID" ]; then
kill "$(cat "$DAEMON_PID")" 2>/dev/null
sleep 1
kill -9 "$(cat "$DAEMON_PID")" 2>/dev/null
rm -f "$DAEMON_PID"
echo "Daemon stopped"
fi
echo "Stopped"
;;
status)
if [ -f "$DAEMON_PID" ] && kill -0 "$(cat "$DAEMON_PID")" 2>/dev/null; then
echo "Daemon: running (PID $(cat "$DAEMON_PID"))"
else
echo "Daemon: stopped"
fi
if [ -f "$DASHBOARD_PID" ] && kill -0 "$(cat "$DASHBOARD_PID")" 2>/dev/null; then
echo "Dashboard: running on port 8089 (PID $(cat "$DASHBOARD_PID"))"
exit 0
else
echo "Dashboard: stopped"
fi
[ -f "$DAEMON_PID" ] && kill -0 "$(cat "$DAEMON_PID")" 2>/dev/null && exit 0
exit 1
;;