197 lines
11 KiB
Markdown
197 lines
11 KiB
Markdown
# AGENTS Changelog
|
||
|
||
多 agent 并行时的共享变更记录。开工前先读本文,避免重复实现或与已变更的接口冲突。
|
||
条目按时间倒序排列;破坏性变更(接口签名、协议字段等)会明确标注。
|
||
|
||
---
|
||
|
||
## 2026-08-22 Node SSR 配置与 Nginx 双槽受控区块
|
||
|
||
### 已完成
|
||
|
||
- `deploymentconfig.Config` 新增精确的 `nodeSsr` camel 表。
|
||
- Node SSR 仅接受 `container`,槽位固定为宿主端口 `18910`、`28910`。
|
||
- 槽位容器名固定为 `node-ssr-18910`、`node-ssr-28910`。
|
||
- 健康检查固定为 `http://127.0.0.1:18910/health` 与 `http://127.0.0.1:28910/health`。
|
||
- `hostnginx` 新增 Node SSR 受控 upstream 区块解析、活动端口读取和硬切换渲染:
|
||
`# yms-update managed nodeSsr upstream begin/end`。
|
||
- Node SSR Nginx 逻辑入口端口为 `8910`;受控 upstream 后端为 `18910`、`28910`。
|
||
- Node SSR upstream 名称冻结为 `ssr`,受控标记为 `# yms-update managed ssr upstream begin/end`。
|
||
|
||
### 尚未完成
|
||
|
||
- Node SSR 容器更新事务执行器、SQLite 部署记录、CLI `--service nodeSsr` 分派尚未实现。
|
||
- Node SSR updater 接入后,必须复用上述 Nginx 受控区块,并在健康检查通过后切换活动槽位。
|
||
- 执行器接入前,`nodeSsr` 表暂为可选;存在时严格校验,缺失时不影响现有 backend 配置启动。
|
||
|
||
### 提交
|
||
|
||
- `83a1f05 feat: add node SSR dual-slot deployment config`
|
||
- `a909ecf feat: add Node SSR Nginx upstream switching`
|
||
- `3f6b1cb fix: keep Node SSR config optional during rollout`
|
||
- `ed80e2b feat: add Node SSR deployment transaction record`
|
||
- `40e3147 feat: extend container executor for Node SSR`
|
||
|
||
### 事务底座
|
||
|
||
- SQLite schema version 升至 3,新增 `node_ssr_container_deployment` 单例表。
|
||
- 新增 `NodeSsrContainerDeployment` 读写与原子提交方法,端口严格限制为 `18910/28910`。
|
||
- 通用容器执行器允许 Node SSR 使用 `PORT`、`/health`、18910/28910,并支持无配置文件与无 bind mount 的容器。
|
||
|
||
### Sonar 清理
|
||
|
||
- Node SSR upstream 行解析拆分为单行解析函数,降低主解析函数复杂度。
|
||
- Node SSR 部署记录字段校验改为有序字段列表,避免 map 遍历顺序不稳定。
|
||
- 容器执行器的可选挂载路径校验提取为 `validateOptionalPathPair`,移除重复分支和单行嵌套判断。
|
||
- `go test ./...`、`go vet ./...`、`git diff --check` 通过。
|
||
- `d2070c9 refactor: simplify Node SSR parsing and validation`
|
||
- `99082fd refactor: simplify optional container path validation`
|
||
- `a81f81e refactor: split deployment configuration validation`
|
||
- `3f13130 refactor: split container switch and commit steps`
|
||
- `076167d refactor: split CLI diagnosis and status rendering`
|
||
- `67214dd refactor: split container executor validation states`
|
||
|
||
---
|
||
|
||
## 2026-08-22 对账结果可见性 + 容器镜像 tag 展示
|
||
|
||
### 诊断与对账输出
|
||
|
||
- `ymsctl status/doctor/reconcile` 的状态展示区分 `HEALTHY`、`REPAIRABLE`、`DRIFT`。
|
||
- `ymsctl reconcile --service backend` 明确标记为只读修复计划,并提示追加 `--apply`。
|
||
- `ymsctl reconcile --service backend --apply` 成功后输出 `APPLIED`、对账事务 ID 和重新核对结果。
|
||
- `daemonapi.Diagnosis` 新增 `RepairApplied`、`RepairTransactionID` 字段;自动修复完成后由服务端填充。
|
||
- 对账修复仍通过 SQLite 事务与 coordinator 执行,未改变只读命令的行为。
|
||
|
||
### 容器镜像显示与校验
|
||
|
||
- 容器更新创建容器时使用用户提供的 tag 引用,使 `docker ps` / `docker inspect .Config.Image` 显示可读 tag。
|
||
- `backendexecutor.Request` 新增 `DisplayImageReference`,仅用于容器显示引用。
|
||
- 实际镜像仍使用不可变 digest 引用拉取、校验和事务记录;容器创建阶段继续校验镜像 ID,提交阶段同时接受 digest 引用或对应 tag 引用。
|
||
- 现有已创建容器不会被改写;下一次更新对应槽位后显示 tag。
|
||
|
||
### 验证与产物
|
||
|
||
- `go test ./...`、`go vet ./...`、`git diff --check` 通过。
|
||
- 生成 x86_64 RPM:`dist/yms-daemon-0.1.0-20260822072334.f536987a.x86_64.rpm`。
|
||
- RPM SHA256:`a3df708e54a95dadbf67487b4cd25dfa7599557237241638d00f38d390cf581e`。
|
||
|
||
---
|
||
|
||
## 2026-08-17 容器停止超时配置化 + 示例配置支持 native/container 快速切换
|
||
|
||
### 新增配置项
|
||
|
||
- `deploymentconfig.Backend` 新增 `stop_grace_seconds *int`(`[backend]` 下,可省略)。
|
||
- 容器后端停止旧容器时,SIGTERM 后到强制终止前的等待秒数;省略时默认 30。
|
||
- 配置值覆盖容器创建时的 9000 秒 StopTimeout;原生后端忽略该字段。
|
||
- `validateExactDocumentKeys` 的 backend 允许键新增 `stop_grace_seconds`;`Validate` 要求其为正整数。
|
||
- `backendupdate.Updater` 新增 `containerStopGraceSeconds`,由 `NewContainer` 从配置读取(缺省 30)。
|
||
- `containerStopOperation` 新增 `stopGraceSeconds` 字段,`switchAndCommitContainer` 与 `rollbackContainer` 传 `u.containerStopGraceSeconds`。
|
||
|
||
### 示例配置
|
||
|
||
- 重写 `packaging/etc/yms-daemon/yms-daemon.toml`:同时展示 native(默认启用)与 container(整体注释)两套 `[backend]` 块,顶部注释说明快速切换步骤与约束(type 必须与现场一致、native↔container 需走迁移事务)。
|
||
|
||
### 测试
|
||
|
||
`deploymentconfig/config_test.go` 新增:`stop_grace_seconds` 合法值接受、非正整数拒绝。全量 build/vet/test 通过。
|
||
|
||
---
|
||
|
||
## 2026-08-17 修复旧容器停不掉与启动日志跟随
|
||
|
||
### 破坏性变更
|
||
|
||
`containerengine.Engine.StopContainer` 签名由 `StopContainer(context.Context, string) error` 改为 `StopContainer(context.Context, string, int) error`(新增超时秒数参数)。
|
||
|
||
### 修复旧容器「kill 不掉」
|
||
|
||
- 根因:`MobyEngine.StopContainer` 用 `ContainerStopOptions{}`(不传超时),Docker 沿用容器创建时设置的 `StopTimeout=9000` 秒,Spring Boot 优雅停机长期不退时旧容器无法停止。
|
||
- `internal/containerengine/engine.go` / `moby.go`:`StopContainer` 增加 `timeoutSeconds`,`ContainerStop` 显式传 `Timeout`。
|
||
- `internal/backendupdate/container.go`:新增常量 `containerStopGraceSeconds = 30`,`containerStopOperation.Apply` 传入 30 秒,超时后 Docker 强制 SIGKILL。
|
||
|
||
### 修复启动日志跟随
|
||
|
||
- 根因:`ContainerLogs` 用 `Follow:false` 一次性读快照(读于容器刚启动时,Spring Boot 尚未输出),且 `RestartContainer` 的 `StartLog` 为 false。
|
||
- `internal/containerengine/moby.go`:`ContainerLogs` 改为 `Follow:true` + `io.Pipe` 持续流式返回。
|
||
- `internal/backendexecutor/executor.go`:`startAndCheck` 改为后台 goroutine 跟随读日志(`streamContainerLogs`),健康检查结束后取消跟随。
|
||
- `internal/backendupdate/container.go`:`RestartContainer` 的 `StartLog` 改为 true。
|
||
|
||
### 测试
|
||
|
||
三个测试 fake 的 `StopContainer` 签名同步更新。全量 build/vet/test 通过。
|
||
|
||
---
|
||
|
||
## 2026-08-17 实现 container 后端 restart
|
||
|
||
`ymsctl restart --service backend` 的 container 后端此前直接返回「restart is not implemented for container backend」,本次补齐。
|
||
|
||
### 变更文件
|
||
|
||
- `internal/backendexecutor/executor.go`:新增 `ImageAcquisitionPresent = "present"` 模式——镜像已在本地,跳过 pull/load,仅在 `prepare` 核对本地镜像 digest + platform。
|
||
- `internal/backendupdate/container.go`:新增 `RestartContainer`;新增 `inputTypeContainerRestart` 常量;`runContainerUpdate` 按 `InputType` 区分 `present`/`pull`;提取 `validateContainerInputs` 复用前置校验。
|
||
- `internal/backendupdate/restart.go`:`Restart` 按 `backend.type` 分派,container → `RestartContainer`,native 走原逻辑。
|
||
|
||
### 语义(对齐 native restart 决策 50)
|
||
|
||
- 复用本地镜像,不重新 pull,不依赖 registry。
|
||
- 每次调用执行一次真实槽位轮转,幂等键用随机 `restart:` 前缀,不复用历史 update 的内容幂等键。
|
||
- 无部署记录、gateway 活动端口漂移、活动容器身份不一致时拒绝。
|
||
- 未完成 restart 事务由同一命令恢复;复用 `runContainerUpdate` + `switchAndCommitContainer`。
|
||
|
||
### 测试
|
||
|
||
`container_test.go` 新增:正常 restart(轮转 + 不 pull + 提交部署记录)、无部署记录拒绝、gateway 漂移拒绝。全量 build/vet/test 通过。
|
||
|
||
---
|
||
|
||
## 2026-08-17 实现 status / doctor / reconcile
|
||
|
||
依据 `CLI_NAMING_AND_OPERATIONS_PLAN.md`(已并入 `PLAN.md` 附录)第 3.3 / 4 / 5 节,实现三个诊断与对账子命令。
|
||
|
||
### 破坏性变更
|
||
|
||
1. `daemonserver.New` 签名:由 `New(socketPath, updater, logger)` 改为 `New(socketPath, updater, diagnoser, logger)`。
|
||
2. `daemonapi.Request` 新增 `Apply bool`(`json:"apply"`),仅 `OperationReconcile` 使用。
|
||
3. `daemonapi.Response` 新增 `Diagnosis *Diagnosis`(`json:"diagnosis,omitempty"`)。
|
||
4. `daemonapi` 新增操作常量 `OperationStatus/OperationDoctor/OperationReconcile`,及诊断级别常量 `DiagnosisLevelOK/Fixable/Drift`。
|
||
5. `hostnginx.NewController` 已是 2 参数(`configPath, nginxExecutable`),重载走 `nginx -s reload`(并行期间他人改动,本轮按现状接入)。
|
||
|
||
### 新增 / 修改文件
|
||
|
||
- 新增 `internal/backendstatus/`:`diagnoser.go`、`container.go`、`native.go`、`reconcile.go`、`container_test.go`。
|
||
- 修改 `daemonapi/protocol.go`、`daemonserver/server.go`、`daemonclient/client.go`、`main.go`、`main_test.go`、`daemonserver/server_test.go`。
|
||
|
||
### 诊断模型
|
||
|
||
- 级别:`ok`(一致)/ `fixable`(可自动修复)/ `drift`(需人工)。
|
||
- `Healthy = true` 当且仅当无 `drift` 项。
|
||
- 展示过滤:`status` 只展示 drift/fixable,`doctor` 展示全部,`reconcile` 只展示 fixable。
|
||
- container 诊断以 `backend_container_deployment` 记录为事实来源;native 只读诊断(无自动修复)。
|
||
|
||
### 待办
|
||
|
||
- native 自动修复未实现(JAR 链接漂移修复需 filestore identity + release 校验)。
|
||
- `coverage.out` 未重新生成(不含新包)。
|
||
|
||
---
|
||
|
||
## 2026-08-22 Sonar 复杂度继续收敛
|
||
|
||
- 将部署配置的精确键校验拆为 root、daemon、backend、Node SSR 及槽位校验函数,保留原有字段与错误语义。
|
||
- 将 backend 校验按 native/container 分支拆分,降低单方法认知复杂度。
|
||
- 将 Node SSR Nginx marker 定位与 server 收集拆分,保留重复 marker、重复端口和槽位数量校验。
|
||
- 将容器镜像解析的平台校验、tag 校验、仓库 digest 收集拆分,保留摘要唯一性要求。
|
||
|
||
验证:`GOCACHE=/tmp/yms-go-cache go test ./...` 通过。
|
||
|
||
### 本轮继续拆分
|
||
|
||
- daemon server 将请求读取、进度回调、更新/重启分派、诊断分派拆开,保留协议错误文本与响应行为。
|
||
- `runServe` 将 native/container 运行时构建与资源关闭拆出,避免入口函数承担全部分支。
|
||
- 容器槽位现场核对拆为容器检查、已提交部署校验和活动槽位选择,减少单函数分支嵌套。
|
||
|
||
验证:`GOCACHE=/tmp/yms-go-cache go test ./...`、`git diff --check` 通过。
|