fix: add scoped BuildKit GC entry

This commit is contained in:
pikastech
2026-07-21 08:02:59 +02:00
parent 3f8afa4ca4
commit a23c954258
3 changed files with 27 additions and 0 deletions
+1
View File
@@ -138,6 +138,7 @@ Worktree 清理由 `--include-merged-worktrees` 显式启用,只扫描 `config
- systemd journal vacuum 到目标上限。
- Docker `json-file` 日志截断。
- Docker BuildKit cache prune 只清理 owning YAML `hostDockerGc.buildCachePrune.until` 声明年龄之外的 cache;显式 `--build-cache-until` 可覆盖本次计划,不清理 images、containers 或 volumes。
- `--build-cache-only` 提供短连接 scoped plan/run,跳过 PVC、registry 和全盘 collectors;确认态仍要求 `--confirm` 并复用同一 YAML 筛选器。
- apt archive clean。
- allowlisted `/tmp` 诊断目录删除。
- 受限 core dump 删除。
+22
View File
@@ -1071,6 +1071,25 @@ def parse_docker_build_cache(text):
return {"sizeBytes": size, "reclaimableBytes": reclaim}
return None
def build_cache_only_payload(observed_at):
disk_before = df_snapshot()
section = host_docker_gc_section("buildCachePrune")
until = str(OPTIONS.get("buildCacheUntil") or section.get("until") or "24h")
if not host_docker_gc_enabled("buildCachePrune"):
return {"ok": False, "action": "gc remote %s" % ACTION, "providerId": PROVIDER_ID, "scope": "build-cache-only", "dryRun": ACTION == "plan", "mutation": False, "diagnosis": host_docker_gc_reason("buildCachePrune", "BuildKit cache GC is disabled by YAML")}
system_df = command(["docker", "system", "df"], 8)
if system_df["exitCode"] != 0:
return {"ok": False, "action": "gc remote %s" % ACTION, "providerId": PROVIDER_ID, "scope": "build-cache-only", "dryRun": ACTION == "plan", "mutation": False, "diagnosis": bounded(system_df)}
cache = parse_docker_build_cache(system_df["stdout"])
candidate = None
if cache is not None and cache["reclaimableBytes"] > 0:
candidate = {"id": "docker-builder:prune", "kind": "docker-build-cache-prune", "risk": "low", "sizeBytes": cache["sizeBytes"], "estimatedReclaimBytes": cache["reclaimableBytes"], "action": {"command": ["docker", "builder", "prune", "--all", "--force", "--filter", "until=%s" % until]}}
payload = {"ok": True, "action": "gc remote %s" % ACTION, "providerId": PROVIDER_ID, "scope": "build-cache-only", "configSource": "config/unidesk-cli.yaml#gc.remote.targets.%s.hostDockerGc.buildCachePrune" % PROVIDER_ID, "dryRun": ACTION == "plan", "mutation": ACTION == "run" and candidate is not None, "observedAt": observed_at, "diskBefore": disk_before, "until": until, "candidates": [candidate] if candidate else []}
if ACTION == "run" and candidate is not None:
payload["result"] = execute(candidate)
payload["diskAfter"] = df_snapshot()
return payload
def docker_containers():
ps = command(["docker", "ps", "-qa", "--no-trunc"], 5)
if ps["exitCode"] != 0 or not ps["stdout"].strip():
@@ -2776,6 +2795,9 @@ def main():
else:
emit_json(start_memory_pressure_job(observed_at, visible), persist_large=True)
return 0
if bool(OPTIONS.get("buildCacheOnly")) and ACTION in set(["plan", "run"]):
emit_json(build_cache_only_payload(observed_at), persist_large=False)
return 0
if (bool(OPTIONS.get("registry")) or bool(OPTIONS.get("hwlabRegistry"))) and ACTION == "plan":
emit_json(registry_plan_payload(observed_at), persist_large=True)
return 0
+4
View File
@@ -38,6 +38,7 @@ interface RemoteGcOptions {
historyLimit: number;
saveSnapshot: boolean;
memoryPressureOnly: boolean;
buildCacheOnly: boolean;
}
const DEFAULT_REMOTE_OPTIONS: RemoteGcOptions = {
@@ -69,6 +70,7 @@ const DEFAULT_REMOTE_OPTIONS: RemoteGcOptions = {
historyLimit: 12,
saveSnapshot: true,
memoryPressureOnly: false,
buildCacheOnly: false,
};
const GC_CONFIG_RELATIVE_PATH = "config/unidesk-cli.yaml";
@@ -298,6 +300,8 @@ function parseRemoteGcOptions(args: string[]): RemoteGcOptions {
options.saveSnapshot = false;
} else if (arg === "--memory-pressure-only") {
options.memoryPressureOnly = true;
} else if (arg === "--build-cache-only") {
options.buildCacheOnly = true;
} else {
throw new Error(`unknown gc remote option: ${arg}`);
}