[BUG] roles/repo/tasks/build.yml 中的 create repo directories 任务会无条件删除 /www 目录,导致用户数据丢失
描述
在运行 deploy.yml 或 infra.yml 的 repo 阶段时,roles/repo/tasks/build.yml 中的 create repo directories 任务会在未确认迁移成功的情况下,强制删除 /www 目录,导致用户在该目录下的业务数据永久丢失。
影响版本
当前最新版 v4.3.0 及之前所有版本。
根因分析
roles/repo/tasks/build.yml 第 20-28 行:
if [ -d "${NGINX_HOME}" ] && [ ! -L "${NGINX_HOME}" ]; then
mv -f "${NGINX_HOME}"/* "${NGINX_DATA}/" 2>/dev/null || true
rm -rf "${NGINX_HOME}"
fi
ln -snf "${NGINX_DATA}" "${NGINX_HOME}"
这段代码的逻辑意图是:如果 /www 是一个普通目录(不是软链接),则将其内容迁移到 /data/nginx,然后删除 /www,最后创建一个 /www → /data/nginx 的软链接。
问题在于:
2>/dev/null — mv 命令的所有错误输出被静默丢弃,用户看不到任何错误信息
|| true — 即使 mv 返回非零退出码(迁移失败),也被视为"成功"
rm -rf 无条件执行 — mv 失败后,rm -rf 仍然会执行,导致源文件被永久删除
复现步骤
- 在服务器上创建一个包含业务数据的
/www 目录(例如网站文件)
- 按照官方文档执行 Pigsty 部署
deploy.yml 运行到 REPO 阶段时,自动执行上述任务
/www 目录及其下所有文件被删除,替换为 /data/nginx 的软链接
实际结果
/www 目录被 rm -rf 删除
- 原
/www 下的文件并未成功迁移到 /data/nginx(跨设备 mv 失败等原因)
- 用户数据永久丢失
预期结果
- 如果
/www 已存在且是用户数据目录,应当:
- 跳过该操作,或
- 提示用户并征得确认,或
- 至少保证 mv 失败时不执行 rm
建议修复方案
if [ -d "${NGINX_HOME}" ] && [ ! -L "${NGINX_HOME}" ]; then
if mv -f "${NGINX_HOME}"/* "${NGINX_DATA}/" 2>/dev/null; then
rm -rf "${NGINX_HOME}"
else
echo "[ERROR] Failed to migrate ${NGINX_HOME} to ${NGINX_DATA}, aborting"
exit 1
fi
fi
或者更保守的做法:如果 /www 已存在且非空且不是软链接,直接报错退出,让用户手动处理。
额外说明
- 默认配置中
nginx_home: /www 是一个硬编码路径, /www 是很多用户放置网站文件的常见路径,冲突概率很高
- 文档中对此行为没有任何警告
- 建议在文档和配置注释中明确标注此破坏性行为的风险
[BUG]
roles/repo/tasks/build.yml中的create repo directories任务会无条件删除/www目录,导致用户数据丢失描述
在运行
deploy.yml或infra.yml的 repo 阶段时,roles/repo/tasks/build.yml中的create repo directories任务会在未确认迁移成功的情况下,强制删除/www目录,导致用户在该目录下的业务数据永久丢失。影响版本
当前最新版 v4.3.0 及之前所有版本。
根因分析
roles/repo/tasks/build.yml第 20-28 行:这段代码的逻辑意图是:如果
/www是一个普通目录(不是软链接),则将其内容迁移到/data/nginx,然后删除/www,最后创建一个/www → /data/nginx的软链接。问题在于:
2>/dev/null— mv 命令的所有错误输出被静默丢弃,用户看不到任何错误信息|| true— 即使 mv 返回非零退出码(迁移失败),也被视为"成功"rm -rf无条件执行 — mv 失败后,rm -rf仍然会执行,导致源文件被永久删除复现步骤
/www目录(例如网站文件)deploy.yml运行到 REPO 阶段时,自动执行上述任务/www目录及其下所有文件被删除,替换为/data/nginx的软链接实际结果
/www目录被rm -rf删除/www下的文件并未成功迁移到/data/nginx(跨设备 mv 失败等原因)预期结果
/www已存在且是用户数据目录,应当:建议修复方案
或者更保守的做法:如果
/www已存在且非空且不是软链接,直接报错退出,让用户手动处理。额外说明
nginx_home: /www是一个硬编码路径,/www是很多用户放置网站文件的常见路径,冲突概率很高