Runner 多实例第一版实现方案
这篇文档记录 Runner 独立 PR 的第一版实现边界。目标是把 Runner CLI 收敛为 registry、local、pool、workflow 四个清晰子树,用它们管理多个本机 runner、多个注册 scope、多个 service,并且能在真实 Gitea 环境里调试和验收。
背景
当前已实践确认:
- host 后端可用,不必依赖 Docker;
- 同一机器、同一 Unix 用户下可以启动多个 runner root 和多个 runner daemon;
- 两个 repo-scope host runner 可以被同一个 PR workflow 的两个 job 并发调用;
- user-scope、org-scope、admin-scope runner 都能通过 workflow
runs-onlabel 被调用; - 旧的单 runner
setup入口已经不再作为第一版目标接口;后续文档和实践统一使用runner local。
因此第一版重点不是再证明 runner 能跑,而是把已经跑通的方式固化成 ChatTea CLI 和可维护的本机状态模型。
设计原则
- Registry 和 Local 分层:Gitea 服务器上的 runner 记录,和本机 runner root/service/log 是两层状态,CLI 需要分开表达。
- 直接收敛接口:初版不保留重复旧入口,正式使用
registry、local、pool、workflow。 - 按 name 管理本机实例:每个 runner 有稳定 name、root、config、
.runner、workdir 和 service。 - 先支持 host 后端:第一版把已实践的 host/native 后端做扎实;Docker 后端只保留配置入口和后续验证空间。
- 真实环境调试:接口实现后必须在真实 Gitea 服务上注册、启动、跑 workflow,并把结果回写到本地实践记录。
第一版目标 CLI 树
chattea runner
├── registry # Gitea 服务器上的 runner 记录
│ ├── token # 获取 repo/user/org/admin 注册令牌
│ ├── list # 按 scope 列出服务器端 runner
│ ├── view # 查看 runner 详情
│ ├── enable # 启用 runner
│ ├── disable # 禁用 runner
│ └── delete # 删除服务器端 runner 记录
│
├── local # 本机 runner 实例管理
│ ├── install # 安装或更新 gitea-runner 二进制文件
│ ├── create # 创建本机 runner root 和 config,不注册
│ ├── register # 注册本机 runner 到 Gitea
│ ├── list # 列出本机已管理 runner instances
│ ├── view # 查看某个本机 runner 的 root/config/service 状态
│ ├── start # 启动某个 runner service
│ ├── stop # 停止某个 runner service
│ ├── restart # 重启某个 runner service
│ ├── status # 查看某个 runner service 状态
│ ├── logs # 查看某个 runner service 日志
│ ├── doctor # 检查 binary/config/.runner/workdir/API 连通性
│ ├── config # 查看或修改 runner config.yaml
│ │ ├── show # 显示脱敏后的 config 摘要
│ │ ├── set-labels # 更新 labels
│ │ ├── set-capacity # 更新 capacity
│ │ ├── set-workdir # 更新 host.workdir_parent
│ │ └── set-backend # 更新 label backend 后缀
│ └── remove # disable service 并删除本地 runner root
│
├── pool # 多 runner 批量管理
│ ├── create # 创建 N 个 runner,适合同机并发
│ ├── start # 启动整个 pool
│ ├── stop # 停止整个 pool
│ ├── status # 查看 pool 状态
│ └── remove # 删除整个 pool,需要确认
│
└── workflow # workflow 与 runner label 辅助
├── labels # 列出当前可用于 runs-on 的 labels
├── example # 输出 runs-on 示例
└── check # 检查 workflow runs-on 是否有匹配 runner
本机状态模型
第一版使用每个 runner 独立 root:
<chattea-home>/runners/<runner-name>/
├── bin/gitea-runner
├── config/config.yaml
├── .runner
└── work/
service 名使用 runner name:
chattea-runner@<runner-name>.service
这样同一机器上可以明确管理多个 runner:
chattea runner local create lean-a --label lean-a --backend host
chattea runner local register lean-a --scope repo --repo OWNER/REPO
chattea runner local start lean-a
chattea runner local status lean-a
chattea runner local logs lean-a
注册 scope
第一版 local register 要显式支持四种 scope:
chattea runner local register repo-a \
--scope repo \
--repo OWNER/REPO \
--label repo-a \
--backend host
chattea runner local register user-a \
--scope user \
--label user-a \
--backend host
chattea runner local register org-a \
--scope org \
--org ORG \
--label org-a \
--backend host
chattea runner local register admin-a \
--scope admin \
--label admin-a \
--backend host
workflow 能否调用 runner,取决于两件事:
1. runner scope 是否覆盖当前仓库;
2. workflow 的 runs-on 是否匹配 runner label。
Host 后端约定
CLI 中用户传入的 label 不带 backend 后缀:
chattea runner local create lean-native --label lean-native --backend host
写入 runner config 时变成:
runner:
labels:
- "lean-native:host"
host:
workdir_parent: <runner-root>/work
workflow 中仍然只写 label:
jobs:
prove:
runs-on: lean-native
steps:
- run: echo ok
Pool 第一版
Pool 是多个本机 runner instance 的薄封装。第一版先支持固定命名:
<pool-name>-1
<pool-name>-2
<pool-name>-3
示例:
chattea runner pool create lean --count 3 \
--scope repo \
--repo OWNER/REPO \
--label lean-native \
--backend host
chattea runner pool start lean
chattea runner pool status lean
chattea runner pool stop lean
第一版的 pool 可以先做 create/start/stop/status/remove;scale 可以作为本 PR 的第二步实现,避免一次性引入太多删除和迁移逻辑。
验收计划
第一版实现后按下面顺序验证:
- 本地单元测试:覆盖 runner root 计算、config 生成、service 名、正式子树、pool name 生成。
- 文档构建:
mkdocs build --strict。 - 真实 Gitea 调试:
- 创建两个 repo-scope host runner;
- 用不同 label 注册并启动;
- 在实践仓库里提交 workflow;
- 触发 PR workflow;
- 确认两个 job 分别被不同 runner 接走且成功。
- Scope 回归:至少抽查 user/org/admin 中一类,确认新 CLI 注册路径可用。
- 记录回写:本地 project progress 记录命令、结果、失败点和后续 infra 缺口;公开 PR 文档只保留脱敏命令和结论。
非目标
第一版不解决以下问题:
- 不把 Docker 后端作为已验证事实;
- 不承诺不可信 workflow 的隔离安全;
- 不把 token、
.runner、真实服务 URL、机器本地路径写入公开文档; - 不一次性实现所有 org/user/team CLI 封装。