feat: migrate device pod cli to rest authority

This commit is contained in:
Codex
2026-05-29 11:30:17 +08:00
parent 6e1a63da91
commit f740fc9dbc
12 changed files with 623 additions and 1093 deletions
+12 -2
View File
@@ -26,7 +26,7 @@ device-pod-cli or cloud-web
- 用最少组件把 `device-pod-cli` 从“本地 profile + RPC/gateway 调用”迁到“1:1 REST 请求”。
- `cloud-api` 是用户身份、device grant、profile authority 和 lease 判断入口。
- `hwlab-device-pod` 承接设备业务:profile 校验后的运行、job 生命周期、freshness、blocker、bounded output 和 gateway 调用。
- `device-pod-cli` 只做 selector 解析、REST 请求和 JSON 输出,不保存或上传权威 profile。
- `device-pod-cli` 只做 selector 解析、cloud-api REST 请求和 JSON 输出;默认正式模式不读取 `.device-pod/*.json`,不保存、不上传、不修改权威 profile。
- 第一阶段只部署一个 `hwlab-device-pod` Deployment/Service,管理多个逻辑 `devicePodId`,避免为每台设备创建独立 k8s Service/Deployment。
- 普通用户和 code agent session 不获得 Kubernetes 用户、Service 直连权限、gateway route 或 host workspace route。
@@ -200,6 +200,7 @@ DELETE /v1/admin/device-pod-grants/{devicePodId}/{userId}
- `debug.reset`
- `io.ports`
- `io.uart.read`
- `io.uart.read-after-launch-flash`
- `io.uart.write`
所有响应必须包含 `devicePodId``targetId``profileHash``traceId``operationId``status``freshness``blocker` 和 bounded output metadata。真实硬件响应不得把 fake、dry-run、SOURCE、LOCAL 或过期缓存标为 `DEV-LIVE`
@@ -210,7 +211,7 @@ DELETE /v1/admin/device-pod-grants/{devicePodId}/{userId}
| --- | --- |
| `hwlab-cloud-api` | 用户身份、admin/user、device grant、lease、profile authority、用户态 REST API、转发到内部 device-pod。 |
| `hwlab-device-pod` | 多 `devicePodId` 运行 registry、profile runtime validation、job store、freshness、bounded output、gateway/device-host-cli adapter。 |
| `device-pod-cli` | 把 `devicePodId:surface:path operation args` 1:1 转成 cloud-api REST;不保存权威 profile、不直连 gateway。 |
| `device-pod-cli` | 把 `devicePodId:surface:path operation args` 1:1 转成 cloud-api REST;不保存权威 profile、不读取本地 profile 作为默认 authority、不直连 gateway。 |
| `device-host-cli` | Windows host 侧自包含业务工具,负责 Keil、pyOCD、UART、workspace 文件操作。 |
| `hwlab-gateway` | 只做受控 transport,不理解用户权限和 device-pod 授权。 |
| `hwlab-cloud-web` | 展示用户可见 device pod、admin 管理 profile/grant、显示 job/status/freshness。 |
@@ -248,6 +249,15 @@ manages: many devicePodId
- `POST /v1/device-pods/{devicePodId}/leases` 只对已授权 actor 创建或刷新互斥租约,响应只返回一次性 `leaseToken`;后续强副作用 job 必须通过 `leaseToken``x-hwlab-device-lease-token` 证明持有租约。
- 撤销 device pod grant 必须释放该用户对同一 `devicePodId` 的活动 lease。
## CLI 实现口径
`tools/device-pod-cli.ts` 是 v0.2 正式 CLI 实现,稳定 runner 入口仍是 `/app/skills/device-pod-cli/scripts/device-pod-cli.mjs`。该 `.mjs` 只作为兼容启动器,通过 Bun 运行 TypeScript CLI。正式 CLI 的默认行为是:
- `profile list/show` 调用 cloud-api `/v1/device-pods``/status`,只显示服务端脱敏 profile 摘要和 `profileHash`
- `devicePodId:workspace|debug-probe|io-probe...` selector 转换为 `POST /v1/device-pods/{devicePodId}/jobs` 或 job status/output/cancel REST,不直接调用 `/v1/rpc/hardware.invoke.shell`
- mutating job 继续由 cloud-api 侧强制 lease/reasonCLI 只转发 `reason``leaseToken`,不在本地绕过。
- `profile create` 这类本地 profile bootstrap 在正式默认路径中返回 `legacy_profile_create_removed`;管理员应使用 cloud-api admin API 管理服务端 profile/grant。
## 测试规格
## T1
+2
View File
@@ -13,6 +13,7 @@
- `tools/hwlab-cli/bin/hwlab-cli.mjs` 是唯一 CLI bin 入口。
- `tools/hwlab-cli/lib/cli.mjs` 负责参数解析、JSON 输出、legacy cicd 拒绝、M3 Skill CLI 转发和 MVP e2e dry-run plan。
- `hwlab-cli-template``suspend: true` 的 Kubernetes Job template,运行时通过 env 注入 endpoint、commit 和 image metadata。
- Device Pod 专用 CLI 是 `tools/device-pod-cli.ts`,稳定 skill wrapper 为 `skills/device-pod-cli/scripts/device-pod-cli.mjs`;它属于 device-pod 受控 REST 客户端,不是 `hwlab-cli` 的 CICD/运维入口。
## API 接口说明
@@ -44,4 +45,5 @@
| legacy cicd 删除 | 已实现 | `cicd` 子命令返回明确错误。 |
| v02 Job template | 已实现 | `hwlab-cli-template` 存在且 `suspend: true`。 |
| live e2e 执行 | 未完全实现 | 当前 live path 在 blocker 或未实现时拒绝执行。 |
| Device Pod REST CLI | 已实现 | `device-pod-cli` 已迁到 Bun+TS 默认 REST authority;旧本地 profile/gateway RPC 路径不再作为正式默认入口。 |
@@ -27,7 +27,7 @@
| `POST /v1/device-pods/{devicePodId}/jobs` | 只接受 `hwlab-cloud-api` 内部调用;创建内部 executor job 并返回 job、freshness、output/cancel URL;有可用 profile route 和 `HWLAB_CLOUD_API_INTERNAL_URL` 时通过 cloud-api gateway dispatch 下发到 device-host-cli,否则返回 `gateway_dispatch_unavailable`。 |
| `GET /v1/device-pods/{devicePodId}/jobs/{jobId}``GET /output``POST /cancel` | 只接受 `hwlab-cloud-api` 内部调用,用于查询内部 job、bounded output 和取消非终态 job;普通用户仍必须走 cloud-api 用户态 API。 |
用户态 `POST /jobs`、job output/canceladmin profile/grant API 由 `hwlab-cloud-api` 实现,应以 [spec-device-pod.md](spec-device-pod.md) 为目标。
用户态 `POST /jobs`、job output/canceladmin profile/grant API 和正式 `device-pod-cli` REST 调用`hwlab-cloud-api` 实现,应以 [spec-device-pod.md](spec-device-pod.md) 为目标。`hwlab-device-pod` 不接受 CLI、浏览器或 Code Agent 直接上传 profile snapshot。
## 测试规格
@@ -48,4 +48,5 @@
| 正式 profile authority | 已在 cloud-api 实现 | `hwlab-device-pod` 不读取或覆盖 `device_pods.profile_json`。 |
| job lifecycle | 部分实现 | 用户态 job 由 cloud-api 鉴权、授权、lease 校验和持久化;executor 侧已提供内部 job create/get/output/cancel lifecycle,并能把 job dispatch 结果写回 bounded output。 |
| gateway/device-host-cli adapter | 部分实现 | executor 已通过 cloud-api internal dispatch 接入 gateway poll/result 和 device-host-cli 命令映射;真实执行仍依赖 profile route、在线 gateway 和 host CLI。 |
| device-pod-cli REST authority | 已实现 | `tools/device-pod-cli.ts` 默认只走 cloud-api REST,不读取 `.device-pod/*.json` 作为 profile authority;旧 `.mjs` 入口只负责启动 TypeScript CLI。 |