#!/usr/bin/env bash # 一键体检:网络 / 端口 / adb / ffmpeg / docker / 服务状态(模块化输出) set -euo pipefail ROOT="$(cd "$(dirname "$0")/../.." && pwd)" REPO="$ROOT" # shellcheck source=/dev/null source "$ROOT/live-platform/scripts/lib/common.sh" STACK_ENV="$REPO/config/system-stack.env" if [[ -f "$STACK_ENV" ]]; then set -a # shellcheck source=/dev/null . "$STACK_ENV" set +a fi echo "=== Live Platform Doctor ===" echo "arch: $(detect_arch)" echo "hostname: $(hostname -f 2>/dev/null || hostname)" section() { echo ""; echo "--- $1 ---"; } section "loopback / DNS" ping -c1 -W2 127.0.0.1 >/dev/null 2>&1 && echo "ping 127.0.0.1: ok" || echo "ping 127.0.0.1: fail" MDNS_HOST="${HOSTNAME_ALIAS:-live}.local" getent hosts "$MDNS_HOST" >/dev/null 2>&1 && echo "$MDNS_HOST resolves: yes" || echo "$MDNS_HOST resolves: fail" section "config" if [[ -f /opt/live/config/system.json ]]; then echo "system.json: present" else echo "system.json: MISSING (run install-core)" fi if [[ -f /opt/live/generated/system-stack.env ]]; then echo "generated env: present" else echo "generated env: missing" fi section "ports (LISTEN)" command -v ss >/dev/null 2>&1 && ss -tlnp 2>/dev/null | head -n 40 || netstat -tlnp 2>/dev/null | head -n 40 || true section "adb" if command -v adb >/dev/null 2>&1; then adb devices -l || true else echo "adb not installed" fi section "ffmpeg" command -v ffmpeg >/dev/null 2>&1 && ffmpeg -version | head -n1 || echo "ffmpeg missing" section "docker" if command -v docker >/dev/null 2>&1; then docker info >/dev/null 2>&1 && echo "docker: daemon ok" || echo "docker: daemon unreachable" else echo "docker not installed" fi section "proxy hint (ShellCrash)" if [[ -d /etc/ShellCrash ]]; then echo "ShellCrash dir: /etc/ShellCrash" else echo "ShellCrash dir: not found" fi if [[ -f "$REPO/web.py" ]] && command -v curl >/dev/null 2>&1; then section "API" PORT="${PORT:-8001}" curl -sS -m 3 "http://127.0.0.1:${PORT}/health" && echo "" || echo "health check failed on :$PORT" section "Port 80 (live-edge / Caddy)" systemctl is-active live-edge.service 2>/dev/null || echo "live-edge.service: inactive" curl -sS -m 5 -o /dev/null -w "GET http://127.0.0.1/ → http_code=%{http_code}\n" "http://127.0.0.1/" || echo "curl :80 failed" section "Deployment Acceptance" deploy_json="$(curl -fsS -m 10 "http://127.0.0.1:${PORT}/deploy/check" 2>/dev/null || true)" if [[ -n "$deploy_json" ]]; then DEPLOY_JSON="$deploy_json" python3 - <<'PY' import json import os import sys raw = os.environ.get("DEPLOY_JSON", "").strip() if not raw: raise SystemExit(0) data = json.loads(raw) status = "READY" if data.get("ready") else "DEGRADED" print(f"status: {status} ({data.get('pass_count', 0)}/{data.get('total_count', 0)} checks passed)") for item in data.get("checks") or []: mark = "OK" if item.get("ok") else "FAIL" label = item.get("label") or item.get("id") or "check" detail = item.get("detail") or "" print(f"{mark:4} {label}: {detail}") hints = data.get("hints") or [] if hints: print("hints:") for line in hints: print(f"- {line}") urls = data.get("urls") or {} if urls: print("urls:") for key in ("mdns_root", "mdns_control", "lan_root", "lan_control", "loopback_api"): value = urls.get(key) if value: print(f"- {key}: {value}") PY else echo "deploy/check unavailable on :$PORT" fi fi echo "" echo "=== Doctor finished ==="