fix(disk-monitor): stop the disk check from purging live build workspaces #1

Merged
zachhandley merged 2 commits from fix/disk-monitor-safe-cleanup into main 2026-09-02 20:55:45 +02:00
Owner

Problem

The forgejo-runner-disk-monitor unit runs forgejo-runner cache clean --disk-check-only, whose "disk critical" branch (patches/forgejo-runner-fork.patch) purges the entire ~/.cache. On a host-executor runner that deletes the active act job workspace mid-build — the checkout/CWD, CARGO_HOME (registry crate sources), and git worktrees — so long compiles fail with could not parse/generate dep info … No such file or directory and failed to stat working directory …/hostexecutor.

Observed on a macOS host runner: a ~10-min Rust build was killed when the 5-min disk-monitor read 85% and logged Disk usage 85% is critical - clearing entire cache → Purged /Users/…/.cache (1.6 GB freed) at minute ~6.

Fix (Linux)

Point the disk-monitor at the same safe orchestrator the daily cleanup service already uses — forgejo-runner-cleanup --once: age-guarded cache (>CACHE_MAX_AGE_DAYS) and workspace (>WORKSPACE_MAX_AGE_DAYS, skips currently-running jobs) pruning plus threshold-based docker cleanup. No entire-cache purge. Unit timeout raised for the scan.

macOS (separate follow-up)

scripts/install-macos.sh generates an equivalent disk-monitor plist with the same destructive command. The mac cleanup path differs (inline bash -c daemon in com.forgejo.runner.cleanup.plist; no forgejo-runner-cleanup binary is shipped), so it needs its own change. The one live mac runner has been remediated directly in the meantime (disk-monitor repointed to an age-guarded pruner; ~/.cache/act restored to the external-volume symlink).

Root source (separate follow-up)

