ci(ui-matrix): capture evidence when HFS cannot reach Elasticsearch - #451
ci(ui-matrix): capture evidence when HFS cannot reach Elasticsearch#451angela-helios wants to merge 1 commit into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
Heads up — #452 and #454 have both landed on Of the four commits here, one is still needed and three are superseded:
What replaced them. #454 moved the sweep from a nightly cron into a Your volumes-first ordering was right and is preserved — freeing volumes before images, with every step non-fatal, because a host at its quota fails image deletion (containerd needs a meta.db write) while volume removal frees the same filesystem without one. That lesson carried straight over. One deliberate change from your version. The volume sweep is Root cause, for context. The underlying leak was So this PR should reduce to just |
Companion to #452/#454, which fixed the volume leak that choked the Docker host and produced the nightly ES signature (#449: readiness curl passes, then the mapped port drops SYNs while ES stalls on fsync). What made that incident expensive was the blindness: nothing recorded the ES container's fate. On a wait-for-HFS failure the step now dumps the container state, OOM flag, log tail, and a live reachability probe. Also defensive, and logged either way: NO_PROXY names the backend hosts exactly, because reqwest does not honor CIDR entries the way the curl probes do — a proxy-configured runner would otherwise time out HFS's ES traffic while every probe passes. Closes #449
2b2a80d to
19c9088
Compare
|
Post-#452/#454 validation on this branch (run 30582018605): the Docker-level failures are gone — both ES legs boot, seed, and run the suite. |
Every CI cleanup path force-removed its containers with `docker rm -f`, which does not remove anonymous volumes. The postgres, elasticsearch, mongo, minio and keycloak images all declare VOLUME in their Dockerfiles, so each testcontainer created one — and each reap orphaned it permanently. The shared self-hosted Docker host is an LXC container on a ZFS dataset with a 200G refquota. The orphans filled it until containerd could not write io.containerd.metadata.v1.bolt/meta.db, at which point *every* container start failed with "disk quota exceeded" (EDQUOT, not ENOSPC — the dataset quota, not a full disk). `docker system df` on the host still showed 144 volumes with only 4 active after a manual prune. Add `-v` to all 84 call sites across 16 workflows. This removes only anonymous volumes; named volumes are never touched by `docker rm -v`, and no workflow creates or mounts one — every volume in play here is anonymous. This fixes the leak at the source. The nightly janitor in HeliosSoftware#451 remains worth having as a backstop for runs that die before reaching cleanup, but a 05:30 UTC sweep could not have saved a run that failed at 16:03.
Closes #449
Slimmed after #452/#454 — Steve's PRs root-caused and fixed what my dispatches had been circling: every reap orphaned the testcontainers' anonymous volumes (
docker rm -fwithout-v), and the choked host produced the nightly ES signature (readiness curl passes, then ES stalls on fsync and its mapped port drops SYNs — 30s connect timeouts from HFS's first request while the process still looks alive). My earlier janitor/cron approach here is superseded by the per-rundocker-host-gcaction and has been dropped from this branch.Why this PR is still worth merging
NO_PROXYfor the HFS process — no longer speculative. When first written this was defensive ("current runners show none set"). Theterminology_integrationfailure on PR fix(bulk-submit): key entry results by their manifest output file #466's CI then demonstrated proxy-configured runners exist in the pool: the HTS client detoured through an egress proxy and hung 13 minutes (root-caused and fixed client-side in fix(terminology): the HTS client must fail fast, not hang behind a proxy #469). HFS's Elasticsearch client is the same reqwest with the same CIDR-no_proxyblind spot — on one of those runners, the matrix ES legs would fail with the same phantom timeouts. Naming the backend hosts exactly works for both curl and reqwest, and the step logs which proxy variables are present so any future incident can rule this in or out at a glance.Validation
Dispatches on the pre-#452 branch demonstrated the failure and the recovery: with the host at quota, even image prunes refused (
meta.db: disk quota exceeded); after a volume-first prune, run 30563256271 went green on sqlite-elasticsearch (the leg that failed every night) plus sqlite/postgres/mongodb, with s3-elasticsearch's single failure being the known #442Recentbug (fix in #440).Post-#452/#454 validation on this rebased branch (run 30582018605): the Docker-level failures are gone — both ES legs boot, seed, and run the suite;
s3-elasticsearcheffectively green (94/1, the 1 being #442);sqlite-elasticsearchsurfaced the real product bug the choked host had been masking, filed as #462 — with the conformance probe and these diagnostics being what made that legible from workflow logs alone.