Phase 0 (项目骨架):
- main.go 改为最小骨架 (config + logging + gin + /healthz + 优雅退出)
- internal/{config,logging,storage,cluster,...}/ 目录占位
Phase 1 (配置 + 日志):
- internal/config: env 解析 + 必填校验 + token 隐藏的 String()
- internal/logging: slog multi-handler 双输出 (终端 text + 主文件 JSON)
+ StartToolCall per-tool 独立文件 (0600), tools 目录 0700
Phase 2 续 (存储层):
- internal/cluster: 16 字段 Cluster struct (AuthPassword json:"-")
- internal/storage: modernc.org/sqlite 接入, WAL 模式, schema 自动迁移
- ClusterRepo CRUD: Create/Get/List/Update/Delete + ErrNotFound
+ AuthPassword 空字符串 = 保留旧密码 (核心约定)
- 7 个单元测试全绿 (:memory: DB)
- created_at/updated_at 改纳秒精度, 消除 List 测试的 sleep 特殊 case
Co-Authored-By: Claude <noreply@anthropic.com>
144 lines
6.6 KiB
Markdown
144 lines
6.6 KiB
Markdown
# Progress Log
|
|
|
|
> 会话日志,记录本项目所有重要进展
|
|
|
|
---
|
|
|
|
## 2026-07-10
|
|
|
|
### Session 1: 初始化 + 架构评审 + 计划编写
|
|
|
|
**参与**: User + Claude (Linus persona)
|
|
|
|
#### 进展
|
|
|
|
1. **仓库状态确认** (1dfef0f init)
|
|
- 单 init 提交,只有 GoLand 模板 main.go
|
|
- go.mod 已 pin 所有依赖(全是 // indirect)
|
|
- 没有任何业务代码、测试、文档
|
|
|
|
2. **创建 CLAUDE.md**
|
|
- 记录项目当前状态
|
|
- 列出标准 Go 命令
|
|
- 标注 4 个待确认决策
|
|
|
|
3. **用户提出初版架构方案** (v0.1)
|
|
- 5 个 Tool (spark_submit_cli / yarn_manage_job / fetch_spark_metrics / fetch_cluster_env / analyze_spark_log)
|
|
- Gin + MongoDB + MCP
|
|
- 3 个"底层元工具" (fetch_url / exec_shell / upload_file)
|
|
|
|
4. **Linus 视角评审** (3 个核心问题)
|
|
- **存储选型矛盾**: 文档说 SQLite,go.mod pin MongoDB,.gitignore 还有 data/ → 三选一
|
|
- **元工具归属不清**: 内部 Go / 暴露给 LLM / 外部 MCP Server,三种选择对应不同 API
|
|
- **Tool 粒度过细**: 5 个 Tool 里 3 个本质是 GET <URL>;analyze_spark_log 混了"抓"和"分析"
|
|
- **示例代码 API 不存在**: server.NewStreamableHTTPServer 等在 mcp-go v0.56.0 不存在
|
|
|
|
5. **用户回答 4 个关键决策** (v0.1 → v0.2)
|
|
- 存储: **SQLite** (替换 MongoDB)
|
|
- Spark 能力: **纯 RM/SHS 读模式** (不提供 spark-submit)
|
|
- MCP 传输: **Streamable HTTP**
|
|
- Tool 表面: **list_clusters + yarn_job_manage + fetch_url + upload_file** (4 个 Tool,不暴露 exec_shell)
|
|
|
|
6. **v0.2 计划编写**
|
|
- `task_plan.md` v0.2 — 7 个阶段,30+ 任务
|
|
- `findings.md` — 调研发现、风险分析
|
|
- `progress.md` (本文件)
|
|
|
|
7. **范围变更** (v0.2 → v0.3) — 用户中途修正
|
|
- **澄清**: `upload_file` 用途是 **spark-submit 时的 python 脚本上传**
|
|
- **冲突**: 与"纯 RM/SHS 不支持提交"决策矛盾
|
|
- **解决**: 用户确认**加 spark_submit** (使用 spark-submit shell 命令直接提交,在 admin 后台配置 binary 路径)
|
|
- **`upload_file` 重新定义**: 从"通用 HTTP 上传"改为"本地文件存储" (LLM 提交 content,Server 写到 `./data/`,返回路径)
|
|
- **Cluster 配置新增**: 单一 `spark_submit_execute_bin` (v0.3.1 进一步合并 spark_submit_path + spark2_submit_path)
|
|
- **Tool 总数**: 4 → **5** (重新引入 `spark_submit`)
|
|
|
|
8. **v0.3 计划更新**
|
|
- `task_plan.md` 重写,加入 `spark_submit` Tool 详细设计
|
|
- `findings.md` 更新: 新增命令注入风险、v0.3 范围变更章节
|
|
- 风险矩阵更新
|
|
- 决策日志新增 4 条 v0.3 决策
|
|
|
|
9. **v0.3.1 进一步合并** — `spark_submit_path` + `spark2_submit_path` → `spark_submit_execute_bin` 单一字段
|
|
|
|
10. **v0.3.2 强化发现入口** — `list_clusters` 标为强制入口,Cluster 加 `is_active`
|
|
|
|
11. **v0.3.3 加回高层 Tool** — `fetch_spark_metrics` + `fetch_cluster_env`(内部调 `fetch_url`)
|
|
|
|
12. **v0.3.4 加回规则引擎** — `analyze_spark_log` + 启发式过滤 (data_skew / gc_pressure / bottleneck) + LLM-Ready Prompt。新增 `internal/analyzer/` 包。Tool 总数 5 → **8**
|
|
|
|
13. **v0.3.5 大改**(用户给参考实现 spark_executor):
|
|
- 拆 `yarn_job_manage` → 4 个独立 RM Tool: `list_applications` / `get_application_status` / `get_application_logs` / `kill_application`
|
|
- 加鉴权层 (`none` / `basic` / `kerberos` 桩) + SSL 配置
|
|
- 加 manual redirect following (RM→NM 跨主机 307 必须保留 Authorization)
|
|
- `analyze_spark_log` 日志改走 RM `get_application_logs` 降级链
|
|
- Cluster struct 加 8 个鉴权/SSL/allowlist 字段
|
|
- Tool 总数 8 → **11**
|
|
- Phase 5 时间 6-7h → 10-12h
|
|
|
|
14. **v0.3.6 简化**(用户告知环境用 YARN SimpleAuth):
|
|
- 鉴权层去掉 kerberos 桩,改为 `none` / `simple` / `basic`
|
|
- `simple` 模式:`user.name` query param(默认 `"yarn"`)
|
|
- Hadoop 2.7 兼容性从风险表移除(用户已实测)
|
|
- Cluster struct AuthType 注释更新
|
|
|
|
15. **v0.3.7 用户接受所有 6 项建议**:
|
|
- Cluster 加 `default_submit_args` + `rate_limit_per_min`
|
|
- 删 `applications` 表(纯读不需要)
|
|
- `auth_password` PUT 留空 = 保留旧值
|
|
- 加 `audit_log` 表 + 路由
|
|
- 多 `AdminTokens` 支持(env 逗号分隔)
|
|
- analyzer 阈值改为 env 可配
|
|
- 无任何未决项
|
|
|
|
16. **v0.3.8 日志基础设施** (用户新要求):
|
|
- 用 `log/slog` 替换默认 log
|
|
- 终端 text handler + 主文件 JSON handler (multi-handler fan-out)
|
|
- Per-Tool 独立日志文件: `data/logs/tools/{ts}_{tool}_{id}.log`
|
|
- 文件权限 0600 (含敏感 params)
|
|
- T1.5 新增 + T5.13 Tool 集成
|
|
|
|
#### 当前 Tool 表面 (v0.3.8,11 个)
|
|
|
|
| # | Tool | 类型 | 备注 |
|
|
|---|---|---|---|
|
|
| 1 | `list_clusters` | **发现入口 (强制)** | 返回 cluster 全部元信息(含鉴权+allowlist) |
|
|
| 2 | `spark_submit` | 业务高层 | 本地 `exec.Command` |
|
|
| 3 | `list_applications` | **RM (v0.3.5 新)** | `GET /ws/v1/cluster/apps` |
|
|
| 4 | `get_application_status` | **RM (v0.3.5 新)** | `GET /ws/v1/cluster/apps/{id}` |
|
|
| 5 | `get_application_logs` | **RM (v0.3.5 新)** | 降级链:aggregated-logs → amContainerLogs → NM |
|
|
| 6 | `kill_application` | **RM (v0.3.5 新)** | `PUT /ws/v1/cluster/apps/{id}/state` |
|
|
| 7 | `fetch_spark_metrics` | 业务高层 SHS | 内部调 `fetch_url` |
|
|
| 8 | `fetch_cluster_env` | 业务高层 RM | 内部调 `fetch_url` |
|
|
| 9 | `analyze_spark_log` | 业务高层分析 | 规则引擎 + RM 日志降级 + LLM-Ready Prompt |
|
|
| 10 | `fetch_url` | HTTP 原语 | SSRF + 鉴权 + manual redirect |
|
|
| 11 | `upload_file` | 本地存储 | 路径白名单 |
|
|
| 4 | `fetch_url` | 通用 HTTP 原语 |
|
|
| 5 | `upload_file` | 本地文件存储 (v0.3 重新定义) |
|
|
|
|
#### 下一步
|
|
|
|
- [ ] **用户审阅 v0.3 计划**
|
|
- [ ] 用户确认 / 修改后开始 **Phase 0** 执行
|
|
- [ ] Phase 0 由 Codex 执行 (Go 依赖操作)
|
|
- [ ] 每个 Phase 结束: `go build` + `go test` 全绿才能进入下一 Phase
|
|
|
|
#### 待用户在执行前澄清的项 (在 task_plan.md "待确认项" 也有)
|
|
|
|
- `/mcp` 路由前缀是否带 `/*`?
|
|
- ADMIN_TOKEN 和 AGENT_TOKEN 是否合并?
|
|
- applications 表是否保留?
|
|
- 是否需要 Prometheus metrics?
|
|
|
|
---
|
|
|
|
## 会话状态
|
|
|
|
- **当前阶段**: v0.3 计划已写完,等待用户审阅
|
|
- **下一步行动**: 用户批准后 → Phase 0 (依赖调整)
|
|
- **阻塞项**: 4 个待确认项(可在 Phase 0-2 边做边问)
|
|
- **风险**: mcp-go v0.56.0 API 需在 Phase 6 实施前先查;spark_submit 引入的命令注入面需在 Phase 5.5 严格缓解
|
|
- **关键设计约束** (v0.3 强调):
|
|
- `exec.Command(name, args...)` **绝不**走 shell
|
|
- `upload_file` **绝不**做远程 HTTP 上传
|
|
- SSRF / 路径白名单 / token 鉴权 三道防线不变
|