#!/usr/bin/env bash # 切换 A 步(在 47 上跑): # ① 备份 /lib → /backups/lib-/ # ② 覆盖 /lib(T08 集群版代码) # ③ 装 **本地 Worker**(,19100,无隧道 —— Manager 同机直连) # ④ 把既有用户(admin/guest)的归属**预置**为 (否则粘性落点无处可粘、新老用户会被按容量随机调度) # ⑤ 在 PG 里注册 / 两台 worker set -uo pipefail . "$(cd "$(dirname "$0")/.." && pwd)/config/load.sh" TS=$(date +%Y%m%d-%H%M%S) # 凭据 / 地址一律来自配置(config/platform.env)—— ⛔ 不在脚本里写死 W47_TOKEN="${DSHS_CLUSTER_AGENT_TOKEN:?config/platform.env 缺 DSHS_CLUSTER_AGENT_TOKEN}" W106_TOKEN="${DSH_PEER_AGENT_TOKEN:?config/platform.env 缺 DSH_PEER_AGENT_TOKEN}" PGURL="${DSHS_DB_URL:?config/platform.env 缺 DSHS_DB_URL}" TARBALL=/tmp/dshs-lib-new.tgz echo "=== ① 备份 $DSH_INSTALL_DIR/lib ===" mkdir -p "$DSH_BACKUP_DIR/lib-$TS" cp -a "$DSH_INSTALL_DIR/lib" "$DSH_BACKUP_DIR/lib-$TS/lib" && echo " ✓ 备份到 $DSH_BACKUP_DIR/lib-$TS/lib($(find "$DSH_BACKUP_DIR/lib-$TS" -type f | wc -l) 文件)" echo "=== ② 覆盖 lib ===" [ -f "$TARBALL" ] || { echo " ✗ 缺少 $TARBALL"; exit 1; } rm -rf "$DSH_INSTALL_DIR"/lib && tar -xzf "$TARBALL" -C "$DSH_INSTALL_DIR" echo " ✓ 已覆盖;cluster 特征检查: $(grep -l "DEPLOY_MODE" "$DSH_INSTALL_DIR"/lib/config.js >/dev/null 2>&1 && echo '有 cluster 代码 ✓' || echo '✗ 未见 cluster 代码')" echo " lease/agent/tunnel: $(ls "$DSH_INSTALL_DIR"/lib/supervisor/lease.js "$DSH_INSTALL_DIR"/lib/worker/agent.js "$DSH_INSTALL_DIR"/lib/worker/tunnel.js 2>/dev/null | wc -l)/3" echo "=== ③ 本地 Worker 单元("$DSHS_CLUSTER_HOST_ID",无隧道) ===" cat > /etc/dshs-worker.env < /etc/systemd/system/dshs-worker.service </dev/null 2>&1 systemctl restart dshs-worker; sleep 5 echo " dshs-worker=$(systemctl is-active dshs-worker) healthz=$(curl -s -m 6 http://127.0.0.1:19100/healthz | head -c 120)" echo "=== ④ 既有用户归属预置为 $DSHS_CLUSTER_HOST_ID(粘性锚点) ===" PGPASSWORD="$DSHS_PG_PASSWORD" /usr/bin/psql -h 127.0.0.1 -p "$DSHS_PG_PORT" -U dshs -d dshs -tAc \ "insert into dsh_instances (id, user_id, role, status, host_id, epoch, heartbeat_at, lease_until) select 'dsh-'||id, id, 'main', 'stopped', '$DSHS_CLUSTER_HOST_ID', 0, 0, 0 from users on conflict (id) do update set host_id='$DSHS_CLUSTER_HOST_ID', lease_until=0" 2>&1 | tail -1 PGPASSWORD="$DSHS_PG_PASSWORD" /usr/bin/psql -h 127.0.0.1 -p "$DSHS_PG_PORT" -U dshs -d dshs -tAc \ "select u.username||' -> '||coalesce(i.host_id,'NULL') from users u left join dsh_instances i on i.user_id=u.id" 2>&1 | sed 's/^/ /' echo "=== ⑤ 注册两台 worker ===" PGPASSWORD="$DSHS_PG_PASSWORD" /usr/bin/psql -h 127.0.0.1 -p "$DSHS_PG_PORT" -U dshs -d dshs -tAc \ "insert into dsh_hosts (id, endpoint, agent_token, capacity_mb, used_mb, status) values ('$DSHS_CLUSTER_HOST_ID','http://127.0.0.1:19100','$W47_TOKEN',1024,0,'up'), ('$DSH_PEER_HOST_ID','http://127.0.0.1:19000','$W106_TOKEN',2560,0,'up') on conflict (id) do update set endpoint=excluded.endpoint, agent_token=excluded.agent_token, capacity_mb=excluded.capacity_mb, status='up'" 2>&1 | tail -1 PGPASSWORD="$DSHS_PG_PASSWORD" /usr/bin/psql -h 127.0.0.1 -p "$DSHS_PG_PORT" -U dshs -d dshs -tAc \ "select id||' cap='||capacity_mb||' status='||status||' ep='||endpoint from dsh_hosts order by id" 2>&1 | sed 's/^/ /' echo "=== 回滚剧本(现在就记下) ===" echo " rm -f /etc/systemd/system/dshs.service.d/cluster.conf && systemctl daemon-reload && \\" echo " systemctl restart dshs # 回 SQLite 单机;lib 回滚 = cp -a $DSH_BACKUP_DIR/lib-$TS/lib $DSH_INSTALL_DIR/lib" echo " 备份时间戳: $TS"