diff --git a/lix/nix/ls.cc b/lix/nix/ls.cc index 01f5d7932..79adf8818 100644 --- a/lix/nix/ls.cc +++ b/lix/nix/ls.cc @@ -137,13 +137,21 @@ struct CmdLsStore : StoreCommand, MixLs ); JSON j = json::parse(std::move(file), "a nar content listing"); if (j["version"] == 1) { - path = restPath; accessor = makeLazyNarAccessor(j["root"].dump(), [](uint64_t, uint64_t) -> std::string { throw Error("attempted to read NAR content during listing"); }); + path = restPath; } } - } catch (NoSuchBinaryCacheFile &) { } + } catch (NoSuchBinaryCacheFile &) { + } catch (Error & e) { + warn( + "nar listing for %s on %s is bad (falling back to full nar download): %s", + path, + store->getUri(), + e.what() + ); + } list(accessor); } diff --git a/tests/functional/nar-access.sh b/tests/functional/nar-access.sh index 8365a4fd2..5bcdf8ed3 100644 --- a/tests/functional/nar-access.sh +++ b/tests/functional/nar-access.sh @@ -82,11 +82,21 @@ diff -u \ <(echo '{"narOffset": 368,"type":"regular","size":0}' | jq -S) -# Confirm that we are reading from ".ls" file by deleting the nar -rm -rf $cacheDir/nar +# Confirm that we are reading from ".ls" file by moving the nar +mv $cacheDir/nar $cacheDir/nar.gone diff -u \ <(nix store ls --json -R $storePath/foo/bar --store "file://$cacheDir" | jq -S) \ <(echo '{"narOffset": 368,"type":"regular","size":0}' | jq -S) +mv $cacheDir/nar.gone $cacheDir/nar + +# confirm that we read the nar if the listing is missing offsets +narls=$(echo "$cacheDir/"*.ls) +cp "$narls" "$narls.old" +jq 'walk(if type == "object" then del(.narOffset) else . end)' < "$narls.old" >"$narls" +diff -u \ + <(nix store ls --json $storePath/foo/bar --store "file://$cacheDir" | jq -S) \ + <(echo '{"narOffset": 368,"type":"regular","size":0}' | jq -S) +mv "$narls.old" "$narls" if canWriteNonUtf8Inodes; then # Confirm that there's no more than one `.ls` in the `$cacheDir` because non-UTF8 inodes cannot have `.ls` generated for them.