You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(cleanup): resolve every cleanup entry point through one retention policy (#10562)
Cleanup is reachable through an aggregate planner and a set of category
specialists. Every one of them is a delete path, and every one of them
used to carry its own `default_value_t` retention literal.
Those literals happened to equal the shipped configuration defaults,
which made the drift invisible: the moment an operator widened
`retention.runtime_tmp_days` to 30, `homeboy self cleanup-runtime-tmp
--apply` still deleted at 7 days while `homeboy cleanup --include
runtime-tmp` honored the configuration. Same shape for `runs retention`
and `runs artifact cleanup-persisted` against `retention.terminal_run_days`
and `retention.limit`. A configured retention window being silently
ignored by a delete path is fail-open.
Add `homeboy_core::cleanup::resolve_cleanup_policy`, following the
precedent `controller_runtime::resolve_cleanup_options` set in #10288.
`None` on a command flag now means "use the configured value" and is the
only way a specialist can answer. The resolved policy is the manifest
reported in output, so a report cannot describe a window the deletion
did not apply.
Fail-closed rules the resolver enforces:
- A negative window or non-positive limit is rejected on every entry
point, including when it arrives from configuration rather than from
an argument.
- `scan_limit()` converts the record budget with `unwrap_or(0)`. The CLI
aggregate used `unwrap_or(usize::MAX)` in four places, which widens a
delete budget when a conversion fails.
- The two runner age floors become one named constant instead of a
literal `24` in the aggregate beside `default_value_t = 24` in each
specialist. They stay per-invocation arguments rather than becoming
configuration keys: both live on a remote host whose clock and
in-flight uploads the controller cannot fully observe, so lowering
them should not persist into every future sweep.
- `terminal_only` on persisted-artifact cleanup is documented as
non-overridable. Releasing evidence for a run that is still executing,
or whose state cannot be read, is data loss, not a preference.
Delete `homeboy runs retention`. It was the one specialist with no
narrowing argument left — its `--apply`, `--older-than-days`, and
`--limit` were exactly the aggregate's. Every other specialist survives
because it accepts a narrowing argument the aggregate cannot express
(`--run-id`, `--kind`, `--component`, `--prefix`, `--runner`,
`--passes`, `--cursor`) or is an explicit destructive escape hatch
(`runtime controller-prune --ignore-retention`). Folding those into
`--include`-scoped flags would put a dozen single-category flags on a
surface that sweeps thirteen categories.
Also account for the artifact root in `cleanup retained-storage`. It
accumulated from five sources and never called `artifacts::root()`, so
the one command whose purpose is "where did my disk go" was blind to the
product's primary output store. Persisted run artifacts, runner
downloads, and orphaned artifact bytes now contribute read-only plans,
and `safe_next_commands` names a reclaim command for each. Bytes a
planner would reclaim report `liveness: reclaimable` and are totalled
separately: "cleanup cannot free this" and "cleanup has not freed this
yet" are different answers and are never summed together. Unmeasured
sizes are reported as zero and never inferred.
Refs #10316
Co-authored-by: chubes-bot <266378653+homeboy-ci[bot]@users.noreply.github.com>
0 commit comments