5.6 KiB
发布安装回滚补充验收
结论与范围
2026 年 9 月 21 日,基于已推送的 7114e9e 继续审查发布安装包。
本批修复已有恢复备份被覆盖、恢复不完整却返回回滚成功标记的问题。
Windows 回归与竞态检查、云端 Linux 隔离专项通过;整体验收未通过,发布模块的路径与权限安全门禁仍未关闭。
当前源码搜索中,InstallPair 和 ReadManifest 只有包内测试调用。
本批运行的是发布包测试程序,不是正式升级入口,不曾替换 /opt/smail 的正式程序。
不能将它写成正式升级、进程崩溃恢复或完整发行候选验收通过。
任务状态
- [✓] 复现已有恢复备份被覆盖。
- [✓] 复现恢复重命名失败却返回完整回滚标记。
- [✓] 修改前检查全部旧备份及目标文件类型。
- [✓] 汇总恢复删除、重命名及目录同步错误,区分完整与不完整回滚。
- [✓] Windows 包回归及竞态检查,Linux 受限隔离专项。
- [✓] 发布包 Linux 目标静态复扫,保留非零退出及全部告警。
- [!] 父目录符号链接、路径竞争、并发升级、断电与进程崩溃恢复尚未验收。
- [!] 来源程序真实性、版本声明绑定与正式升级调用链尚未验收。
原始问题与修复
原实现会先删除 *.previous,没有区分上一次失败留下的恢复证据;恢复中的删除和重命名失败又被忽略。
现在修改目标前先用 Lstat 检查全部恢复备份,普通文件、目录、悬空链接均拒绝覆盖;已存在的目标条目必须是普通文件。
恢复按固定反向顺序执行,只有恢复及目录同步全部成功才返回 ErrUpgradeRollback。
任一步失败返回 ErrUpgradeRollbackFailed,不携带完整回滚标记;未能恢复的旧备份保留供人工处理。
提交目录同步失败也走恢复流程,并再次检查恢复后的目录同步。
以上是条目级检查,不代表父目录可信或不存在检查与使用之间的竞争。 成功提交后清理旧备份的行为仍属于原有安装流程;本轮未对用户工作区执行文件删除。
反例与夹具修正
原始日志位于 test-log/production-remediation-20260921/:
release-recovery-before.log:三个已有备份反例失败;首次恢复失败注入误击备份阶段,未准确复现错误标记。release-recovery-before-v2.log:将安装故障限制在暂存目录的管理员程序安装阶段,明确复现恢复失败仍被标为回滚成功。
两次日志都保留。夹具修正不是产品正向通过,不能隐藏第一次反例设置不准确的记录。
测试与证据
| 范围 | 结果 | 边界 |
|---|---|---|
| Windows 发布包回归 | 21 个测试及子测试通过,零跳过 | 不含 Linux 链接专项 |
| Windows 发布包竞态回归 | 21 个测试及子测试通过,零跳过,退出零 | 不是多进程并发升级测试 |
| 云端 Linux 发布包 | 23 个测试及子测试通过,零跳过,退出零 | 全新临时目录,不操作正式数据库和正式安装目录 |
| Linux 目标发布包静态检查 | 5 条告警,退出 1,无包加载错误 | 4 条 G304、1 条 G306 均未整体关闭 |
覆盖三个已有恢复文件、六个重命名故障点、恢复重命名失败、提交及恢复目录同步失败、首次安装失败、目录备份、Linux 悬空备份链接及目标符号链接拒绝。 其中回滚删除失败的错误处理已经纳入实现,但尚无专门故障注入用例,不单独标为通过。
本地日志:
release-recovery-final.logrelease-recovery-race-20260921.logrelease-linux-tests-20260921-204015.logrelease-linux-result-20260921-204015.jsongosec-release-recheck-20260921.jsongosec-release-exit-20260921.json
云端证据目录:/var/tmp/smail-review-release-20260921-204015。
单元:smail-release-test-20260921-204015。
测试采用非特权身份、私有网络及临时目录,正式 Smail、控制通道、数据库目录和 Nginx 配置均不可访问。
内存硬上限 96 MiB、Go 目标 64 MiB、CPU 配额 25%,禁止交换;记录的峰值为 2.2 MiB。
结束时单元 inactive、PID 为零,正式六服务进程标识及正式程序摘要保持不变。
测试程序 SHA-256:4d5fd23de1a407e77443533457f5058d7853c769a7618ec0d8dbcecaa76161b2。
云端日志 SHA-256:1f431b3b974a9f4063cab7907c358789efe618a37c92696a0318e3039b05d210。
本包源码摘要随结果文件保存,不改写此前恢复码批次的 616 份源码清单。
20:50 完成独立只读复核:云端测试程序和日志摘要与本地一致,本包源码摘要未漂移,正式程序及六服务状态未变,测试单元已停止。
结果保存在 release-independent-recheck-20260921.json。
静态工具模块版本为 v2.22.10,工具报告自身版本字段为 dev。
初次 PowerShell 调用未生成独立 JSON,原始控制台日志保留为 gosec-release-20260921.log;随后使用显式参数列表重跑,生成独立 JSON 并记录真实退出码。
没有添加批量忽略,没有把退出 1 改写成通过,也没有将本包复扫冒充全项目复扫。
未关闭的边界
发布模块仍需要验证父目录信任、符号链接与路径竞争、多进程互斥、崩溃中断后的事务恢复、来源程序真实性及正式部署集成。 全项目原有迁移中断临界点、历史凭据处置、浏览器流程、自动续期与全协议换证、外部投递、长时容量和异机灾备门禁继续保留。 本批只关闭已列明的回滚可靠性缺陷,不构成生产放行。