ci/woodpecker/push/main Pipeline was successful
单 project-20260921-deploy-dirtyguard-rootfix(任总 2026-09-21 10:28「根治」)。 问题:开发区 /root/cma-management → /srv/hermes/shared/cma-management 既是编辑区又是部署源, deploy.sh [0] 对任何 tracked modified 即 exit 1,多 agent 并行下反复自锁: - 2026-09-18 frontend/package.json(corepack 生成物) - 2026-09-21 10:09 batch5 在途 6 文件(放行卡住) - 2026-09-21 11:07 构建又写出 frontend/components.d.ts 改动: - deploy.sh:部署内容 = 已提交的 origin/main(独立部署检出 /srv/hermes/shared/cma-deploy: fetch -> checkout --detach -f -> clean -fdx);[0] 降级为告警(不再 exit); 新增 1.1 部署树自检(部署树必须无 tracked 修改)、1.2 运行时资产单源接线(.env/venv/node_modules)、 1d 后端可导入自检、运行树幂等切换(unit 改写前备份 + 一行回滚,cma-runtime-unit-switch 可抽取块); 保留 [1b] 鉴权面审计闸门(B 类缺口即中止)与 构建->铺站->重启->冒烟 全流程; 新增 drill 模式(离线演练:www 必须在 /var/www 之外、systemctl/nginx 必须是 PATH 桩、迁移只 --check)。 - deploy/cma-deploy-dirty-guard.sh:宿主前置闸门降级为告警(仅仓库不可用时失败关闭),不再写开发区。 - deploy/gitea-cma-deploy-hook.sh:[0] 段文案/语义同步(gate-trail 留痕链原样保留)。 - deploy/install-host-deploy-hook.sh:宿主组件安装/升级(备份 + md5 校验 + --check)。 演练证据(26/26 PASS):脏区旧版 [0] exit=1 / 新版整链 exit=0;开发区在途改动逐字节保留; 构造 B 类缺口时 [1b] 中止且未铺站;真机 drill 零生产影响。 未 push(发布须任总放行)。
66 lines
2.3 KiB
Bash
Executable File
66 lines
2.3 KiB
Bash
Executable File
#!/bin/bash
|
||
# ============================================================
|
||
# 宿主部署链组件安装/升级(CMA)
|
||
# cma-deploy-source-decouple-20260921(单 project-20260921-deploy-dirtyguard-rootfix)
|
||
#
|
||
# 把本仓 deploy/ 下的宿主侧组件安装到 /usr/local/sbin/(改前自动备份、改后校验 md5)。
|
||
# 组件(宿主侧,容器内 gitea post-receive → SSH forced-command 进入本仓库时执行):
|
||
# gitea-cma-deploy-hook.sh → /usr/local/sbin/gitea-cma-deploy-hook.sh
|
||
# cma-deploy-dirty-guard.sh → /usr/local/sbin/cma-deploy-dirty-guard.sh
|
||
#
|
||
# 用法:
|
||
# bash deploy/install-host-deploy-hook.sh # 安装/升级(含备份 + 校验)
|
||
# bash deploy/install-host-deploy-hook.sh --check # 只比对(不写任何文件)
|
||
#
|
||
# 说明:
|
||
# - 备份目录 /root/backups/cma-deploy-source-decouple-<YYYYMMDD-HHMMSS>/
|
||
# - 一行回滚: cp <备份目录>/<文件名> /usr/local/sbin/<文件名> && md5sum -c <备份目录>/MD5SUMS.rollback
|
||
# ============================================================
|
||
set -euo pipefail
|
||
|
||
REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||
SRC_DIR="$REPO_DIR/deploy"
|
||
DST_DIR="/usr/local/sbin"
|
||
FILES=(gitea-cma-deploy-hook.sh cma-deploy-dirty-guard.sh)
|
||
MODE="${1:-install}"
|
||
|
||
for f in "${FILES[@]}"; do
|
||
[ -r "$SRC_DIR/$f" ] || { echo "❌ 源文件缺失: $SRC_DIR/$f"; exit 1; }
|
||
done
|
||
|
||
if [ "$MODE" = "--check" ]; then
|
||
rc=0
|
||
for f in "${FILES[@]}"; do
|
||
if [ -r "$DST_DIR/$f" ] && cmp -s "$SRC_DIR/$f" "$DST_DIR/$f"; then
|
||
echo "✓ 一致: $DST_DIR/$f"
|
||
else
|
||
echo "≠ 不一致: $DST_DIR/$f(需要安装)"; rc=1
|
||
fi
|
||
done
|
||
exit "$rc"
|
||
fi
|
||
|
||
TS="$(date +%Y%m%d-%H%M%S)"
|
||
BAK_DIR="/root/backups/cma-deploy-source-decouple-$TS"
|
||
mkdir -p "$BAK_DIR"
|
||
|
||
for f in "${FILES[@]}"; do
|
||
if [ -e "$DST_DIR/$f" ]; then
|
||
cp -a "$DST_DIR/$f" "$BAK_DIR/$f"
|
||
md5sum "$DST_DIR/$f" >> "$BAK_DIR/MD5SUMS.rollback"
|
||
else
|
||
echo "<absent>" >> "$BAK_DIR/MD5SUMS.rollback"
|
||
fi
|
||
done
|
||
|
||
for f in "${FILES[@]}"; do
|
||
install -m 0755 -o root -g root "$SRC_DIR/$f" "$DST_DIR/$f"
|
||
done
|
||
|
||
echo "备份目录: $BAK_DIR"
|
||
for f in "${FILES[@]}"; do
|
||
echo "已安装: $DST_DIR/$f md5=$(md5sum "$DST_DIR/$f" | awk '{print $1}')"
|
||
done
|
||
bash -n "$DST_DIR/gitea-cma-deploy-hook.sh" && echo "✓ 语法检查通过"
|
||
echo "✓ 安装完成(生效于下一次 push 触发的部署)"
|