Repository navigation
CI's guest suite pulls its Debian image from ToyOSOrg's GHCR copy, with the run's token, by the same digest - #903
Conversation
…n's token, by the same digest Public ECR refused `guest / suite`'s container pull in the merge queue with `toomanyrequests: Data limit exceeded`: ECR Public gives unauthenticated clients 500 GB of data a month, and GitHub-hosted runners share their addresses. Docker Hub had refused it before for its own anonymous limit. The image, Docker Hub's `sid-20260918` (digest `a2aa4626…`), is copied once, every manifest byte for byte, to `ghcr.io/toyosorg/debian`, and both containers pull it with `container.credentials` from `github.token`, the callers granting `packages: read`. GitHub documents data transfer to Actions under `GITHUB_TOKEN` as free; the digest stays the pin, so the registry is no part of the provenance. nightly's `portability-linux` takes the same digest, since a copy made once cannot follow `sid`'s tag; its archive stays `sid` as it stands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Review of #903 at Checked and holding:
BLOCKER
NOTE
SEND BACK |
|
Rulings on round 1 (#903 (comment)): revert nightly's |
The review of #903 found that moving nightly's portability-linux onto the guest's 2026-09-18 copy breaks its premise, a fresh sid machine: deps installs without a full upgrade, so the base would drift ever further from sid and the job could pass where a fresh machine fails. It never hit ECR's limit, so it goes back to ECR Public's moving tag, and the issue row says so again. The GHCR copy was made with skopeo, which Arrivals asks declared: Go, so refused, with its exit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
|
Round 2 review of #903 at Round 1:
Gate at this head: BLOCKER NOTE
LAND AFTER NAMED CHANGES |
The package is private; a second copy doubles its charge to the private allowance, and whoever re-pins reads this row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
CI's guest suite (
guest.yml, called by ci.yml'sguestand nightly'stcg) pullsghcr.io/toyosorg/debian@sha256:a2aa4626…, ToyOSOrg's copy of Docker Hub'sdebian:sid-20260918, with the run's ownGITHUB_TOKEN. The digest is unchanged, so the pin and its provenance are what they were; only the registry and its authentication move. nightly'sportability-linuxstays on ECR Public's movingdebian:sid.Why
The merge queue's
guest / suitefor #892 (run 38340843761) failed before any test: public ECR refused the container pull withtoomanyrequests: Data limit exceeded. AWS's ECR Public quotas: "For unauthenticated customers, Amazon ECR Public supports up to 500GB of data per month. This is the max amount of data supported and isn't adjustable", plus a 1 pull/s unauthenticated rate (excerpt, from https://docs.aws.amazon.com/AmazonECR/latest/public/public-service-quotas.html). GitHub-hosted runners share their egress, so an anonymous pull from them spends a quota others spend too. Docker Hub was left for ECR in 3fb782c for the same reason, although GitHub's workflow-syntax page says hosted runners are exempt from Docker Hub's limits (excerpt); that exemption did not hold then, so it is not relied on now.Decisions
GITHUB_TOKENis the path GitHub documents for Actions:jobs.<job_id>.container.credentialswithgithub.actorand the token, its own example being aghcr.ioimage (excerpt, https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idcontainercredentials); "Data transfer is also free when an action installs a package", and GitHub Packages' billing counts a download as Actions' when it logs in withGITHUB_TOKEN(excerpt, https://docs.github.com/en/billing/concepts/product-billing/github-packages). GitHub documents no pull-rate limit for it. Authenticating the ECR pull instead would need an AWS account and an OIDC role; Docker Hub's would need an account and a stored secret.skopeo copy --all --preserve-digests; the index read back from GHCR hashes toa2aa4626…by tag and by digest (fill log, the index). The package is linked toToyOSOrg/ToyOS, which the publishing workflow's repository is granted automatically.packages: readat the job, not the workflow. ci.yml'sguestand nightly'stcggrant it to the reusableguest.yml(a called workflow cannot exceed its caller's token); every other job keepscontents: read.portability-linuxis untouched. Its premise is a freshsidmachine, image and archive both; a base copied once drifts fromsidbecausedepsdoes no full upgrade, and the job never hit ECR's limit (runs 38040586026, 38128536418, 38233410799 passed on it).skopeois declared inissues/the-build-runs-host-tools-outside-rust-and-qemu.md, the record Arrivals names: Go, so refused; exit, a Rust tool makes the copy or the container goes with the image row. The image row names the GHCR copy for the guest suite and ECR's anonymoussidforportability-linux.fill-ci-image.yml(kept here), dropped from the branch before review; the image is never refilled, and a new pin is a new copy made the same way, and the copy it replaces is deleted.Gates (head b572aac)
cargo run -- --ci host: EXIT=0, "Host: 76 step(s), all green" (log).guest.ymland ci.yml this head leaves as they were. Run 38344457897, on 296a2d5 plus the temporary workflow, concludedsuccess:toolchain / buildthen the realguest.ymlwithkvm: true, whose container step logged intoghcr.io, pulledDigest: sha256:a2aa4626…, and ran the suite to "Guest: 5 step(s), all green" (log, toolchain).toyosorg/debian:pullanswersUNAUTHORIZED(log), so thecredentialslines are what make that pull work.host-gate.loganddocs/github-packages-excerpts.txtcarried host paths; both are masked in evidence commit e7f4627aca124e99a3652aafa84dd64924058bd8. The branch is append-only, so 689af7a and 00c678c still hold the unmasked versions.Unsure
tcghas not run with its newpermissions:block; it is the same block as ci.yml'sguest, which did.🤖 Generated with Claude Code
https://claude.ai/code/session_015xhaydXCVRNscoccHYFUWy
Why the package stays private (orchestrator's ruling, replacing "make it public"). GitHub's API cannot change a package's visibility, and the browser step is the owner's. The pull is authenticated either way. The cost is storage against the organisation's private Packages allowance: about 368 MB for the one copy, which is all seven platforms plus attestations, summed from Docker Hub's tag API for
sid-20260918. A new pin is a new copy, so an old copy is deleted when its pin is replaced.