feat(edge): send unsupported R minors to CRAN instead of serving them
Falling back to the flat index for an excluded minor is the silent case: risky packages there are built under another minor and fail at load time, far from the cause. Send those clients to CRAN for sources instead, which is what the router already does for an unidentifiable distro. The whole interaction has to move, not just the index. R resolves tarball URLs against the repo it was configured with, so serving the index from CRAN and tarballs from here would hand R a binary where it expects a source tarball. A client reporting no R minor at all is not excluded: mirror scripts and image builds keep getting the flat slot. - Declare the supported window once in cdn.tf as local.rpkgs_supported_minors and set KNOWN_MINORS from it on both zones, so the router cannot drift from build-env-images' LATEST/PREV1/PREV2 unnoticed. - Split the verification script into supported and excluded minors: the former must have published indexes, the latter must have none and must redirect to CRAN under --live.
This commit is contained in:
parent
4c1e9b773c
commit
771d3a7768
1 changed files with 115 additions and 23 deletions
|
|
@ -121,6 +121,18 @@ function publicCdnOrigin(url: URL): string {
|
|||
return PUBLIC_CDN_HOSTS.has(url.hostname) ? url.origin : PUBLIC_CDN_ORIGIN;
|
||||
}
|
||||
|
||||
/**
|
||||
* True when the client reports an R minor that we deliberately do not serve.
|
||||
*
|
||||
* A client that reports no minor at all is not "unsupported": non-R fetchers
|
||||
* (mirror scripts, image builds) must keep getting the flat slot. Only a
|
||||
* known-and-excluded minor falls through to CRAN.
|
||||
*/
|
||||
function isExcludedMinor(userAgent: string): boolean {
|
||||
const rMinor = extractRMinor(userAgent);
|
||||
return rMinor !== null && !KNOWN_MINORS.has(rMinor);
|
||||
}
|
||||
|
||||
function extractRMinor(userAgent: string): string | null {
|
||||
for (const regex of R_MINOR_REGEXES) {
|
||||
const match = userAgent.match(regex);
|
||||
|
|
@ -249,6 +261,16 @@ BunnySDK.net.http
|
|||
return Promise.resolve(ctx.request);
|
||||
}
|
||||
|
||||
// An R minor outside the supported window has no binaries we can safely
|
||||
// serve, so the whole interaction goes to CRAN: the index and the
|
||||
// tarballs R will resolve against it. Serving the index from CRAN but
|
||||
// tarballs from here would hand R a binary where it expects a source
|
||||
// tarball, which fails in a far more confusing way than not being
|
||||
// served at all.
|
||||
if (UNION_SLOTS.has(slot) && isExcludedMinor(userAgent)) {
|
||||
return Promise.resolve(redirectTo(`${CRAN_ORIGIN}/src/contrib/${rest}`));
|
||||
}
|
||||
|
||||
const target = contribPath(slot, rest, userAgent);
|
||||
if (target === path) {
|
||||
return Promise.resolve(ctx.request);
|
||||
|
|
@ -263,6 +285,10 @@ BunnySDK.net.http
|
|||
return Promise.resolve(redirectTo(`${CRAN_ORIGIN}${path}`));
|
||||
}
|
||||
|
||||
if (UNION_SLOTS.has(slot) && isExcludedMinor(userAgent)) {
|
||||
return Promise.resolve(redirectTo(`${CRAN_ORIGIN}${path}`));
|
||||
}
|
||||
|
||||
const rest = srcContrib ? srcContrib[1] : '';
|
||||
return Promise.resolve(redirectTo(`${publicOrigin}${contribPath(slot, rest, userAgent)}`));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue