88 lines
5.6 KiB
Markdown
88 lines
5.6 KiB
Markdown
# 发布安装回滚补充验收
|
||
|
||
## 结论与范围
|
||
|
||
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.log`
|
||
- `release-recovery-race-20260921.log`
|
||
- `release-linux-tests-20260921-204015.log`
|
||
- `release-linux-result-20260921-204015.json`
|
||
- `gosec-release-recheck-20260921.json`
|
||
- `gosec-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 改写成通过,也没有将本包复扫冒充全项目复扫。
|
||
|
||
## 未关闭的边界
|
||
|
||
发布模块仍需要验证父目录信任、符号链接与路径竞争、多进程互斥、崩溃中断后的事务恢复、来源程序真实性及正式部署集成。
|
||
全项目原有迁移中断临界点、历史凭据处置、浏览器流程、自动续期与全协议换证、外部投递、长时容量和异机灾备门禁继续保留。
|
||
本批只关闭已列明的回滚可靠性缺陷,不构成生产放行。
|