libfetchers: ensure that lastModified is a uint64_t

When lastModified comes via inputFromAttrs it ends up as string in the
Attrs map. This results in:

error: input attribute 'lastModified' is not an integer

Fix by handling it like revCount, which already does the right thing.
If added a test and confirmed that it catches the issue.

Also kudos to alexander.sieg@cyberus-technology.de for helping with
debugging this!

Change-Id: I8378fcaea986d798cb8458d4e6e15c2a92c2520a
This commit is contained in:
Julian Stecklina
2025-03-13 09:34:59 +01:00
parent 85a140accb
commit 0e59e5b308
4 changed files with 34 additions and 4 deletions
+7
View File
@@ -53,6 +53,10 @@ bb010g:
forgejo: bb010g
github: bb010g
blitz:
display_name: Julian Stecklina
github: blitz
cole-h:
display_name: Cole Helbling
github: cole-h
@@ -197,6 +201,9 @@ winter:
forgejo: winter
github: winterqt
xanderio:
github: xanderio
yshui:
github: yshui
+17
View File
@@ -0,0 +1,17 @@
---
synopsis: "Fix handling of `lastModified` in tarball inputs"
issues: []
cls: [2792]
category: Fixes
credits: [xanderio, blitz]
---
Previous versions of Lix would fail with the following error, if a
[tarball flake input](@docroot@/protocols/tarball-fetcher.md) redirect
to a URL that contains a `lastModified` field:
```
error: input attribute 'lastModified' is not an integer
```
This is now fixed.
+1 -1
View File
@@ -219,7 +219,7 @@ struct CurlInputScheme : InputScheme
url.scheme = parseUrlScheme(url.scheme).transport;
emplaceURLQueryIntoAttrs(url, attrs, {"revCount"}, {});
emplaceURLQueryIntoAttrs(url, attrs, {"revCount", "lastModified"}, {});
attrs.emplace("url", url.to_string());
return inputFromAttrs(attrs);
+9 -3
View File
@@ -3,6 +3,8 @@
let
pkgs = config.nodes.machine.nixpkgs.pkgs;
lastModified = builtins.toString nixpkgs.lastModified;
root = pkgs.runCommand "nixpkgs-flake" {}
''
mkdir -p $out/{stable,tags}
@@ -19,7 +21,7 @@ let
# arbitrary headers.
cat >$out/tags/.htaccess <<EOF
Redirect "/tags/latest.tar.gz" "/stable/${nixpkgs.rev}.tar.gz"
Header always set Link "<http://localhost/stable/${nixpkgs.rev}.tar.gz?rev=${nixpkgs.rev}&revCount=1234>; rel=\"immutable\""
Header always set Link "<http://localhost/stable/${nixpkgs.rev}.tar.gz?rev=${nixpkgs.rev}&revCount=1234&lastModified=${lastModified}>; rel=\"immutable\""
EOF
'';
in
@@ -69,23 +71,27 @@ in
# Check that we got redirected to the immutable URL.
locked_url = info["locked"]["url"]
assert locked_url == "http://localhost/stable/${nixpkgs.rev}.tar.gz?rev=${nixpkgs.rev}&revCount=1234", f"{locked_url=} != http://localhost/stable/${nixpkgs.rev}.tar.gz"
assert locked_url == "http://localhost/stable/${nixpkgs.rev}.tar.gz?lastModified=${lastModified}&rev=${nixpkgs.rev}&revCount=1234", f"{locked_url=} != http://localhost/stable/${nixpkgs.rev}.tar.gz"
# Check that we got the rev and revCount attributes.
# Check that we got the right attributes.
revision = info["revision"]
rev_count = info["revCount"]
last_modified = info["lastModified"]
assert revision == "${nixpkgs.rev}", f"{revision=} != ${nixpkgs.rev}"
assert rev_count == 1234, f"{rev_count=} != 1234"
assert last_modified == ${lastModified}, f"{last_modified=} != ${lastModified}"
# Check that fetching with rev/revCount/narHash succeeds.
machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?rev=" + revision)
machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?revCount=" + str(rev_count))
machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?narHash=" + info["locked"]["narHash"])
machine.succeed("nix flake metadata --json http://localhost/tags/latest.tar.gz?lastModified=" + str(last_modified))
# Check that fetching fails if we provide incorrect attributes.
machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?rev=493300eb13ae6fb387fbd47bf54a85915acc31c0")
machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?revCount=789")
machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?narHash=sha256-tbudgBSg+bHWHiHnlteNzN8TUvI80ygS9IULh4rklEw=")
machine.fail("nix flake metadata --json http://localhost/tags/latest.tar.gz?lastModified=1111111111")
'';
}