perf,feat(events),ops: third optimization pass

Overview cold start:
- InstanceResourceService persists every live fetch into status_snapshots
  (category 'resources') and serves a snapshot younger than 2 minutes
  before calling upstream, so the first fleet overview after a restart
  costs zero device requests; instance deletion cleans up via FK cascade

Bounded retention for the four fastest-growing tables (15-minute sweep):
- connection_logs: one row per probe per beat had no automatic cleanup
- audit_events: new pruneBefore (90d)
- operation_preparations: every prepare/retry attempt inserted a row,
  terminal rows now expire after 7 days
- notification_queue: terminal rows pruned after 30 days

SSE events now cover instance lifecycle:
- create/update emit instance envelopes from the routes; the two-phase
  delete emits a job envelope on every terminal transition plus an
  instance envelope when the node actually disappears, so fleet and
  instance views invalidate in real time

Linux ops:
- 'install.sh unit' writes systemd user units for API and gateway with
  Restart=on-failure, 0600 secret injection, and
  MULTI_SIMADMIN_SYSTEMD_UNIT wired so console self-update restarts via
  systemctl -- closing the self-update loop on Linux
This commit is contained in:
chick
2026-09-07 02:43:11 +08:00
parent c1be714ba4
commit 70e598208a
11 changed files with 362 additions and 6 deletions
+68
View File
@@ -36,6 +36,7 @@ Multi SimAdmin 一键安装与服务管理
restart 停止后重新启动
status 显示进程、端口与健康状态
uninstall 卸载程序,默认保留数据、令牌和日志
unit (仅 Linux)生成 systemd 用户单元,支持开机自启与在线自更新重启
环境变量:
MULTI_SIMADMIN_HOME 安装根目录(默认 macOS 为 ~/Library/Application Support/multi-simadminLinux 为 ~/.local/share/multi-simadmin
MULTI_SIMADMIN_ALLOWED_HOSTS 额外允许的 LAN 主机名/IP,逗号分隔
@@ -297,6 +298,72 @@ uninstall_app() {
say "程序已卸载;默认保留数据、Gateway token 和日志:$APP_ROOT"
}
write_systemd_units() {
require_platform
[ "$PLATFORM" = Linux ] || die "systemd 单元仅适用于 Linux"
command -v systemctl >/dev/null 2>&1 || die "缺少 systemctl"
[ -f "$SOURCE_DIR/apps/web/dist/index.html" ] || die "尚未安装,请先运行 install"
[ -f "$TOKEN_FILE" ] || die "缺少 Gateway token,请先运行 install"
node_bin=$(command -v node)
unit_dir=${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user
mkdir -p "$unit_dir"
chmod 700 "$unit_dir"
env_file="$APP_ROOT/service-env"
{ printf 'MULTI_SIMADMIN_GATEWAY_TOKEN='; cat "$TOKEN_FILE"; } >"$env_file"
chmod 600 "$env_file"
cat >"$unit_dir/multi-simadmin-api.service" <<EOF
[Unit]
Description=Multi SimAdmin control-plane API
After=network.target
[Service]
WorkingDirectory=$SOURCE_DIR
ExecStart=$node_bin --import tsx $SOURCE_DIR/apps/api/src/production-cli.ts
Restart=on-failure
RestartSec=3
Environment=MULTI_SIMADMIN_DATA_ROOT=$DATA_ROOT
Environment=MULTI_SIMADMIN_DATABASE_PATH=$DATA_ROOT/control-plane.sqlite3
Environment=MULTI_SIMADMIN_SECRET_BACKEND=secret-file
Environment=MULTI_SIMADMIN_SYSTEMD_UNIT=multi-simadmin-api.service
EnvironmentFile=$env_file
UMask=0077
[Install]
WantedBy=default.target
EOF
cat >"$unit_dir/multi-simadmin-gateway.service" <<EOF
[Unit]
Description=Multi SimAdmin LAN gateway
After=network.target multi-simadmin-api.service
[Service]
WorkingDirectory=$SOURCE_DIR
ExecStart=$node_bin --import tsx $SOURCE_DIR/apps/api/src/production-gateway-cli.ts
Restart=on-failure
RestartSec=3
Environment=MULTI_SIMADMIN_CUTOVER_ACK=I ACKNOWLEDGE MULTI-SIMADMIN OWNS PORT 8788
Environment=MULTI_SIMADMIN_GATEWAY_HOST=0.0.0.0
Environment=MULTI_SIMADMIN_GATEWAY_ALLOWED_HOSTS=$(allowed_hosts)
Environment=CANARY_DIST_DIR=$SOURCE_DIR/apps/web/dist
Environment=CANARY_UPSTREAM_PORT=8790
Environment=MULTI_SIMADMIN_SYSTEMD_UNIT=multi-simadmin-gateway.service
EnvironmentFile=$env_file
UMask=0077
[Install]
WantedBy=default.target
EOF
chmod 600 "$unit_dir/multi-simadmin-api.service" "$unit_dir/multi-simadmin-gateway.service"
systemctl --user daemon-reload
say "已写入 systemd 用户单元。启用自启动并启动:"
say " systemctl --user enable --now multi-simadmin-api.service multi-simadmin-gateway.service"
say "注意:由 systemd 托管后请用 systemctl 管理,不要再用本脚本 start/stop,避免双进程争抢端口。"
}
command=${1:-install}
case "$command" in
install) install_app ;;
@@ -305,6 +372,7 @@ case "$command" in
restart) stop_service; start_service ;;
status) status_service ;;
uninstall) uninstall_app ;;
unit) write_systemd_units ;;
help|-h|--help) usage ;;
*) usage >&2; exit 2 ;;
esac