记录首次IP初始化开发进度与验收边界

This commit is contained in:
xuans 2026-09-16 19:23:38 +08:00
parent 3d1afab22e
commit bcfffb4754

View File

@ -0,0 +1,82 @@
# 首次 IP 初始化开发记录
## 已确认需求
- 无 GUI 的 Linux 首次启动允许通过服务器 IP 打开初始化页面。
- 完成配置后使用选定的域名或 IP 访问正式管理服务。
- 初始化支持 SQLite、MySQL、PostgreSQL 三种存储方式。
- DNS 面向阿里云,保留多用户、通知及其他原有功能。
- 数据库和 DNS 验证通过后,由服务端保存验证状态;客户端不能通过传入凭据引用绕过验证。
- 初始化入口与正式管理服务分离,初始化未完成时不得启动正式业务和后台续期任务。
## 任务状态(2026-09-16)
这里的“复审通过”仅指对应代码和本地自动化测试,不代表浏览器、Linux 实机或生产验收通过。
- [✓] 配置保存改用同目录随机临时文件;写入、权限、归属、同步和关闭全部在替换正式文件之前完成。
- [✓] 配置保存覆盖首次保存、覆盖保存及各准备步骤失败的回归测试;失败不能改变原正式配置。
- [✓] 新增 `POST /api/v1/bootstrap/complete`,强制初始化会话认证、正文限额、对象类型、未知字段和单段 JSON 校验。
- [✓] 初始化完成接口按错误类别映射状态码,不向浏览器返回底层错误、密码或凭据引用;成功撤销会话并清除 Cookie。
- [✓] 数据库和 DNS 验证结果支持原子领取;领取后令牌不能重复使用,凭据回收责任交给初始化事务。
- [✓] 过期清理、其他验证操作和批量清理不能删除事务持有的凭据;保存失败时精确回收本次领取的凭据。
- [✓] 补齐 32 个并发请求的唯一领取及一次性回收测试,并通过竞态检测。
- [✓] 初始化支持 HTTP、SMTP 通知配置;省略通知对象保留已有设置,新密码只交给敏感信息存储。
- [✓] 通知凭据部分写入失败、配置保存失败时回收本次新凭据,保留原有凭据。
- [✓] 显式关闭通知重试不再在配置重新加载时变回三次重试。
- [✓] 正式管理地址支持 IPv4、IPv6、默认及非默认 HTTPS 端口;代理模式不输出内部监听端口。
- [✓] 初始化提交测试夹具显式隔离所有可写目录,避免 Linux 默认路径指向 `/scert` 或 `/ssl`。
- [ ] CLI 启动状态机:未初始化进入独立 Bootstrap HTTPS,已初始化进入正式应用,损坏配置失败关闭。
- [ ] 接入 `--bootstrap-public-ip`、`SCERT_BOOTSTRAP_PUBLIC_IP` 和 `/run/scert/bootstrap-url`。
- [ ] 正式应用构造函数拒绝未初始化配置。
- [ ] 前端初始化向导迁移至 Bootstrap API,加入令牌兑换、三数据库选择及验证、通知对象和完成跳转。
- [ ] 新启动和前端链路验证通过后,停止注册旧初始化路由,保留旧源文件。
- [ ] 新版 Linux 发布包、桌面浏览器和真实数据库整链路验收。
- [ ] 在明确授权范围内进行真实 DNS、ACME、HTTPS 和远程部署验收。
## 本轮验证
在 Windows 开发工作区执行并通过:
```text
go test ./...
go vet ./...
go test -race ./internal/bootstrap ./internal/config ./internal/setup
go test -race ./...
git diff --check
```
另外,设置 `GOOS=linux`、`GOARCH=amd64`、`CGO_ENABLED=0` 后执行 `go build ./...` 通过,仅验证 Linux 目标源码可构建,没有生成或部署本轮 Linux 发布包。
测试使用独立临时目录和隔离 SQLite 数据库;阿里云验证、证书签发和防火墙由测试替身模拟,没有修改真实 DNS 或主机防火墙。
MySQL/PostgreSQL 参数、验证状态和凭据处理有自动化覆盖,但这不等于本轮完成两个真实数据库服务的连接、迁移和权限验收。HTTP 接口测试不等于浏览器验收。通知配置测试不等于实际邮件投递。
## 关键设计与续接注意事项
### 配置提交边界
`Config.Save` 只有正式文件替换成功才返回成功,替换之后不再执行可能返回错误的权限操作,避免调用方错误回滚已提交的证书和凭据。代码不保证断电后的目录项持久性;Linux 目录归属及权限准备仍可能产生元数据副作用。
### 验证凭据的事务所有权
`Claim` 在验证管理器的互斥锁下读取并移除有效令牌,返回验证结果和仅能执行一次的失败回收函数。`Completer` 成功保存配置后不调用回收函数;任何提交前失败都尝试回收。旧 `Resolve`、`Check`、`Consume` 保留给原有调用方,但新 Bootstrap 提交不再采用“先读取、最后消费”的模式。
此机制覆盖当前进程内的受控失败,不承诺进程强制终止后的孤立临时凭据自动恢复;后续启动清理机制应单独复审。数据库迁移和管理员写入可能已发生,不能宣称所有数据库副作用可回滚。
### 通知兼容
完成请求通过可选 `notification` 对象传递通知配置。省略对象保留原有配置,提供对象按完整表单应用;客户端不能指定 `http_credential_ref` 或 `smtp_credential_ref`。HTTP 支持 Bearer、HMAC-SHA256 和账号会话认证;SMTP 密码单独存储。
前端迁移时应将现有通知表单映射到该对象,而不是移除通知步骤。不要把客户端输入或底层错误写入公开响应。
### 验收与操作边界
- 当前新路由尚未接入 `scert serve`,现有启动行为和旧前端没有因为上述模块测试通过而自动完成迁移。
- IP 管理入口目前使用自签名证书,不能表述为已获公共 CA 信任。
- 本轮未连接远程主机,未操作真实 DNS,未清空既有数据库,未修改 `pcux.cn` 及其证书。
- `47.108.78.12` 用于项目部署;`8.137.23.95` 用于推送测试,两者不可混用。
- 历史未跟踪补丁、测试脚本、二进制和 `dist/` 产物保持不动,不纳入提交。
## 下一步
先实现可注入依赖的启动状态机及隔离 HTTPS 服务,并补充启动、关闭、配置损坏和完成切换测试。之后迁移前端,再做真实浏览器与 Linux 发布验收;不要提前停用旧路由导致现有向导不可访问。