Conversation
src/libstore/filetransfer.cc
Outdated
| encoding = trim(line.substr(i + 1)); | ||
| else if (name == "accept-ranges" && toLower(trim(line.substr(i + 1))) == "bytes") | ||
| acceptRanges = true; | ||
| else if (name == "x-amz-meta-nix-is-immutable" || name == "x-nix-is-immutable") { |
There was a problem hiding this comment.
I also wonder if it might be more accurate to be named or x-nix-redirect-is-stable or something to make it more obvious that this is describing the fact that the redirect target isn't expected to change, not that its contents aren't expected to change (a slight difference).
But maybe this is probably bikeshedding, so feel free to disregard.
There was a problem hiding this comment.
Note that the header x-nix-is-immutable indicates the URL that was fetched is immutable. So:
GET http://flake-test.s3-website-eu-west-1.amazonaws.com/patchelf-latest.tar.gz
Location: http://flake-test.s3-website-eu-west-1.amazonaws.com/patchelf-442793d9ec0584f6a6e82fa253850c8085bb150a.tar.gz
then:
GET http://flake-test.s3-website-eu-west-1.amazonaws.com/patchelf-442793d9ec0584f6a6e82fa253850c8085bb150a.tar.gz
x-nix-is-immutable: 1
causes Nix to store that GET's URL in the lock.
If the first request had it, like this:
GET http://flake-test.s3-website-eu-west-1.amazonaws.com/patchelf-latest.tar.gz
x-nix-is-immutable: 1
Location: http://flake-test.s3-website-eu-west-1.amazonaws.com/patchelf-442793d9ec0584f6a6e82fa253850c8085bb150a.tar.gz
Nix would store http://flake-test.s3-website-eu-west-1.amazonaws.com/patchelf-latest.tar.gz in the lock.
There was a problem hiding this comment.
As a practical issue, using a header in the redirect doesn't work with S3 website buckets, since they don't allow custom headers on redirects.
There was a problem hiding this comment.
Given https://www.rfc-editor.org/rfc/rfc6648, I'd recommend not having an X- prefix on the header (where we have full control over the header name, at least).
There was a problem hiding this comment.
Or use a standard header
|
Instead of a redirect and custom header you could use a standard header, a By putting a full link in the header, you could let any response in the chain of redirects provide the permanent location:
So this is more standard and it allows more flexibility in service implementation. |
|
@roberth Using Wouldn't which is the URL that Nix would record in the lock file. |
The name is a bit confusing, as you really have to read the linked paragraph thoroughly to conclude that it refers to a resource like
I did consider it, but its use is for crawling/indexing, which might perhaps conflict, specifically when the resource considers itself to be more about the
EDIT: |
Maybe I read too much into the "latest version by timestamp" phrase. It could refer to the content of the final response instead of the URL. As an alternative, we could bring to life
It seems to have the least potential for ambiguity, despite not being a registered |
|
Or if we're ok with using a draft,
|
This comment was marked as outdated.
This comment was marked as outdated.
|
The purpose of
There's no mention of the immutability of contents, so the |
|
An example wouldn't hurt to illustrate the Link idea; it's not just a syntax change. Here's the shortest possible exchange: GET http://server/patchelf-latest.tar.gz
200 OK
Link: <http://server/patchelf-442793d9ec0584f6a6e82fa253850c8085bb150a.tar.gz>; rel="immutable"
<tarball data>As you can see it contains both the data and the pinned URL. If we want to test the immutable URL as part of locking, we could use a Here's a more elaborate exchange: First a dumb redirect. If we don't learn anything from the redirect, we just keep going. This lets users set up an indirection that makes them independent of their service choices. GET http://get-patchelf.io/letsgonix
302 Found
Location: http://server/patchelf-latest.tar.gz
GET http://server/patchelf-latest.tar.gz
302 Found
Link: <http://server/patchelf-442793d9ec0584f6a6e82fa253850c8085bb150a.tar.gz>; rel="immutable"
Location: http://cdn.server/c0584f6a6e82fa25?q=idkAt this point we have both the pinned URL for the lock file and a URL to start the actual download. GET http://cdn.server/c0584f6a6e82fa25?q=idk
200 OK
<tarball data>We didn't save a roundtrip because we got a 302, but that's ok. At least we do support cutting out the roundtrip as shown in the prior case. Maybe |
Previously, for tarball flakes, we recorded the original URL of the tarball flake, rather than the URL to which it ultimately redirects. Thus, a flake URL like http://example.org/patchelf-latest.tar that redirects to http://example.org/patchelf-<revision>.tar was not really usable. We couldn't record the redirected URL, because sites like GitHub redirect to CDN URLs that we can't rely on to be stable. So now we use the redirected URL only if the server returns the `x-nix-is-immutable` or `x-amz-meta-nix-is-immutable` headers in its response.
c98c775 to
1ad3328
Compare
|
Updated the PR to use |
|
Triaged in Nix maintainers team meeting 2023-06-09: (for reference)
|
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
|
Discussed in Nix team meeting:
|
|
I've added a "Protocols" chapter to the manual that documents how to serve tarball flakes. |
| ?rev=442793d9ec0584f6a6e82fa253850c8085bb150a | ||
| &revCount=835 | ||
| &narHash=sha256-GUm8Uh/U74zFCwkvt9Mri4DSM%2BmHj3tYhXUkYpiv31M%3D>; rel="immutable" | ||
| ``` |
There was a problem hiding this comment.
I don't know whether this or Link: <url>; rel="immutable"; rev="442..." is better. It gives the server implementer the option to not pass those parameters to the CDN. OTOH it could lead to some duplication, but is that a problem? Both seem like minor problems so I really don't know.
Maybe the folks at GitHub have a preference?
Co-authored-by: Robert Hensing <[email protected]>
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: |
Motivation
This PR adds the following improvements to tarball flakes:
Link: <url>; rel="immutable"HTTP header to return an "immutable" URL that will be recorded in lock files. Previously, the locked URL was the original URL, making redirects such ashttp://.../patchelf-latest.tar.gzpretty useless.The
Linkheader can be returned on any HTTP request in the chain of redirects. The "immutable" URL can include the flake attributesrevandrevCount(as HTTP query parameters), which makes it possible to mirror Git/GitHub flakes while retainingrev/revCount. The URL can also include thenarHashattribute for verifying the content.Instead of
Link, you can also usex-amz-meta-link, since S3 buckets currently don't allow setting a customLinkheader.Example:
Context
Checklist for maintainers
Maintainers: tick if completed or explain if not relevant
tests/**.shsrc/*/teststests/nixos/*Priorities
Add 👍 to pull requests you find important.