argus-cluster/specs/mvp/v3.0/v3.0_dev_plan.md

233 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MVP v3.0 开发计划TDD 驱动)
本文是 v3.0 的**工程化开发计划**强调“先写测试再写实现”TDD并将每个里程碑拆成**可独立验收**的小闭环。
输入依据:
- 路线图:`specs/mvp/mvp_roadmap_v2.md`
- v3.0 设计:`specs/mvp/v3.0/v3.0_design.md`
- v3.0 API`specs/mvp/v3.0/v3.0_api.md`
- v3.0 验收:`specs/mvp/v3.0/v3.0_acceptance.md`
- 现状基线v2.5Task queue + User mgmt + Stateless ray pool + 单镜像节点守护)
v3.0 已确认约束:
- 允许用户数据集路径:`/private/users/<me>/datasets/...`
- 允许用户本地模型路径:`/private/users/<me>/models/...`
- **不允许执行用户自定义代码**(不注入 user code 到 PYTHONPATH`code_path` 仍只允许 `/private/common/...`
- SFTPGo 先用 **password** 方案(方案 AAPI 联动创建/管理 SFTPGo 用户)
- jobs retention**3 天移入回收站trash/jobs再 7 天永久删除**;不提供 keep/延长保留标记
- janitor**API server 内置后台线程**;删除/移动采用**文件系统直接操作**(不依赖 SFTPGo API
---
## 0. TDD 规范(所有功能都遵循)
### 0.1 测试分层
1) **单元测试fast**
- 纯 Python 逻辑路径策略、SFTPGo client、retention 计算、文件移动/删除策略(用临时目录)。
- 不依赖真实 Ray、不依赖 docker、不依赖网络。
2) **组件测试(中等)**
- FastAPI 路由(含 WebUI 路由):`fastapi.testclient.TestClient`
- mock/stub SFTPGo client 与 ray client
3) **端到端(慢)**
-`argus@h1` 通过 docker compose + scripts
- Ray 集群自动起来head+2 worker
- SFTPGo 服务可用
- 上传数据 → 提交训练 → 下载产物 → jobs 回收站/清理
### 0.2 代码与测试约定
- 测试目录:`src/mvp/py/tests/`
- 新功能必须先补齐测试用例,并让其在未实现时失败(红)
- 最小实现让测试变绿(绿)
- 再做重构(重构)
- 覆盖率:继续沿用当前阈值(>= 90%
---
## 1. 里程碑拆分v3.0 = 5 个可验证闭环)
### M1TaskSpec 路径策略升级(允许 user datasets/modelscode_path 仍仅 common
**目标**
- API submit 时的路径校验从 v2.5 的 “仅 `/private/common/`” 升级为:
- `train_file` / `val_file`:允许 `/private/common/...``/private/users/<me>/...`
- 本地模型路径:允许 `/private/users/<me>/models/...`(不改变 YAML 结构,见实现建议)
- `code_path`:仍仅允许 `/private/common/...`
- 阻止越权路径(`/private/users/other/...`)与非 `/private/...` 路径。
**实现建议(不扩展 TaskSpec**
- `model_id` 字段保持不变:
-`model_id``/private/` 开头 → 视作本地模型路径
- 否则视作 HuggingFace repo id`Qwen/...`
**TDD 用例(先写测试)**
- 单测:
- `test_paths_allow_common_and_own_user_prefix()`
- `test_paths_reject_other_user_prefix()`
- `test_model_id_local_path_allowed_only_under_users_models()`
- `test_code_path_still_common_only()`
- API 测试:
- `test_submit_accepts_user_datasets_paths()`
- `test_submit_rejects_cross_user_paths_404_or_400()`(按约定返回 400/403
**验收点**
- `v3.0_acceptance.md` 的 D 类安全隔离用例可由 API 测试覆盖。
---
### M2SFTPGo 集成(方案 A用户联动创建 + password
**目标**
- 引入 `data management (SFTPGo)`
- admin 创建用户时联动创建 SFTPGo 用户home=/private/users/<user_id>chroot
- password 模式生成一次性密码reset/create并返回给 admin明文只返回一次
- 提供用户自助信息:
- `GET /api/v2/me` 返回 SFTP 连接信息、目录约定、retention 提示。
**实现建议**
- 新增 `SFTPGoAdminClient`(同步调用):
- 通过 `urllib``httpx`(建议 `urllib`,减少依赖;禁止 hard-code requests 使用)
- 支持create user / disable user / reset password最小集合
- API server 启动时校验配置enabled 时必须具备 admin 密码 env
- 同步创建用户目录结构(文件系统):
- `/private/users/<u>/{datasets,models,code,jobs,trash/jobs}`(最小必需)
**TDD 用例(先写测试)**
- 单测:
- `test_sftpgo_client_builds_correct_requests()`不发真实网络mock urlopen
- `test_user_dirs_created_on_user_create()`tmp dir 断言目录存在)
- API 测试:
- `test_create_user_calls_sftpgo_client()`stub client断言调用参数
- `test_me_returns_sftp_info_and_paths()`(含 trash/jobs 与 TTL 字段)
**验收点**
- `v3.0_acceptance.md` 的 A 类(用户/凭据)与 B 类(上传闭环前置)覆盖。
---
### M3WebUI最小可用多页面 + 侧边栏)
**目标**
- WebUI 由 API server 托管(同源,无额外 CORS
- `/ui/login`token 粘贴登录localStorage
- `/ui/tasks`:任务列表 + 过滤(最小)
- `/ui/tasks/new`YAML 提交(优先)+(可选)表单生成 YAML
- `/ui/tasks/{task_id}`:详情页
- `/ui/tasks/{task_id}/logs`:日志 tail + 可选自动刷新
- `/ui/data`SFTP 信息 + 目录/retention 提示
- (可选)`/ui/admin/users`:管理员用户管理(若时间允许,强烈建议)
**实现建议**
- 先不引入 Node 构建:
- HTML 模板可用最简单的字符串拼接或 Jinja2若引入 jinja2则补齐依赖与测试
- 页面通过 fetch 调用 `/api/v2/...`,并复用 token header
**TDD 用例(先写测试)**
- 组件测试TestClient
- `test_ui_routes_render_200()`
- `test_ui_contains_sidebar_links()`(简单断言文本包含导航链接)
- `test_ui_tasks_detail_shows_ids()`(包含 task_id、state、ray_submission_id
**验收点**
- WebUI 能完成:登录→创建任务→查看任务→查看日志→看到 data 页提示。
---
### M4Jobs Retention janitor3 天移入 trash7 天后 purge
**目标**
- API server 内置 janitor 后台线程:
- 周期性扫描 DB 中 terminal tasks
- 到期后执行:
- move`/private/users/<u>/jobs/<sid>``/private/users/<u>/trash/jobs/<sid>`
- purge递归删除 `/private/users/<u>/trash/jobs/<sid>`
- 全程严格 path 校验,禁止越界删除
- 清理操作记录到 DB events审计
**实现建议(数据与状态)**
- 需要稳定的时间锚点与幂等:
- 使用 attempts.end_time 作为 job 结束时间latest attempt
- 在 tasks 表新增字段(或新表)记录:
- `trashed_at`(首次成功 move 时间)
- `purged_at`(成功删除时间)
- `trash_path`(可选)
- 幂等:重复运行不会报错(目录不存在视为已处理)
**TDD 用例(先写测试)**
- 单测(用 tmpdir 构造 jobs/trash 目录):
- `test_janitor_moves_job_to_trash_after_threshold()`
- `test_janitor_purges_trash_after_threshold()`
- `test_janitor_never_touches_models_or_datasets()`
- `test_janitor_path_escape_rejected()`(恶意 path 不可删)
- API/组件测试:
- `test_me_includes_retention_fields()`jobs_trash_after_days/jobs_purge_after_days
**验收点**
- `v3.0_acceptance.md` 的 C2 用例可按“把阈值调小到分钟级”完成验证。
---
### M5端到端h1— SFTP 上传→训练→产物下载→回收站/清理
**目标**
-`argus@h1` 落一个一键脚本(或手册)跑通:
1) `docker compose up -d` 拉起 Rayhead+2 worker+ SFTPGo
2) admin 创建用户 alice联动创建 SFTPGo 用户 + password
3) alice 通过 SFTP 上传:
- 数据集到 `/private/users/alice/datasets/...`
- (可选)本地模型到 `/private/users/alice/models/...`
4) alice 通过 API/WebUI 提交任务引用上述路径
5) 任务成功后:
-`jobs/<sid>` 下载 logs/checkpoints
- 把权重移动到 `models/`,验证不会被清理
6) 把 retention 配置调小,验证 jobs→trash→purge
**交付建议**
- 新增脚本(命名示例):
- `scripts/run_all_v30_api.sh`
- `scripts/run_e2e_v30_cases.sh`
- 新增 `docker-compose.yaml` 中的 `sftpgo` service`docker-compose.v30.yaml` 叠加文件)
**验收点**
- `v3.0_acceptance.md` 全部 MUST 用例通过。
---
## 2. 风险与测试关注点
1) **权限与路径逃逸**
- path policy 必须覆盖train/val/model_id(local)/output dirsjobs/trash
- 所有删除/移动必须做 prefix 校验
2) **并发与竞态**
- janitor 只处理 terminal tasks避免清理正在写入的目录
- move 使用同文件系统 `os.replace`(原子)
3) **SFTPGo 可用性**
- SFTPGo 不在线不应影响训练与 API 核心功能(除了用户创建联动)
- janitor 不依赖 SFTPGo文件系统直连
---
## 3. 交付清单(代码/配置/脚本/文档)
### 3.1 代码
- Path policyv3.0
- SFTPGoAdminClient + user create/disable/reset password 联动
- `/api/v2/me` 扩展SFTP/目录/retention
- WebUI 路由与静态资源
- janitortrash+purge后台线程 + DB 记录
### 3.2 配置
- `configs/dev.yaml` 增加 `data.sftpgo``data.retention` 段(详见设计文档)
### 3.3 scripts / compose
- compose 增加 `sftpgo`(或新增 overlay compose 文件)
- v3.0 e2e 脚本(上传/下载/清理验证)
### 3.4 文档
- 更新 `specs/mvp/v3.0/*``src/mvp/README.md`运行方式、路径约定、SFTP 操作、retention 解释)