@cryptotaxi247 / infra / commits / 9bf74400

fastly: implement "Lockable HTTP Tarball Protocol" (Flakes) for channels.nixos.org

This is part of another PR over in NixOS/nixos-channel-scripts that implements the precomputed x-amz-meta-link header. For the motivation behind this change look there. Hydra executes mirror-nixos-branch.pl when a given channel advances. Thus, we need some sort of fallback to handle channels which have long been EOL. A fallback also allows this change to be deployed in any order and over the span of multiple days. Our default mode of operation is simply renaming the precomputed "x-amz-meta-link" header created by the script to "link", if it exists. Note that we cannot use "link" directly because AWS S3 does not allow it. As a fallback we take the "location" header (which always exists) and template it into "link". This lacks additional flake attributes like "rev" or whatever additional metadata the script may precompute, but is perfectly compliant with the "Lockable HTTP Tarball Protocol". When running into the fallback, the string returned by nixpkgs' lib.trivial.versionSuffix will contain "dirty" instead of "pre-git" or the proper 7-char substring of the rev. While we could have Fastly do a sub-request to fetch the git-revision txt right next to the tarball, I don't think it's worth the effort and complexity. Tested using <https://fiddle.fastly.dev/>. Ref: https://github.com/NixOS/nix/blob/61f49de7ae0b3899abdcc102832523153dd40d35/doc/manual/source/protocols/tarball-fetcher.md

emilylange committed Feb 21, 2025 at 13:07 UTC 9bf74400074851b5920a1023ea6abc4f3fd09ffe
1 file changed +13
terraform/channels.tf
+13
@@ -229,11 +229,24 @@ resource "fastly_service_vcl" "channels" {
229 # Note: we need to match on 301s and 302s here, since Fastly has multiple
230 # layers, and otherwise a redirect might still get cached at the second
231 # layer after the first layer turned a 301 into a 302.
232 + #
233 + # Additionally, this also implements the "Lockable HTTP Tarball Protocol"
234 + # to use nixexprs.tar.xz with Flakes and have it locked properly.
235 if (beresp.status == 301 || beresp.status == 302) {
236 set beresp.status = 302;
237 set beresp.ttl = 0s;
238 set beresp.grace = 0s;
239 set beresp.cacheable = false;
240 + if (req.backend.is_origin && std.suffixof(bereq.url, "/nixexprs.tar.xz")) {
241 + # rename prepared link header if available
242 + if (beresp.http.x-amz-meta-link) {
243 + set beresp.http.link = beresp.http.x-amz-meta-link;
244 + unset beresp.http.x-amz-meta-link;
245 + # otherwise, use fallback that contains no flake attributes (e.g. rev)
246 + } else {
247 + set beresp.http.link = "<" + beresp.http.location + {">; rel="immutable""};
248 + }
249 + }
250 return (pass);
251 }
252 EOT