HOMELAB-2479: feat(forgejo-runner): CI reservation trim 51.8->33.1 GiB, slots kept #876
No reviewers
Labels
No labels
operator-review
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Homelab/infra-core!876
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "plane/HOMELAB-2479-ci-trim"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
HOMELAB-2479 — CI reservation trim: 51.79 GiB → 33.14 GiB, all 23 slots kept, 2 h timeout untouched
Plan:
working-files/infra-stability/orch16/ci-reservation-plan.md(APPROVED), §2 table.GO (overseer, through El Director)
Measured before (live objects, not the repo)
kubectl get sts -n forgejo-runner -o json,.spec.template.spec.containers[*].resources.requests.memory, clockdate -u= 2026-11-06T12:44:42Z:statefulset/forgejo-runner(×8)statefulset/android-ci(×2)statefulset/android-emu(×2)statefulset/android-release(×1)statefulset/ld-ci(×1)statefulset/ld-push(×1)Pod request totals before = 51.79 GiB namespace-wide (pod sums: 3163, 6144, 3300, 6144, 2048, 584 Mi × replicas).
The change — requests only, per pool
forgejo-runner)forgejo-runner("k8s")android-ciandroid-emuandroid-releaseld-cild-pushforgejo-runnerrunner 2560Mi / dind 8Gi,android-ci12Gi,ld-ci6Gi.cm/forgejo-runner-configrunner.timeout: 2his not in this diff;android-emu's 2h +shutdown_timeout: 40mand 2700 s grace are untouched.sbx-sendrast, nothing in any sandbox pool, no node config, noprodchange (no image is published by this diff, so no pin bump).Risk, named (plan §2 — do not read this PR as "fixed")
requestsvalue can remove).Apply gate (NOT applied by this PR's author)
Apply only with no Sendrast job running, on homelab-ba's word through the overseer; read back from the live pod spec afterwards (
kubectl get pods -n forgejo-runner -o json→.spec.containers[*].resources.requests.memory), and expect pods to roll (android-emu's roll can take up to 45 min at 2700 s grace; android-release 90 s). Do not merge/apply while a job is in flight.Validation run
android-ci 2048 + android-emu 6600 + android-release 6144 + ld-ci 2176 + ld-push 584 + forgejo-runner 16384 = 33936Mi = 33.14 GiB.kubectl apply --dry-run=server -f <file> -n forgejo-runner:statefulset.apps/forgejo-runner configured (server dry run),statefulset.apps/android-ci configured (server dry run),statefulset.apps/ld-ci configured (server dry run),statefulset.apps/ld-push configured (server dry run).kubectl applywithout--dry-run.Review — APPROVE
Head reviewed:
dc4e2a54cdfa1879a6b436a565550661014ac7b0(exact head verified from the API before review; baselive960410f5f74cee5eeeff893bb8550cad359bbc29). Model:omniroute/deepseek-flash. Session:01a1b0f8-4445-76f3-8e2c-eccb8c7b163f.Verdict
APPROVE. No blockers. 3 concerns, 2 suggestions — every one is a follow-up, disclosed in the PR body or inherited from the approved plan, not introduced by this diff.
1. Diff vs the GO — exact
3 files, 3 hunks, three changed values, all
requests.memory:statefulset.yamlrunner2118Mi1003Miandroid-ci-statefulset.yamlrunner6Gi1Gild-pool-statefulsets.yaml(ld-ci)runner2Gi2176Mik8s is a pod-level move: 1003 + 1045 (dind) = 2048 Mi ✔. Limits untouched (runner
2560Mi/dind8Gi, android-ci12Gi, ld-ci6Gi), verified by reading the files at the head sha, not just the hunk context. Unchanged lanes verified from the head tree, not merely absent from the diff: android-emu 2×(2700+600), android-release 1×6144, ld-push 1×(172+412). Nothing insbx-sendrastor any sandbox namespace — no file outsidecore/manifests/apps/forgejo-runner/is touched, and the recursive tree at the head sha shows no duplicate/overriding definition of these StatefulSets anywhere else in the repo.2. Arithmetic — recomputed from the head files
33 936 Mi = 33.14 GiB — matches the brief's 33 936 Mi, the GO's 33.1 and the PR's figure. No drift in any changed line or in the total. Per-node: wk-05 = 22 984 Mi = 22.44 GiB ✔, wk-06 = 10 952 Mi = 10.70 GiB ✔ (both as stated). Slots 23 → 23: 16+2+2+1+1+1;
replicas:untouched in all six objects, no capacity/configmap in the diff.3. Scope safety — clean
No
labels,selector,nodeAffinity/nodeSelector/toleration,replicas,capacity,volumeClaimTemplates, grace period, image or timeout change. The only non-comment lines that changed are the threememory:request values.4. Apply gate — honest, and cross-checked
The body carries the required gate: apply only with no Sendrast job running, on homelab-ba's word through the overseer, read the live pod spec back after (
.spec.containers[*].resources.requests.memory), do not apply with a job in flight. Independently confirmed (read-onlykubectl get sts -n forgejo-runner, 13:09Z) that live still reads 3163 / 6144 / 3300 / 6144 / 2048 / 584 Mi — the change is genuinely not applied and the PR's "before" column is the live truth. CI on this exact head: 11/11 success, incl.runner-manifest-testandyaml-lint.Concern 1 — the k8s
runnerrequest is now below its own measured peakrunner.requests.memory = 1003Miagainst that container's measured 7 d peak 1786.55 Mi and the worst pod's cgroup peak 2258.79 Mi. Limits unchanged, so this moves eviction/OOM ranking, not the ceiling — the 8 pods become earlier eviction candidates on a node whose 7 d node-level peak was 52.31 GiB of 58.35 GiB allocatable. It is the direct arithmetic consequence of the GO's 33.1 GiB with 23 slots kept, and it is disclosed; not a defect of the diff. Needs a post-apply watch onkube_pod_container_status_restarts_total{namespace="forgejo-runner"}and node memory-pressure evictions on wk-05/wk-06 for 24 h.Concern 2 — the approved plan contradicts itself (PR resolved it correctly)
Plan §2 says pod 3163 → 2048 Mi; plan §5 says
runner 2118 → 2048with dind unchanged = 3093 Mi/pod = 41.30 GiB total (the PR's narrative says 41.28; exact is 41.30, 42 296 Mi). The PR implemented §2/the GO and disclosed the deviation explicitly — the honest resolution. Please correct the plan doc so the audit trail does not carry two shapes.Concern 3 — the "before" total does not reconcile with its own rows (inherited from plan §1)
25 304 + 12 288 + 6 600 + 6 144 + 2 048 + 584 = 52 968 Mi = 51.73 GiB, not 53 032 Mi / 51.79 GiB (64 Mi; the plan's note about 2 extra
Succeededdind-gc pods is the likely origin). The delta is therefore −18.59 GiB, not −18.65. The after figure is exact, so nothing in the change depends on it — narrative only.Suggestion 1 — do not let
android-cistay at 1 GiCorrect per the GO and nothing dispatches to it today, but leave an explicit step on HOMELAB-2479: raise it back to ≈12 Gi before any job is dispatched, or the first re-enabled android job runs a 12 GiB limit against a 1 GiB reservation on wk-05.
Suggestion 2 — only three StatefulSets roll
The body warns of android-emu's 45 min roll (2700 s grace) and android-release's 90 s; neither template is in this diff and neither is drifted from live, so neither rolls. Only
forgejo-runner(8),android-ci(2),ld-ci(1) do — the "no job in flight" window is far shorter than the body implies. Worth correcting so the operator does not wait 45 minutes for a roll that will not happen.Not verified by me
The 7 d peak figures are inherited from the PR body/plan (no Prometheus query run in this review);
android-ci/ld-ciidleness is inherited from the plan's live-branch check; whetherprodcarries an overriding patch was not read (out of scope for this diff, and the apply read-back is the right control); CI job logs were not read, only the head's status.