2026-09-15 18:47:02 +08:00
#!/usr/bin/env bash
# 切换 A 步(在 47 上跑):
2026-09-19 15:12:19 +08:00
# ① 备份 <install-dir>/lib → <platform-dir>/backups/lib-<ts>/
# ② 覆盖 <install-dir>/lib( T08 集群版代码)
# ③ 装 **本地 Worker**( <host-a>, 19100,无隧道 —— Manager 同机直连)
# ④ 把既有用户(admin/guest)的归属**预置**为 <host-a>(否则粘性落点无处可粘、新老用户会被按容量随机调度)
# ⑤ 在 PG 里注册 <host-a> / <host-b> 两台 worker
2026-09-15 18:47:02 +08:00
set -uo pipefail
2026-09-19 15:12:19 +08:00
. " $( cd " $( dirname " $0 " ) /.." && pwd ) /config/load.sh"
2026-09-15 18:47:02 +08:00
TS = $( date +%Y%m%d-%H%M%S)
2026-09-19 15:12:19 +08:00
# 凭据 / 地址一律来自配置(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 } "
2026-09-15 18:47:02 +08:00
TARBALL = /tmp/dshs-lib-new.tgz
2026-09-19 15:12:19 +08:00
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) 文件)"
2026-09-15 18:47:02 +08:00
echo "=== ② 覆盖 lib ==="
[ -f " $TARBALL " ] || { echo " ✗ 缺少 $TARBALL " ; exit 1; }
2026-09-19 15:12:19 +08:00
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"
2026-09-15 18:47:02 +08:00
2026-09-19 15:12:19 +08:00
echo "=== ③ 本地 Worker 单元(" $DSHS_CLUSTER_HOST_ID ",无隧道) ==="
2026-09-15 18:47:02 +08:00
cat > /etc/dshs-worker.env <<ENV
2026-09-19 15:12:19 +08:00
DSHS_DATA_ROOT=$DSHS_DATA_ROOT
2026-09-15 18:47:02 +08:00
DSHS_ISOLATION_MODE=account
DSHS_DSH_BIN=/usr/local/bin/dsh
DSHS_BASE_UID=100000
DSH_INSTANCE_NODE_OPTIONS=--max-old-space-size=160
DSH_INSTANCE_UNIVER_SOCKET=auto
DSHS_CLUSTER_AGENT_TOKEN=$W47_TOKEN
ENV
chmod 600 /etc/dshs-worker.env
cat > /etc/systemd/system/dshs-worker.service <<UNIT
[Unit]
Description=DSHS cluster worker agent (this host = 47, local users' instances)
After=network-online.target
[Service]
Type=simple
EnvironmentFile=/etc/dshs-worker.env
2026-09-19 15:12:19 +08:00
ExecStart=/usr/local/bin/node $DSH_INSTALL_DIR/lib/cli.js worker --port 19100 --host 127.0.0.1 --host-id $DSHS_CLUSTER_HOST_ID --instance-host 127.0.0.1 --log-level info
2026-09-15 18:47:02 +08:00
Restart=on-failure
RestartSec=3
KillMode=mixed
[Install]
WantedBy=multi-user.target
UNIT
systemctl daemon-reload; systemctl enable dshs-worker >/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) "
2026-09-19 15:12:19 +08:00
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 \
2026-09-15 18:47:02 +08:00
"insert into dsh_instances (id, user_id, role, status, host_id, epoch, heartbeat_at, lease_until)
2026-09-19 15:12:19 +08:00
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 \
2026-09-15 18:47:02 +08:00
"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 ==="
2026-09-19 15:12:19 +08:00
PGPASSWORD = " $DSHS_PG_PASSWORD " /usr/bin/psql -h 127.0.0.1 -p " $DSHS_PG_PORT " -U dshs -d dshs -tAc \
2026-09-15 18:47:02 +08:00
"insert into dsh_hosts (id, endpoint, agent_token, capacity_mb, used_mb, status)
2026-09-19 15:12:19 +08:00
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')
2026-09-15 18:47:02 +08:00
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
2026-09-19 15:12:19 +08:00
PGPASSWORD = " $DSHS_PG_PASSWORD " /usr/bin/psql -h 127.0.0.1 -p " $DSHS_PG_PORT " -U dshs -d dshs -tAc \
2026-09-15 18:47:02 +08:00
"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 && \\"
2026-09-19 15:12:19 +08:00
echo " systemctl restart dshs # 回 SQLite 单机;lib 回滚 = cp -a $DSH_BACKUP_DIR /lib- $TS /lib $DSH_INSTALL_DIR /lib"
2026-09-15 18:47:02 +08:00
echo " 备份时间戳: $TS "