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

9.3 KiB
Raw Blame History

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 APIspecs/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 到 PYTHONPATHcode_path 仍只允许 /private/common/...
  • SFTPGo 先用 password 方案(方案 AAPI 联动创建/管理 SFTPGo 用户)
  • jobs retention3 天移入回收站trash/jobs再 7 天永久删除;不提供 keep/延长保留标记
  • janitorAPI server 内置后台线程;删除/移动采用文件系统直接操作(不依赖 SFTPGo API

0. TDD 规范(所有功能都遵循)

0.1 测试分层

  1. 单元测试fast
  • 纯 Python 逻辑路径策略、SFTPGo client、retention 计算、文件移动/删除策略(用临时目录)。
  • 不依赖真实 Ray、不依赖 docker、不依赖网络。
  1. 组件测试(中等)
  • FastAPI 路由(含 WebUI 路由):fastapi.testclient.TestClient
  • mock/stub SFTPGo client 与 ray client
  1. 端到端(慢)
  • 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 idQwen/...

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(同步调用):
    • 通过 urllibhttpx(建议 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/logintoken 粘贴登录localStorage
    • /ui/tasks:任务列表 + 过滤(最小)
    • /ui/tasks/newYAML 提交(优先)+(可选)表单生成 YAML
    • /ui/tasks/{task_id}:详情页
    • /ui/tasks/{task_id}/logs:日志 tail + 可选自动刷新
    • /ui/dataSFTP 信息 + 目录/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 servicedocker-compose.v30.yaml 叠加文件)

验收点

  • v3.0_acceptance.md 全部 MUST 用例通过。

2. 风险与测试关注点

  1. 权限与路径逃逸
  • path policy 必须覆盖train/val/model_id(local)/output dirsjobs/trash
  • 所有删除/移动必须做 prefix 校验
  1. 并发与竞态
  • janitor 只处理 terminal tasks避免清理正在写入的目录
  • move 使用同文件系统 os.replace(原子)
  1. 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.sftpgodata.retention 段(详见设计文档)

3.3 scripts / compose

  • compose 增加 sftpgo(或新增 overlay compose 文件)
  • v3.0 e2e 脚本(上传/下载/清理验证)

3.4 文档

  • 更新 specs/mvp/v3.0/*src/mvp/README.md运行方式、路径约定、SFTP 操作、retention 解释)