Docs: static-port NAT path for the LXC, dispatcher back on LXC, Plane webhook allowlist notes
This commit is contained in:
+3
-2
@@ -95,7 +95,8 @@ docs/ design.md executor-contract.md runbook.md
|
||||
配置里只有 Vault 键名;token 由 `agent-access.py exec --secret-env` 注入 agentd 进程;执行器不持有 Plane 凭据、不能直接改工作项;webhook 是工作区级的一个密钥(Vault 键 `PLANE_WEBHOOK_SECRET`,只经 `--secret-env` 进接收端进程,不传给子进程),HMAC 校验失败 401,只认配置里的项目;接收端只听内网地址;页面仅 tailnet 可达,登录走既有网关。
|
||||
|
||||
## 9. 部署位置
|
||||
- Plane VM(plane-01)只跑 Plane:它是设备化节点(固定版本、每日备份停写路径),不放 agentd。
|
||||
- 网络(2026-10-21):LXC 到 NAS 的 tailnet 路径依赖 OPNsense 的静态端口出站 NAT 规则 + LXC tailscaled 固定 UDP 41642,已直连(详见 docs/deploy-lxc.md §2.1);曾因 DERP 导致调度器暂回 oregon,已于同日切回 LXC。
|
||||
- Plane VM(Plane 3.3.3,PVE VM 506 plane-02)只跑 Plane:它是设备化节点(固定版本、每日备份停写路径),不放 agentd。
|
||||
- 阶段 1–2:agentd 跑在 oregon(已有 Vault 客户端、Warpgate 中继脚本、Claude Code、现有 worker 状态),cron 拉起;配置页面同进程,只监听 tailnet 地址。
|
||||
- 阶段 3 起(**2026-10-21 PAD-11 已切换**):迁到 PVE 上的精简 LXC `agentd-01`(CT 600,root,仓库 `/opt/plane-agentd`,状态 `/var/lib/plane-agentd`,日志 `/var/log/plane-agentd`;1 vCPU / 1–2 GB,tailnet + 内网 10.77.10.0/24,与 Plane/Temporal 同网段,webhook 走内网)。**LXC 上不装任何 agent CLI**,只有 Python 3.10+、PyYAML、Agent Vault 客户端、ssh 客户端;所有终端(win10、oregon、mac…)一律远程启动(`transport: warpgate-ssh`),LXC 只负责调度、回帖、通知。对外访问经 Warpgate HTTP target,复用既有登录。
|
||||
- 远程启动的通用实现(P1-6,已实现):Linux/macOS 经 Warpgate SSH(`agent-access.py run --target <终端 target> -- bash -c …`)上传 `prompt.md`/`run.sh` 并一次调用内启动,`setsid nohup` 脱离会话(macOS 用 perl `POSIX::setsid`),轮询 `exit.txt`,从终端上的输出文件取回最后消息/线程 ID,kill 按进程组 + 会话;中继目标名由终端配置给出。oregon 已切到这条路径(调度器暂仍在 oregon,启动经 Warpgate 回到本机)。部署步骤:`docs/deploy-lxc.md`。
|
||||
@@ -109,5 +110,5 @@ docs/ design.md executor-contract.md runbook.md
|
||||
- **合并与补跑**:第一条投递后等 3 s,期间的投递合并成一次 tick;tick 运行中又来的投递 → 结束后再跑一次(运行中的 tick 可能在变化之前读过 Plane)。锁被占(cron/手工 tick;脚本 `flock -n -E 75`,`cli tick` 撞上 agentd 状态锁也退出 75)→ 每 15 s 重试,最长 2 min,之后交给 cron。
|
||||
- **进程隔离**:tick 用 `systemd-run --scope` 跑在独立 cgroup 里,重启/停止接收端不会杀掉正在跑的 tick(tick 可能正在启动远程运行)。
|
||||
- **延迟构成**:投递 → tick 开始 ≈ 3 s 合并窗口;tick 本身 = vault 取 token(1–2 s)+ 读 Plane + 先 poll 每个在途运行(每个中继调用约 10 s)+ 启动(中继约 12 s;win10 上传更久)。`[worker] 第 k 轮开始` 评论在启动调用返回之后才发,所以"建项 → 开始评论"受中继成本限制,而不是触发方式。
|
||||
- **Plane 的 SSRF 防护**:Plane(≥1.4 / 商业版 3.x)拒绝解析到私有/CGNAT 地址的 webhook URL(创建时和每次投递时都查),除非 Plane 的环境里有 `WEBHOOK_ALLOWED_IPS`(CIDR 列表)或 `WEBHOOK_ALLOWED_HOSTS`。内网接收端需要在 Plane 的 api 与 worker 容器环境里加 `WEBHOOK_ALLOWED_IPS=10.77.10.249/32`。
|
||||
- **Plane 的 SSRF 防护**:Plane(≥1.4 / 商业版 3.x)拒绝解析到私有/CGNAT 地址的 webhook URL(创建时和每次投递时都查),除非 Plane 的环境里有 `WEBHOOK_ALLOWED_IPS`(CIDR 列表)或 `WEBHOOK_ALLOWED_HOSTS`。内网接收端需要在 Plane 的 api 与 worker 容器环境里设 `WEBHOOK_ALLOWED_IPS=10.77.10.249/32`(改 `/opt/plane/plane.env` 与渲染的 `/var/plane/docker-compose.yml`,重建 api/worker,见 deploy-lxc §8)。截至 2026-10-21 尚未应用,webhook 未启用,调度靠 cron 轮询。
|
||||
- **心跳里的跳过原因**:每个 tick 把没派出去的 Todo 项和原因写进 `heartbeat.json` 的 `skipped`(`concurrency 1/1 (GW-15)`、`serialize_group game held by GW-4`、`busy_process codex (1 running, not started by agentd)`、`relay down`、`no route for assignee kappiee`、`start failed: …`),同一项的原因变化时才写一行日志。
|
||||
|
||||
Reference in New Issue
Block a user