node 控制能力升级:缺 provider/allocation 子命令、窗口与运行态不可见、输出不可机读 #3
Labels
No labels
P0
P1
P2
P3
blocked
fixed-pending-verify
frozen-hold
manual-fallowup
needs-fix
rewrite
verified
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
xm/yuvuCli#3
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
背景
近两天做平台问题定位/验证时,凡涉及「受管运维动作」几乎都绕不开 CLI 的能力缺口,最后只能手写 REST 调用与直连只读数据库。可以用,但不好用:同一件事在 CLI 里没有入口,或入口给了错误/不完整的信息。以下全部为实测(NAS 节点,2026-09-26/27)。
缺口清单(含实测证据)
1. 没有受管运维子命令:provider / allocation(租约)
capability|task|workflow|template|resource|resources|runtime|node,无provider、无租约/allocation。yuvu provider list→error: usage: yuvu <capability|task|workflow|template|resource|resources|runtime|node> ...PATCH /api/v1/providers/{id}(base_url /unpin_base_url)、POST /api/v1/task-allocations/{leaseID}/release(释放卡死租约)、providercontrol/restart。这些正是排查execution target registration cannot change...一类故障的必需动作。yuvu provider list|get|patch(含--pin-base-url/--unpin-base-url)、yuvu provider restart、yuvu allocation list|show|release|renew。2. 看不到 capability 并发窗口与排队
max_concurrency,opencode 原为 1、现已调到 3)。CLI 无任何入口查看「谁占着窗口、有多少在 ready 排队」。max_inflight_reached拒绝」只能直连 DB 查task_invocations/ 并发字段。yuvu capability windows [-capability X](running/limit/ready 列表 + 占用者 task id)。3.
node deployment show缺运行态,只有声明 tagshow core -node nas -format json给出image: docker.lib.zuixue.site/yuvu/core:latest(tag,非 digest)、plan_hash、resolved_plan(env/labels/mounts),但没有:解析后的镜像 digest、容器运行态(running/exited、started_at、health)、实例数。upgrade --dry-run的 plan 里previous_image == next_image == ...:latest→ 无法判断本次部署是否真的会换构建。docker inspect侧推(本次排查#9/#17/#13都靠这种方式)。resolved_image_digest、runtime_state{status,started_at,health}、instances[];dry-run plan 输出解析后的 digest 并标注no change。4.
node status/node instance-info参数语义与报错不可诊断yuvu node status -node nas→error: node status requires at least one instance id;yuvu node instance-info -node nas同。node deployment show core用的是 deployment id,两处一个要 instance id 一个要 deployment id,命名未区分。例: yuvu node status core;统一--deployment/--instance参数名。5.
node logs是裸 envelope,无 tail/follow{ "action": "INSTANCE_ACTION_LOGS", "extensions": {...} },需手工剥壳;-format json|yaml存在但内容仍是 envelope。provider instance is not managed by agent(见 yuvuAdapter 侧问题)。-tail N/-since/-follow/-stderr,默认直接给人看日志文本。6.
--output与--format命名分裂 + 状态值大小写不一致task run|get:-output full|id|status|runtime|allocation(选字段)与-format yaml|json(选格式)并存;node *只有-format。task ... -output status返回大写枚举TASK_STATUS_SUCCEEDED。我方轮询脚本按小写匹配导致永不退出(空转到超时)。-format json|yaml,字段选择改-fields;状态值统一小写或文档明确枚举表。7. 凭据/前置条件缺失时错误不可诊断
yuvu node deployment show core -node nas→unknown node target "nas"(实际原因:缺YUVU_NODE_*等 env)。yuvu node self plan→request violates whitelist: image "" is not allowed(实际原因:节点自身不在 deployment 列表)。8. 错误没有分类/退出码约定
error: <文本>,脚本无法区分 404 / 凭据 / whitelist / 超时(remote runtime unavailable曾以 exit 125 出现)。error_class+ 稳定退出码表。期望的总目标
让「受管运维」在 CLI 内闭环:看得到(窗口/运行态/digest/日志)→ 改得动(provider pin、租约释放、受管重启)→ 机读稳定(
-format json+ 错误分类 + 退出码),不再需要手写 REST 和直连数据库。最小复现(逐条)
关联
node exec够不到 runtime 容器)internal_bug)、yuvuCore#18(base_url pin 被部署覆盖)补充:泄漏面比正文更广(2026-09-27 03:4x 追加实测)
正文只写了
yuvu node deployment show -format json的resolved_plan.env。刚又发现同一个泄漏也出现在yuvu node deployment upgrade <dep> --dry-run的compose_preview:即:同一份 env 里遮蔽策略不一致(
*_SIGNING_KEY明文,*_SECRET_KEY/*_RPC_TOKEN遮蔽),且所有会把 plan/compose 渲染出来的命令都带着它(至少show与upgrade --dry-run)。处置建议不变,但优先级提高:这是"只要跑一条只读命令就能拿到 Adapter V3 allocation 签名密钥"的暴露面,且签名密钥可用于伪造 allocation。若短时间内无法改代码,建议先把
YUVU_*_ALLOCATION_SIGNING_KEY轮换一次(轮换后旧的泄漏值失效),再修遮蔽逻辑。(本条不复制任何取值,只给形状与长度。)
✅ 复验通过并已合入
main(合并提交e591cfe,分支fix/cli-3tip8d03ee6保留)门禁:lane worktree 与合并树各跑一次
make check,两次 rc=0(internal/cli全部用例 ok)。反向验证(变异必红 → 还原 sha256 一致 → 复绿)
taskStatusText()从「小写 + 去TASK_STATUS_前缀」改回直接status.String()--- FAIL: TestTaskStatusOutputIsLowercase→status_output_test.go:18: expected lowercase status, got "TASK_STATUS_SUCCEEDED\n"sha256(internal/cli/task_output.go)与变异前一致,工作树干净,复绿(另一次尝试性变异「从
runtimeStateValue删掉running键」没有让TestNodeDeploymentShowIncludesRuntimeState变红 → 该用例对running键的断言偏弱,建议后续补强。)请验证这几点(真机)
yuvu task output --output status输出小写succeeded,shell 脚本可直接比较;yuvu node deployment show <id>输出稳定形状的runtime_state(status/health/running/instance_id,+started_at)与resolved_image_digest;runtime report 拉取失败时降级为runtime_state.status=unavailable且错误文本已脱敏,命令本身不整体失败;yuvu node deployment show --instance/--deployment别名、--fields、allocation list|show|lease renew、capability 并发窗口在真机可用且报错可操作。独立复验 + 合并完成(issue 保持 open,等真机验收)
分支
fix/cli-3tipf15c29f→ 已合并main=eb003ff(与 #1 的ac7130a同一条 main 序列,合并树门禁 rc=0)。改动两处:①
taskWatchEventSummary/taskWatchSummary统一走taskStatusText()(状态文本小写);② 新增「runtime_state 精确键集合」断言(2a3311c),使 digest/state 字段被改动的实现必红。门禁
反向验证
还原后
sha256sum internal/cli/task_observe.go=b0351f41911f118c5637ef0ac2783c8bf83108ddcf0c950e33a49fba98bedf2a==git show HEAD:同值 ⇒ 复绿 rc=0。请验证这几点(真机)
yuvu task watch/task get的状态文本一律小写(running/succeeded…),脚本消费不必再大小写兼容;yuvu node deployment show <name> -format json的runtime_state键集合稳定(新增/改名键会使测试红);node runtime exec联合使用(会话→运行时容器→状态可观测)。补充新发现(2026-10-03):上述 CLI 运行态缺口在最新 main/已合入提交上仍需真机验收。对 MAA workflow
1a056746-5dca-51d7-aa9c-0b8a7cde19e6实测,已成功任务仍返回 runtime.state/profile/session_id/provider_runtime_id/node_code 为<nil>,而 selected_instance_id、selected_node_code、provider_trace_id 存在。请把yuvuCore#41作为跨仓关联,优先验证 execution identity 的统一投影。当前 CLI 已补 provider/allocation、窗口/运行态、日志 tail/follow 与 help 等运维入口;go test ./... 通过,状态文本/运行态结构也有回归约束。但 issue 中错误分类/退出码统一和 NAS 全链路验收仍未完成;本轮记录为部分实现,保持 needs-fix/open,下一步补齐稳定错误契约后再验收。