#!/bin/sh # connect-wizard.sh — One-button Keylink IT fleet setup. # Idempotent — safe to run multiple times. # Usage: connect-wizard.sh [--auto] [--force] # --auto Non-interactive mode (for postinst) # --force Re-register even if already assigned set -e HUB_HOST="162.243.83.36" HUB_PORT="8080" AUTO=0 FORCE=0 [ "$1" = "--auto" ] && AUTO=1 [ "$1" = "--force" ] || [ "$2" = "--force" ] && FORCE=1 banner() { echo "" echo " ╔══════════════════════════════════════════╗" echo " ║ KEYLINK IT — Pioneer Bus Fleet Setup ║" echo " ╚══════════════════════════════════════════╝" echo "" } step() { echo " ▶ $*"; } ok() { echo " ✓ $*"; } warn() { echo " ⚠ $*"; } fail() { echo " ✗ $*"; } banner # ── Step 1: Detect device ────────────────────────────────────── step "Detecting device..." DEVICE_ID=$(cat /etc/busrouter/device-id 2>/dev/null || true) if [ -z "$DEVICE_ID" ]; then DEVICE_ID=$(hostname 2>/dev/null | sed 's/[^a-zA-Z0-9_-]//g' || echo "unknown") # If hostname is generic, try to derive from model if [ "$DEVICE_ID" = "OpenWrt" ] || [ "$DEVICE_ID" = "openwrt" ] || [ -z "$DEVICE_ID" ]; then model=$(cat /tmp/sysinfo/model 2>/dev/null | tr ' ' '-' | sed 's/[^a-zA-Z0-9_-]//g' || echo "") [ -n "$model" ] && DEVICE_ID="${model}-$(cat /sys/class/net/eth0/address 2>/dev/null | tr -d ':' | tail -c 6 || echo '000000')" [ -z "$DEVICE_ID" ] && DEVICE_ID="GL-unknown" fi fi mkdir -p /etc/busrouter echo "$DEVICE_ID" > /etc/busrouter/device-id ok "Device ID: ${DEVICE_ID}" # ── Step 2: Check prerequisites ──────────────────────────────── step "Checking prerequisites..." MISSING="" for cmd in curl ssh ssh-keygen; do command -v "$cmd" >/dev/null 2>&1 || MISSING="${MISSING} ${cmd}" done if [ -n "$MISSING" ]; then fail "Missing:${MISSING}" [ "$AUTO" = "1" ] && exit 1 echo "" echo " Install missing packages with:" echo " opkg update && opkg install curl openssh-client" exit 1 fi ok "All prerequisites found (curl, ssh)" # ── Step 3: SSH key ──────────────────────────────────────────── step "Checking SSH key..." KEY="/etc/kitconnect/connect_id_ed25519" if [ ! -f "$KEY" ]; then warn "Key not found at ${KEY}, generating..." mkdir -p /etc/kitconnect ssh-keygen -t ed25519 -f "$KEY" -N "" -C "kit-connect-${DEVICE_ID}" >/dev/null 2>&1 ok "Generated new Ed25519 key" else ok "SSH key present" fi chmod 600 "$KEY" # ── Step 4: UCI config defaults ──────────────────────────────── step "Configuring Keylink IT defaults..." # Ensure UCI config exists if ! uci -q get kitconnect.main >/dev/null 2>&1; then uci set kitconnect.main=kitconnect fi uci -q set kitconnect.main.device_id="$DEVICE_ID" uci -q set kitconnect.main.hub_host="$HUB_HOST" uci -q set kitconnect.main.hub_port="$HUB_PORT" uci -q set kitconnect.main.tunnel_enable='1' uci -q set kitconnect.main.tunnel_remote_host="$HUB_HOST" uci -q set kitconnect.main.tunnel_remote_user='node' uci -q set kitconnect.main.tunnel_remote_ssh_port='22' uci -q set kitconnect.main.tunnel_remote_port='0' uci -q set kitconnect.main.tunnel_local_port='2223' uci -q set kitconnect.main.tailscale_enable='1' uci -q set kitconnect.main.tailscale_auth_key='tskey-auth-kJz8wqNVo211CNTRL-GNL5EFjp5aWQcaWPSVn2aW9TNworKUNBV' uci -q set kitconnect.main.tailscale_hostname="$DEVICE_ID" uci -q set kitconnect.main.watchdog_interval='60' uci -q set kitconnect.main.forward_fail_limit='2' uci commit kitconnect ok "UCI config written" # ── Step 5: Register with hub ────────────────────────────────── step "Registering with fleet hub (${HUB_HOST}:${HUB_PORT})..." REG_FLAG="" [ "$FORCE" = "1" ] && REG_FLAG="--force" resp=$(curl -s --connect-timeout 10 "http://${HUB_HOST}:${HUB_PORT}/api/register/${DEVICE_ID}" 2>/dev/null) || true if [ -z "$resp" ]; then warn "Hub unreachable — will retry on next daemon start" ok "Config saved locally (port will auto-assign when hub is reachable)" else port=$(echo "$resp" | grep -o '"tunnel_port"[[:space:]]*:[[:space:]]*[0-9]*' | grep -o '[0-9]*') status=$(echo "$resp" | grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4) tskey=$(echo "$resp" | grep -o '"tailscale_auth_key"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4) if [ -n "$port" ] && [ "$port" != "0" ]; then uci set kitconnect.main.tunnel_remote_port="$port" uci commit kitconnect ok "Hub assigned port ${port} (status: ${status})" fi if [ -n "$tskey" ]; then uci set kitconnect.main.tailscale_auth_key="$tskey" uci commit kitconnect ok "Tailscale key configured" fi fi # ── Step 6: Enable & start service ───────────────────────────── step "Enabling kit-connect service..." /etc/init.d/kitconnect enable 2>/dev/null && ok "Enabled at boot" || warn "Could not enable (may already be enabled)" step "Starting kit-connect..." if /etc/init.d/kitconnect start 2>/dev/null; then ok "Service started" else warn "Service start returned non-zero (check logread for details)" fi # ── Done ─────────────────────────────────────────────────────── echo "" echo " ╔══════════════════════════════════════════╗" echo " ║ SETUP COMPLETE ║" echo " ╠══════════════════════════════════════════╣" echo " ║ Device: $(printf '%-30s' "$DEVICE_ID")║" ASSIGNED=$(uci -q get kitconnect.main.tunnel_remote_port 2>/dev/null || echo "pending") echo " ║ Port: $(printf '%-30s' "$ASSIGNED")║" echo " ║ Hub: $(printf '%-30s' "${HUB_HOST}:${HUB_PORT}")║" echo " ╠══════════════════════════════════════════╣" echo " ║ Dashboard: http://$(hostname)/kitconnect/$(printf ' ')%s║" "" echo " ║ Status: /etc/init.d/kitconnect status║" echo " ╚══════════════════════════════════════════╝" echo "" echo " The daemon is now running under procd supervision." echo " If it crashes, procd will restart it automatically." echo "" exit 0