8.3 KiB
name, description
| name | description |
|---|---|
| unidesk-trans | UniDesk SSH 透传与 apply-patch 语法 — `trans <route> <operation>` 分布式执行入口,包含 route 语法、workspace/k3s/Windows 路由、apply-patch envelope 格式、script/py/upload/download operation 和 60s 短连接约束。用户提到 trans、tran、ssh 透传、远端执行、apply-patch、apply_patch、远端 patch、k3s route、workspace route 时使用。 |
UniDesk Trans(SSH 透传 + apply-patch)
UniDesk 分布式 SSH 透传入口,统一通过 trans <route> <operation> 在远端 host/k3s/Windows 上执行命令或文本 patch。
固定入口: trans <route> ...(wrapper 位于 /root/.local/bin/trans,等价 bun scripts/cli.ts ssh "$@")
Route 语法
trans <providerId>[/absolute/workspace] <operation> [args...]
trans <providerId>:<plane>[:<namespace>:<resource>[:<container>]] <operation> [args...]
Host workspace route
trans G14:/root/hwlab git status --short --branch
trans G14:/root/hwlab-v02 script -- 'git fetch origin v0.2 && git pull --ff-only origin v0.2'
trans D601:/home/ubuntu/workspace/unidesk-dev script <<'SCRIPT'
...
SCRIPT
规则: workspace 路径写在 route 第一个 token,不写进 cd 串。反面示例:trans G14 script -- 'cd /root/hwlab && git status'
k3s route
# 控制面
trans G14:k3s kubectl get pods -n hwlab-dev
trans D601:k3s kubectl get pods -A
# 指定 namespace + workload
trans G14:k3s:hwlab-dev:hwlab-cloud-web-abc/app cat /app/version.txt
trans G14:k3s:hwlab-dev:pod-name/workspace apply-patch <<'PATCH'
...
PATCH
CLI 自动注入 KUBECONFIG=/etc/rancher/k3s/k3s.yaml。
Windows route
trans D601:win ps <<'PS'
Get-ChildItem C:\test
PS
trans D601:win/c/test cmd cd
Windows operation 必须显式区分:ps 走 PowerShell,cmd 走 cmd.exe。
Operation
script(POSIX shell heredoc)
# heredoc(多行脚本)
trans G14:/root/hwlab script <<'SCRIPT'
echo "step 1"
git status --short --branch
echo "step 2"
SCRIPT
# one-liner
trans G14:/root/hwlab script -- 'git fetch origin G14 && git pull --ff-only origin G14'
# direct argv(单进程,带 -- 参数)
trans D601:/path script -- sed -n '1,20p' AGENTS.md
script 只走 host/k3s POSIX shell。Windows PowerShell 必须用 ps。
argv(单命令)
trans G14:/root/hwlab git status --short --branch
trans D601 hostname
apply-patch(远端文本 patch)
- P0: 所有远端文本/源码修改必须优先使用
apply-patch,禁止用py(python3 写文件)或sedheredoc 拼接大段文本替代。 只有当 apply-patch 本身不可用或需处理非文本/批量机械生成文件时,才使用其他受控方式;使用前必须在注释中说明原因,修改后立即用git diff或文件尾部检查确认没有截断或污染。
trans G14:/root/hwlab apply-patch <<'PATCH'
*** Begin Patch
*** Update File: AGENTS.md
@@
## Heading
context line
-old line
+new line
more context
*** End Patch
PATCH
# 从文件读
trans G14:/root/hwlab apply-patch < patch.diff
v2 引擎(默认):本地 TypeScript 解析 hunk,远端只读写文件。v1 legacy 入口:apply-patch-v1。
py(远端 Python 脚本)
trans D601 py -- arg1 arg2 < script.py
自动写到远端临时 .py 文件,python3 -u 执行后清理。
upload / download(整文件传输)
trans G14:/root/hwlab upload ./local-file.txt /root/remote-file.txt
trans G14:/root/hwlab download /root/remote-file.txt ./local-file.txt
自动校验 SHA-256,结果中 verified=true 即完整性证明。
kubectl / logs(k3s 诊断)
trans G14:k3s kubectl get pods -n hwlab-dev
trans G14:k3s logs deploy/hwlab-cloud-api -n hwlab-dev --tail 50
trans G14:k3s:hwlab-dev:hwlab-cloud-web-abc logs --tail 100
skills(远端 skill 发现)
trans G14 skills [--scope all|wsl|windows] [--limit N]
tcp-pool 状态与并发 smoke
查看 Provider 是否使用 SSH TCP data pool:
bun scripts/cli.ts debug health
在输出或 frontend 原始 JSON 里看这些 labels:providerGatewaySshDataTransport=tcp-pool、providerGatewaySshDataPoolReady、providerGatewaySshDataPoolClaimed、providerGatewaySshDataPoolDesired、providerGatewaySshDataPoolLastError。
快速验证 D601 维护桥:
trans D601 argv true
trans D601 argv hostname
并发 smoke 用短命令并给每路加本地 timeout:
tmp=$(mktemp -d /tmp/trans-d601-pool-10.XXXXXX)
for i in $(seq 1 10); do
timeout 30s trans D601 argv bash -lc 'printf start:'"$i"':%s\\n "$(date +%s%3N)"; sleep 2; printf end:'"$i"':%s\\n "$(date +%s%3N)"' >"$tmp/$i.out" 2>"$tmp/$i.err" &
done
wait
for i in $(seq 1 10); do echo "[$i]"; cat "$tmp/$i.out"; cat "$tmp/$i.err" >&2; done
期望是每一路 rc=0、stderr 为空、stdout 同时包含 start/end;结束后 pool labels 回到 claimed=0。
apply-patch 语法(Envelope 格式)
不是 unified diff,是 Codex 专用 envelope。
*** Begin Patch
*** Update File: <relative-path>
@@
context line
-old line
+new line
more context
*** End Patch
关键规则
| 规则 | 正确 | 错误 |
|---|---|---|
| 路径必须相对 | AGENTS.md |
/root/unidesk/AGENTS.md |
| hunk 分隔符 | @@ |
@@ -N,M +K,L @@ |
| 空行 | \n(空格+换行) |
裸 \n |
| 首行/尾行 | *** Begin Patch / *** End Patch |
外层不能有空行 |
操作类型
*** Update File: path/to/file.ext # 修改现有文件
*** Add File: path/to/new.ext # 新增文件(可覆盖已有)
*** Delete File: path/to/old.ext # 删除文件
*** Move File: old/path -> new/path # 移动/重命名
上下文定位
默认 3 行上文 + 3 行下文。同一 hunk 在文件中重复时用 @@ 跳到 class/function:
*** Update File: src/app.ts
@@ class MyComponent
old context
-old code
+new code
more context
常见失败
| 症状 | 原因 | 处理 |
|---|---|---|
failed to find expected lines |
上下文不匹配(文件已变) | 重读目标块,缩小 hunk |
| 空 stdout + stderr 报错 | 首行/路径格式错误 | 检查相对路径、envelope |
| partialChanges | 前序 hunk 成功,当前失败 | 基于当前文件状态补小 patch |
成功 stdout:Success. Updated the following files: + 文件列表。失败 stdout 为空,stderr 写原因。
远端 patch 正确姿势
第一个 route token 直接定位到目标 pod+workspace,不要从 host 生成 diff 再改路径上传:
# ✅ 正确
trans G14:k3s:hwlab-dev:hwlab-cloud-web-abc/app/web apply-patch <<'PATCH'
*** Begin Patch
*** Update File: app.mjs
@@
-old
+new
*** End Patch
PATCH
# ❌ 错误:host 生成 diff → 本地 sed 改路径 → 管道到 pod
60s 硬超时与短连接
trans 有 60 秒硬超时(不可调大)。长任务必须拆成 submit-and-poll:
# ✅ 异步启动 + 短轮询
trans G14:/root/hwlab script -- 'hwlab-cli case run start d601-f103-v2-compile'
trans G14:/root/hwlab script -- 'hwlab-cli case run status <runId>'
# ❌ 长时间挂着等
trans G14:/root/hwlab script -- 'long_running_command && wait'
HINT 信号
| stderr 输出 | 含义 |
|---|---|
UNIDESK_SSH_HINT |
SSH 握手/超时摩擦,提示改用 stdin script |
UNIDESK_TRAN_TIMEOUT_HINT |
60s 硬超时触发,提示改用短查询+轮询 |
UNIDESK_SSH_TIMING |
慢命令 warning(>10s),用于性能回归监控 |
UNIDESK_APPLY_PATCH_TIMING |
apply-patch 耗时摘要 |
关键约定
heredoc 优先
多行远端脚本优先用 heredoc,不拼接 shell 字符串:
# ✅ 推荐
trans G14:/root/hwlab script <<'SCRIPT'
cmd1
cmd2
SCRIPT
# ❌ 避免
trans G14 script -- 'cmd1 && cmd2 && cmd3'
本地 shell 运算符陷阱
&& / ; / | 在 trans 后面会被本地 shell 截获。需要远端执行多条命令时用 script 包裹:
# ❌ 第二个 sed 在 master server 本地执行
trans G14:/root/hwlab sed -n '1,20p' a && sed -n '1,20p' b
# ✅ 两个 sed 都在远端
trans G14:/root/hwlab script -- 'sed -n "1,20p" a && sed -n "1,20p" b'
Windows quoting
Windows PowerShell heredoc 用单引号 <<'PS':
trans D601:win ps <<'PS'
Write-Output "hello"
PS