- .gitea/workflows/ci.yml:后端 gofmt/vet/test + 前端 lint/test/build 双 job 门禁 - vitest + @testing-library + jsdom 落地,14 个命脉用例:useListQuery 乱序丢弃/卸载中止、 http.ts 401 单飞刷新+队列重放+失败登出+silent 直拒、审计防抖、StepDeploy 部署目标、query-utils - 版本注入断裂修复:main 补 buildTime/gitCommit 符号,build.sh/Dockerfile 注入 main.version, /health 返回真实版本,前端 package.json 版本对齐 2.0.0 - gofmt 清零(8 个存量未格式化文件)
=== 现象(线上实际日志)=== http: panic serving 172.19.16.138:35256: runtime error: index out of range [4] with length 4 lokistack/middleware.inferAuditFields(...) lokistack/middleware/audit.go:179 === 根因 === segments := strings.Split(strings.Trim(path, "/"), "/") if len(segments) >= 4 { resource = segments[3] resourceID = segments[4] // ← 4 段时越界 } /api/v1/hosts/2 正好拆成 4 段 [api v1 hosts 2],取 segments[4] 直接 panic。 影响面比想象大:**所有 4 段路径的写请求**(PUT/DELETE /hosts/:id、 /storage/:id、/clusters/:id 等)都 500,且中间件 panic 后审计也写不进去 —— 等于审计功能在最常用的更新/删除接口上完全失效。 === 修法 === 每个下标单独判断长度: if len(segments) >= 3 { module = segments[2] } if len(segments) >= 4 { resource = segments[3] } if len(segments) >= 5 { resourceID = segments[4] } === 回归测试(middleware/audit_test.go)=== TestInferAuditFieldsNoPanic : 0/1/2/3/4/5 段的 12 种路径 × 3 种方法, 全部不得 panic(原 bug 的 4 段路径在列) TestInferAuditFieldsFourSegments : 4 段时 module/resource 正确、resourceID 为空 TestInferAuditFieldsFiveSegments : 5 段时能解出 resourceID TestInferAuditFieldsSemanticActions: deploy/stop/install/uninstall/reset-password/ validate/test 语义动作不被位置解析覆盖 TestShouldAudit : 只读接口跳过、部署安装类必须记 === 顺带修:CLI 模式下的两处误报 === 1) backup 的 manifest.recordCount 恒为 0 原因:CLI(CronJob 里跑 lokistack backup)没 init DB,GetDB() 返回 nil。 改为 countRecords() 直接从备份出的字节数集合。 2) self-check 报「数据库: 未初始化」 同上原因,误报会让巡检脚本以为库坏了。 改为 CLI 模式直接解析数据文件统计(fileDBStats)。 === 实测(修复后)=== 修复前:POST /api/v1/hosts/2/validate → panic,无审计记录 修复后:POST /api/v1/hosts/2/validate → 200 audit-logs total=5,含 [hosts/validate] admin POST /api/v1/hosts/2/validate -> 200 [auth/login] POST /api/v1/auth/login -> 200 panic serving 计数 = 0 用户数据完好(initial-admin-password.txt 不存在,说明不是首次部署) 镜像:lghost/lokistack:latest + v0.1 = 2493a288758d