The destructive escalation itself lives in patches/forgejo-runner-fork.patch ("… is critical - clearing entire cache" → Purged %s). Making that branch age-guarded would fix every invoker, but the fork build is currently red (patches don't apply cleanly to upstream v12.13.x), so this unit-level change is what protects the deployed fleet now.

## Problem The `forgejo-runner-disk-monitor` unit runs `forgejo-runner cache clean --disk-check-only`, whose **"disk critical" branch** (`patches/forgejo-runner-fork.patch`) purges the **entire `~/.cache`**. On a host-executor runner that deletes the **active** act job workspace *mid-build* — the checkout/CWD, `CARGO_HOME` (registry crate sources), and git worktrees — so long compiles fail with `could not parse/generate dep info … No such file or directory` and `failed to stat working directory …/hostexecutor`. Observed on a macOS host runner: a ~10-min Rust build was killed when the 5-min disk-monitor read 85% and logged `Disk usage 85% is critical - clearing entire cache` → `Purged /Users/…/.cache (1.6 GB freed)` at minute ~6. ## Fix (Linux) Point the disk-monitor at the same safe orchestrator the daily cleanup service already uses — `forgejo-runner-cleanup --once`: age-guarded cache (>`CACHE_MAX_AGE_DAYS`) and workspace (>`WORKSPACE_MAX_AGE_DAYS`, **skips currently-running jobs**) pruning plus threshold-based docker cleanup. No entire-cache purge. Unit timeout raised for the scan. ## macOS (separate follow-up) `scripts/install-macos.sh` generates an equivalent disk-monitor plist with the same destructive command. The mac cleanup path differs (inline `bash -c` daemon in `com.forgejo.runner.cleanup.plist`; no `forgejo-runner-cleanup` binary is shipped), so it needs its own change. The one live mac runner has been remediated directly in the meantime (disk-monitor repointed to an age-guarded pruner; `~/.cache/act` restored to the external-volume symlink). ## Root source (separate follow-up) The destructive escalation itself lives in `patches/forgejo-runner-fork.patch` (`"… is critical - clearing entire cache"` → `Purged %s`). Making that branch age-guarded would fix every invoker, but the fork build is currently red (patches don't apply cleanly to upstream v12.13.x), so this unit-level change is what protects the deployed fleet now.
fix(disk-monitor): stop the disk check from purging live build workspaces
All checks were successful
CI - ForgejoRunner / Lint Shell Scripts (push) Successful in 9s
CI - ForgejoRunner / Test Chocolatey Package (push) Successful in 12s
CI - ForgejoRunner / CI Summary (push) Successful in 6s
CI - ForgejoRunner / trigger-build (push) Successful in 25s
CI - ForgejoRunner / Lint Shell Scripts (pull_request) Successful in 3s
CI - ForgejoRunner / Test Chocolatey Package (pull_request) Successful in 11s
CI - ForgejoRunner / CI Summary (pull_request) Successful in 3s
CI - ForgejoRunner / trigger-build (pull_request) Successful in 3s
b0f3b5f793
The disk-monitor unit ran `forgejo-runner cache clean --disk-check-only`, whose
"disk critical" branch (forgejo-runner-fork.patch) purges the entire ~/.cache.
On a host-executor runner that deletes the ACTIVE act job workspace mid-build —
the checkout/CWD, CARGO_HOME (registry crate sources), and git worktrees — so
long compiles fail with "could not parse/generate dep info ... No such file or
directory".

Point the disk-monitor at the same safe orchestrator the daily cleanup service
uses (`forgejo-runner-cleanup --once`): age-guarded cache/workspace pruning that
skips currently-running jobs, plus threshold-based docker cleanup. Raise the
unit timeout for the scan.

macOS install-macos.sh generates an equivalent disk-monitor plist with the same
destructive command; the mac cleanup path differs (inline daemon, no
forgejo-runner-cleanup binary) and needs a separate change — the one live mac
runner was remediated directly in the meantime.
fix(cleanup): don't let set -e abort the cycle on a benign no-op
Some checks failed
CI - ForgejoRunner / Lint Shell Scripts (pull_request) Successful in 3s
Test Shell Scripts / test-cleanup-cache (push) Successful in 3s
Test Shell Scripts / test-cleanup-workspaces (push) Successful in 5s
Test Shell Scripts / test-diagnose (push) Failing after 20s
Test Shell Scripts / lint (push) Successful in 15s
Test Shell Scripts / test-cleanup-cache (pull_request) Successful in 3s
Test Shell Scripts / lint (pull_request) Successful in 15s
Test Shell Scripts / test-diagnose (pull_request) Successful in 12s
CI - ForgejoRunner / Lint Shell Scripts (push) Successful in 37s
Test Shell Scripts / test-cleanup-workspaces (pull_request) Successful in 3s
Test Shell Scripts / test-cleanup-docker (push) Failing after 4m59s
Test Shell Scripts / test-cleanup-docker (pull_request) Failing after 4m56s
CI - ForgejoRunner / Test Chocolatey Package (push) Successful in 11s
CI - ForgejoRunner / CI Summary (push) Successful in 1s
CI - ForgejoRunner / trigger-build (push) Failing after 3s
Test PowerShell Scripts (Windows) / lint (push) Successful in 11s
Test PowerShell Scripts (Windows) / test-cleanup-cache (push) Successful in 12s
Test PowerShell Scripts (Windows) / test-cleanup-workspaces (push) Successful in 11s
Test PowerShell Scripts (Windows) / test-cleanup-docker (push) Successful in 11s
CI - ForgejoRunner / Test Chocolatey Package (pull_request) Successful in 11s
CI - ForgejoRunner / CI Summary (pull_request) Successful in 1s
CI - ForgejoRunner / trigger-build (pull_request) Failing after 4s
Test PowerShell Scripts (Windows) / lint (pull_request) Successful in 10s
Test PowerShell Scripts (Windows) / test-cleanup-cache (pull_request) Successful in 12s
Test PowerShell Scripts (Windows) / test-cleanup-docker (pull_request) Successful in 11s
Test PowerShell Scripts (Windows) / test-cleanup-workspaces (pull_request) Successful in 11s
7d8a74a16d
forgejo-runner-cleanup's tasks (remove_stale_locks, clean_cache, clean_workspaces,
clean_docker) end on — or early-return after — a false test (`[ $count -gt 0 ]`,
`[ $VERBOSE -eq 1 ]`, `[ usage -lt threshold ]`) when there is nothing to do, so
under `set -e` the function returns non-zero and the whole run aborts with exit 1.
This bricked both the disk-monitor and the daily cleanup service on any runner
where a cleanup pass had nothing to remove (the common case) — the daily service
sat in activating/status=1/FAILURE.

Wrap the task calls in run_cleanup with `|| true` so a benign non-zero from a
cleanup task never aborts the cycle; real mid-task failures still surface via the
task's own logging.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Public/ForgejoRunner!1
No description provided.