feat(edge): route PACKAGES requests to the per-R-minor slot #152
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/per-minor-edge-routing"
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?
Problem
install.packages("curl")fails inreg.devxy.io/r/r-alpine:4.5-3.24with "package 'curl' is not available for this version of R", on both arches.curlis not missing from the repo: it is in…/latest/src/contrib/4.5/and…/4.6/, the per-minor slots that base R cannot address. The image's repo URL resolves to…/latest/src/contrib, whose index does not list it. Onamd64/alpine324that is 2 886 packages invisible toinstall.packages()(23 onamd64/noble) — what issue #63 records as "missing binaries".Two further findings while investigating:
cran.rpkgs.com/src/contrib/…form, and that form was broken for every Linux client on a stock R user agent:ALPINE_REGEX/UBUNTU_REGEX/RHEL_REGEXneed a Posit-style UA that carries the distro, so stock R fell through toextractOs()and got redirected to/amd64/linux-musl/latest/…, a slot that does not exist.PACKAGES*is servedcdn-cache: BYPASS(bincraft uploads itno-store), so the middleware sees every index request and no purge is needed for routing changes to take effect.What this changes
edge/rpkgs-router.ts— the middleware, now a reviewed file in this repo rather than dashboard state. It routesPACKAGES,PACKAGES.gzandPACKAGES.rdsinto…/src/contrib/<x.y>/for slots listed inUNION_SLOTS, and nothing else.Tarballs are deliberately left alone. R keeps the
contriburlit asked for, not the one the redirect served it, so every tarball URL is resolved against the flat directory and the union index steers the per-minor ones with aPath: <x.y>field. Rewriting a tarball request here would send flat-slot packages into a directory that does not hold them.Also in the script: the phantom
linux-gnu/linux-muslfallback is gone (an unidentifiable distro goes to CRAN, as an unparseable UA already did), and every redirect carriesCache-Control: no-storesince its target depends on the User-Agent. The macOS branches are unchanged.cdn.tf—bunnynet_compute_script.rpkgs_routerwithcontent = file("edge/rpkgs-router.ts"), theUNION_SLOTSvariable, andmiddleware_scriptpointing at the resource instead of the literal29277.UNION_SLOTSis empty, so merging and applying this changes no client's behaviour. A slot is added only once bincraft has republished its per-minor index as a union (rpkgs/bincraft#97); routing to a raw per-minor index would hide every package it does not carry. Rolling back is a variable edit, not a deploy.specs/,plans/— the design and the implementation plan, including the two approaches that were rejected (edge-side merge, moving the minor up the path) and why.Verification
just edge-testruns 13 routing cases against the SDK's local server, so what is tested is the artifact that gets deployed; pass-through cases proxy to the real origin. All pass.End to end, with the middleware in front of a locally built union index for
amd64/alpine324(31 507 records), inside the runtime image:tofu validatepasses.tofu planhas not been run: noBUNNYNET_API_KEYavailable in this environment.Before applying
The script pre-dates this configuration, so it must be adopted, not created:
The plan should show an in-place
contentupdate and no replacement of the pull zone. Without the import, tofu creates a second script and repoints the zone at it. Note thatname = "rpkgs-router"will rename the existing script on apply.Not fixed here
install.packages("curl")onalpine324will now resolve, then fail to build: that slot's tarballs are byte-identical CRAN source tarballs (noMeta/, noBuilt:in DESCRIPTION) which the index nevertheless stampsBuilt: R 4.5.3; …-linux-musl. Sampled:amd64/alpine3243/12 binary,arm64/alpine32413/30,amd64/noble12/12,amd64/alpine32317/20. That slot needs a rebuild, tracked separately.