14 KiB
name, description
| name | description |
|---|---|
| unidesk-gc | UniDesk 磁盘 GC 与主机压力处置流程。用于 `bun scripts/cli.ts gc ...`、 根盘高水位、worktree/缓存/日志清理、Web observe/Chrome 内存压力和安全停止判定。 |
UniDesk GC
-
处理 UniDesk 磁盘或内存压力时,优先使用受控 UniDesk CLI。
-
到达保护边界后停止,不得扩大为临时
rm -rf、Docker prune、数据库清理、原生 Kubernetes 删除或运行时状态删除。 -
长期规则以
docs/reference/gc.md为准。 -
执行远端 GC、k3s/PVC 归因、Web observe/Chrome 压力处置、registry/CI 留存或安全停止判定前,必须先读该文档。
本机流程
先执行只读归因:
df -h /
df -BG /
bun scripts/cli.ts gc plan --target-use-percent 69 --limit 50
默认计划存在缺口时,显式启用候选类别:
bun scripts/cli.ts gc plan --target-use-percent 69 --limit 2000 \
--include-tool-caches \
--include-stale-tmp \
--include-vscode-stale-servers \
--include-vscode-stale-extensions \
--include-vscode-cached-vsix \
--include-baidu-staging \
--include-state-artifacts \
--include-state-stale-scratch \
--include-codex-sessions \
--include-merged-worktrees \
--include-vpn-diagnostic-logs
复核计划后,只执行相同候选范围:
bun scripts/cli.ts gc run --confirm --target-use-percent 69 --limit 2000 \
--include-tool-caches \
--include-stale-tmp \
--include-vscode-stale-servers \
--include-vscode-stale-extensions \
--include-vscode-cached-vsix \
--include-baidu-staging \
--include-state-artifacts \
--include-state-stale-scratch \
--include-codex-sessions \
--include-merged-worktrees \
--include-vpn-diagnostic-logs
worktree 因 merge/cherry 超时而受保护时,只提高 worktree 临时预算:
bun scripts/cli.ts gc plan --target-use-percent 69 --limit 2000 \
--include-merged-worktrees \
--worktree-scan-budget-ms 120000 \
--worktree-cherry-check-timeout-ms 10000 \
--no-file-logs --no-docker-logs --no-journal --no-build-cache --no-tmp --no-db-summary
- 只对计划仍显示的候选执行匹配的
run --confirm。 - dirty、近期、活跃、未合并或超时保护的 worktree 必须继续受保护。
缓存与日志
单独检查 Docker 镜像候选:
bun scripts/cli.ts server cleanup plan --min-age-hours 24 --limit 80
- 返回零个过期镜像候选时,不得使用
docker image prune或docker system prune。 - 受保护镜像可能仍是当前运行或回滚真相。
默认 BuildKit 清理可能因缓存均较新而实际释放 0B。只有明确止压时才使用 --build-cache-all:
bun scripts/cli.ts gc plan --target-use-percent 69 --build-cache-all --limit 50 \
--no-file-logs --no-docker-logs --no-journal --no-tmp --no-db-summary
bun scripts/cli.ts gc run --confirm --target-use-percent 69 --build-cache-all --limit 50 \
--no-file-logs --no-docker-logs --no-journal --no-tmp --no-db-summary
Journald 上限也通过同一 CLI 管理:
bun scripts/cli.ts gc plan --target-use-percent 69 --journal-target-size 128M --limit 50 \
--no-file-logs --no-docker-logs --no-build-cache --no-tmp --no-db-summary
计划可接受时,使用参数完全匹配的 run --confirm。
临时转储
/tmp/unidesk-cli-output保存超大 JSON/stdout。- 截断的 plan/run 会持续写入新转储,因此 GC 诊断时可能增长到 GiB 级。
- 提取必要证据并确认没有活跃写入者后,可以删除该目录:
fuser -v /tmp/unidesk-cli-output 2>&1 || true
rm -rf -- /tmp/unidesk-cli-output
重复出现时应补受控 CLI 留存策略,不得把手工删除变成常规入口。
- 其他
/tmp目录先检查大小、mtime 和活跃 fd。 - 未明确归属和可重建性时,不得删除可能属于并行任务的当日 source/workspace scratch。
远端节点
- provider host 统一使用
bun scripts/cli.ts gc remote <providerId> ...。 - 远端长任务必须异步执行,并用
status --job-id短查询,不得维持长 SSH 会话。
已合并 worktree
先读取 YAML 策略并只生成计划:
bun scripts/cli.ts gc remote <providerId> merged-worktrees plan
- 仅枚举 Git 登记且位于
workspaceRoots的 worktree; - dirty、活跃、近期、未被
baseRef吸收、cherry 检查超时和主 worktree 必须显示为 protected; - 手动入口与 policy timer 复用同一筛选器,批量上限分别读取 YAML 的手动和自动字段;
- 执行前逐项重新计划,只允许
git worktree remove,不得删除 branch 或使用rm -rf。
复核候选后才允许执行:
bun scripts/cli.ts gc remote <providerId> merged-worktrees run --confirm
周期 stage 通过以下入口核对 YAML 字段、stage 和 inSync:
bun scripts/cli.ts gc remote <providerId> policy plan
bun scripts/cli.ts gc remote <providerId> policy status
内存分布与 Kubernetes 留存
先用紧凑 overview 归因真实内存压力:
bun scripts/cli.ts gc remote <providerId> memory-distribution
- 默认一次输出物理内存、PSS、进程 swap、cgroup、zombie 和 Kubernetes 对象分布;
- 同一结果必须直接披露
processes.topSwap,以及 zombie 父进程的 Kubernetes Pod 归属、 泄露分类和处置类别,避免额外执行ps、cgroup 映射和kubectl拼接; - swap 单独披露,不能计入 WebProbe 启动资格;
- 需要完整明细时才使用
--full。
发现大量 zombie 时不得尝试终止 zombie。先按 overview 的 owner 定位长期父进程, 修复子进程回收路径,再通过正常自动交付滚动 owner。运行面重启只能清除既有 zombie, 不能替代源码修复。
Kubernetes 历史对象手动回收固定使用:
bun scripts/cli.ts gc remote <providerId> retention plan --limit 500
bun scripts/cli.ts gc remote <providerId> retention run --confirm --limit 500
bun scripts/cli.ts gc remote <providerId> status --job-id <id>
- 筛选、保留窗口、分组、批量和级联策略只来自目标节点的
kubernetesObjectRetentionYAML; - 多 namespace 必须由共享
defaults与显式policies表达:- 一个
retention plan聚合显示全部 policy; - 每个 policy 使用唯一
configId和不会随 commit 变化的稳定 owner 分组标签; - CLI
--limit是每个 policy 的上限,并继续受对应 YAML 单批上限约束; - 根级
aggregatePreviewLimit控制聚合样例数,默认 overview 不得依赖第二次--full才能判断。
- 一个
- 手动入口与
policyTimer.includeKubernetesObjectRetention自动阶段必须复用同一筛选器; - 活跃、过新、未知分组、时间不可解析、扫描截断和 Table 形状漂移全部保护;
- 只删除 YAML 指定的根对象,通过 ownerRef 级联,不直接删除下游 TaskRun、Pod、Secret 或 Event;
- 自动回收由
gc remote <providerId> policy plan|install --confirm|status管理,周期和单批上限由 YAML 控制。 policy status必须一次披露期望与安装态的配置/runner 指纹、policy 数量、各 namespace 关键留存字段和inSync;- owning YAML 变化后只通过
policy install --confirm收敛安装态,禁止直接修改 host JSON、runner 或 systemd unit。
WebProbe 低内存人工处置
- 唯一资格指标:
- 只读取
/proc/meminfo的MemAvailable; - 输出必须披露
metric=MemAvailable、source=/proc/meminfo和swapExcluded=true; - swap 只作为独立压力信号,绝不计入启动可用量;
- 启动门槛和比较语义只读取
config/hwlab-node-lanes.yaml#templates.hwlabV03.webProbeWorkbench.resourcePolicy.memoryStartGuard; - 文档、skill、源码和测试不得复制
thresholdBytes的当前数值; - 除非用户明确授权修改 WebProbe 启动门槛,否则不得改变 owning YAML 的
thresholdBytes。
- 只读取
- 人工处置命令必须按顺序执行:
bun scripts/cli.ts gc remote <node> plan --memory-pressure-only
bun scripts/cli.ts gc remote <node> run --confirm --memory-pressure-only
bun scripts/cli.ts gc remote <node> plan --memory-pressure-only --memory-reclaim-config-id <id>
bun scripts/cli.ts gc remote <node> run --confirm --memory-pressure-only --memory-reclaim-config-id <id>
bun scripts/cli.ts gc remote <node> status --job-id <id>
bun scripts/cli.ts gc remote <node> memory
- 顺序约束:
- 默认 scoped plan 必须直接披露 YAML 限量候选摘要和
runEligibility,一次输出即可判断; - 只有
runEligibility.allowed=true时才允许执行明确标记安全的内存压力候选; --full只用于下钻完整身份明细,不得作为 scoped run 的默认前置步骤;run返回 job id 后,重复执行status --job-id <id>直到终态;- job 未终态时不得提前执行
memory或重试 WebProbe; - 终态后执行
memory,只有不再命中 owning YAML 的manualComparator时才可重试人工启动; - 内存处置不得改用未带
--memory-pressure-only的通用 plan/run。 - 只执行一个 cgroup 回收目标时,plan/run 必须携带相同的
--memory-reclaim-config-id <id>; <id>只能来自 owning YAMLmemoryPressure.cgroupReclaim.targets[].id,不得按运行面身份或候选排序猜测。
- 默认 scoped plan 必须直接披露 YAML 限量候选摘要和
- sentinel cadence:
- 命中 owning YAML 的
sentinelComparator时返回skipped-wait-next-round; - 不创建 observer、不启动 Chromium、不自动执行 GC;
- 等待下一轮 cadence 重新读取
MemAvailable。
- 命中 owning YAML 的
以下远端场景必须先读 docs/reference/gc.md:
- G14 registry/CI workspace 留存、k3s/PVC 归因和安全停止判定;
- PK01 pikanode 临时目录留存与 Docker provider 安全边界;
- JD01 k3s/PVC 归因,以及 NC01/JD01 Web observe artifact、Chrome/observer 内存增长与 YAML-first 真相源核对。
Web observe 与 Chrome 逃逸进程
- 正常生命周期:
- 远端节点的 Chrome 内存增长应先按 observer 生命周期问题处理;
- sentinel/quick-verify 的全部终态必须停止对应 observer;
- runner 的 TTL、maxSamples 和 artifact cap 必须来自 YAML;
- 归属尚未判清时不得按名称终止 Chrome,也不得删除 web-observe 目录。
- 保护边界:
- active observer、受控任务仍引用的浏览器会话及其完整进程树始终受保护。
- 只有独立且无归属的 Playwright
cliDaemon/Chrome 进程树才可进入精确终止:- 存活时间超过 owning YAML 定义的异常存活窗口;
- 受控 observe/sentinel 状态未显示该进程树归属于 active observer 或在途受控任务;
- manifest、heartbeat、PID/session 记录均不能把它归属到有效 run;
PID、PPID、SID、startTicks与后代进程能闭合为唯一身份;- 任一证据缺失或存在歧义时继续标记 protected。
- 精确终止:
- TERM 前重新核对
PID/PPID/SID/startTicks,防止 PID 复用; - 只向已核实的唯一进程树发送 TERM;
- 按 YAML 定义的有界等待时间重新枚举;
- 仍未退出时,只以不可变的
PID/startTicks复核残留身份; - 同时披露原始与当前
PPID/SID,允许 TERM 后重挂载但不放宽 PID 复用保护; - 只对复核后的同一残留进程树发送 KILL。
- TERM 前重新核对
- 禁止批量终止:
- 不得使用
pkill -f chrome、killall chrome或其他按进程名批量终止方式; - 证据不完整或归属存在歧义时保持 protected,不得猜测。
- 不得使用
- 终止后验证:
- 确认目标 PID、后代 PID 和 session/process group 全空;
- 确认 active observer 未受影响;
- 重新采集
/proc/meminfo的MemAvailable、独立 swap 信号、observer 状态和 Chrome/runner 摘要; - 结构化记录判定证据、TERM/KILL 结果、残留进程与终止前后资源数据。
JD01 等远端节点只能显式启用可重建工具缓存:
bun scripts/cli.ts gc remote JD01 plan --target-use-percent 49 --include-tool-caches --limit 100
bun scripts/cli.ts gc remote JD01 run --confirm --target-use-percent 49 --include-tool-caches --limit 100
- 必须先复核 plan。
- 候选仅限固定 allowlist 的 npm/npx/Bun 缓存。
- 不得改用
rm -rf ~/.npm ~/.bun,也不得触碰node_modules、auth/config、k3s/containerd、PVC 或 Docker volume。
保护边界
以下对象不得作为通用磁盘止压目标:
-
docker system prune、docker image prune、Docker/Compose volume 删除; -
未经
gc db-trace、备份和维护窗口的 PostgreSQL PGDATA/trace 清理; -
/var/lib/containerd、/var/lib/rancher/k3s、/var/lib/kubelet、PVC、registry blob、runtime snapshot; -
Codex auth/config/profile;session 仅能通过
--include-codex-sessions清理,活跃 SQLite 日志还需fuser与专门留存决策; -
以下 Web observe 与 Chrome 对象:
- active run 和 live observer runner;
- 归属或 stale 分类未闭合的 Chrome process tree;
- 缺少 manifest/heartbeat/pid/open-fd 证据的 web-observe state root;
- 只有按“Web observe 与 Chrome 逃逸进程”完成无归属判定的唯一进程树才可精确终止。
-
dirty、active、unmerged、recent 或 timeout-protected worktree;
-
用户未明确要求时的
backend-corerebuild/restart/replacement。 -
低风险候选执行后仍为
summary.target.safeStop=true时,停止并报告剩余压力源与决策选项。 -
不得绕过 CLI 追求目标百分比。
验证
使用以下有界证据收口:
df -h /
df -BG /
docker system df
du -sh /root/unidesk/.worktree /root/unidesk/.state /tmp /var/log 2>/dev/null || true
- 远端内存/Chrome 压力还需记录
free -h、Chrome/observer 摘要与 web-observe state 大小。 - 总结起止
df百分比、主要清理类别、受保护失败和剩余高风险压力源。