diff options
-rw-r--r-- | doc/manual/change-authors.yml | 5 | ||||
-rw-r--r-- | doc/manual/rl-next/fod-failure-includes-url.md | 16 | ||||
-rw-r--r-- | doc/manual/rl-next/registry-add-shorthand-only.md | 10 | ||||
-rw-r--r-- | doc/manual/src/contributing/testing.md | 3 | ||||
-rw-r--r-- | meson.build | 1 | ||||
-rw-r--r-- | src/libexpr/flake/flakeref.cc | 6 | ||||
-rw-r--r-- | src/libstore/build/local-derivation-goal.cc | 5 | ||||
-rw-r--r-- | src/libstore/gc.cc | 28 | ||||
-rw-r--r-- | src/libutil/url-parts.hh | 3 | ||||
-rw-r--r-- | src/libutil/url.cc | 1 | ||||
-rw-r--r-- | src/nix/registry-add.md | 5 | ||||
-rw-r--r-- | src/nix/registry.cc | 8 | ||||
-rw-r--r-- | tests/functional/build.sh | 5 | ||||
-rw-r--r-- | tests/functional/flakes/flakes.sh | 11 | ||||
-rw-r--r-- | tests/functional/fod-failing.nix | 2 |
15 files changed, 85 insertions, 24 deletions
diff --git a/doc/manual/change-authors.yml b/doc/manual/change-authors.yml index 5894ce821..28a20b25f 100644 --- a/doc/manual/change-authors.yml +++ b/doc/manual/change-authors.yml @@ -44,6 +44,11 @@ cole-h: display_name: Cole Helbling github: cole-h +delan: + display_name: delan + forgejo: delan + github: delan + edolstra: display_name: Eelco Dolstra github: edolstra diff --git a/doc/manual/rl-next/fod-failure-includes-url.md b/doc/manual/rl-next/fod-failure-includes-url.md new file mode 100644 index 000000000..43179aa52 --- /dev/null +++ b/doc/manual/rl-next/fod-failure-includes-url.md @@ -0,0 +1,16 @@ +--- +synopsis: "Hash mismatch diagnostics for fixed-output derivations include the URL" +cls: [1536] +credits: [jade] +category: Improvements +--- + +Now, when building fixed-output derivations, Lix will guess the URL that was used in the derivation using the `url` or `urls` properties in the derivation environment. +This is a layering violation but making these diagnostics tractable when there are multiple instances of the `AAAA` hash is too significant of an improvement to pass it up. + +``` +error: hash mismatch in fixed-output derivation '/nix/store/sjfw324j4533lwnpmr5z4icpb85r63ai-x1.drv': + likely URL: https://meow.puppy.forge/puppy.tar.gz + specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + got: sha256-a1Qvp3FOOkWpL9kFHgugU1ok5UtRPSu+NwCZKbbaEro= +``` diff --git a/doc/manual/rl-next/registry-add-shorthand-only.md b/doc/manual/rl-next/registry-add-shorthand-only.md new file mode 100644 index 000000000..72f972b0a --- /dev/null +++ b/doc/manual/rl-next/registry-add-shorthand-only.md @@ -0,0 +1,10 @@ +--- +synopsis: "`nix registry add` now requires a shorthand flakeref on the 'from' side" +cls: 1494 +credits: delan +category: Improvements +--- + +The 'from' argument must now be a shorthand flakeref like `nixpkgs` or `nixpkgs/nixos-20.03`, making it harder to accidentally swap the 'from' and 'to' arguments. + +Registry entries that map from other flake URLs can still be specified in registry.json, the `nix.registry` option in NixOS, or the `--override-flake` option in the CLI, but they are not guaranteed to work correctly. diff --git a/doc/manual/src/contributing/testing.md b/doc/manual/src/contributing/testing.md index 84836b891..b6b5318e0 100644 --- a/doc/manual/src/contributing/testing.md +++ b/doc/manual/src/contributing/testing.md @@ -433,9 +433,6 @@ I grepped `src/` for `get[eE]nv\("` to find the mentions in Lix code. - `NIX_PROFILE` - Selects which profile `nix-env` will operate on. Documented elsewhere. - `NIX_SSHOPTS` - Options passed to `ssh(1)` when using a ssh remote store. Incorrectly documented on `nix-copy-closure` which is *surely* not the only place they are used?? -- `_NIX_TEST_NO_LSOF` - Used on non-Linux, non-macOS platforms to disable using `lsof` when finding gc roots. - - Since https://git.lix.systems/lix-project/lix/issues/156 was fixed, this should probably just be removed as it was a bad workaround for a macOS issue. - `_NIX_TEST_GC_SYNC_1` - Path to a pipe that is used to block the GC briefly to validate invariants from the test suite. - `_NIX_TEST_GC_SYNC_2` - Path to a pipe that is used to block the GC briefly to validate invariants from the test suite. - `_NIX_TEST_FREE_SPACE_FILE` - Path to a file containing a decimal number with the free space that the GC is to believe it has. diff --git a/meson.build b/meson.build index 0cb2030e7..7d8a3a315 100644 --- a/meson.build +++ b/meson.build @@ -432,6 +432,7 @@ add_project_arguments( '-Wimplicit-fallthrough', '-Werror=switch', '-Werror=switch-enum', + '-Werror=unused-result', '-Wdeprecated-copy', '-Wignored-qualifiers', # Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index 1c90bfc43..a95df04ba 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -85,8 +85,8 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment( + "(?:#(" + queryRegex + "))?", std::regex::ECMAScript); - static std::regex flakeRegex( - "((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)" + static std::regex flakeShorthandRegex( + flakeShorthandRegexS + "(?:#(" + queryRegex + "))?", std::regex::ECMAScript); @@ -95,7 +95,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment( /* Check if 'url' is a flake ID. This is an abbreviated syntax for 'flake:<flake-id>?ref=<ref>&rev=<rev>'. */ - if (std::regex_match(url, match, flakeRegex)) { + if (std::regex_match(url, match, flakeShorthandRegex)) { auto parsedURL = ParsedURL{ .url = url, .base = "flake:" + match.str(1), diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index 968f669ec..1dd2ad8aa 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -2546,9 +2546,12 @@ SingleDrvOutputs LocalDerivationGoal::registerOutputs() /* Throw an error after registering the path as valid. */ worker.hashMismatch = true; + // XXX: shameless layering violation hack that makes the hash mismatch error at least not utterly worthless + auto guessedUrl = getOr(drv->env, "urls", getOr(drv->env, "url", "(unknown)")); delayedException = std::make_exception_ptr( - BuildError("hash mismatch in fixed-output derivation '%s':\n specified: %s\n got: %s", + BuildError("hash mismatch in fixed-output derivation '%s':\n likely URL: %s\n specified: %s\n got: %s", worker.store.printStorePath(drvPath), + guessedUrl, wanted.to_string(SRI, true), got.to_string(SRI, true))); } diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index d58e3c8eb..02234d404 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -321,22 +321,20 @@ Roots LocalStore::findRoots(bool censor) void LocalStore::findPlatformRoots(UncheckedRoots & unchecked) { - // lsof is really slow on OS X. This actually causes the gc-concurrent.sh test to fail. - // See: https://github.com/NixOS/nix/issues/3011 - // Because of this we disable lsof when running the tests. - if (getEnv("_NIX_TEST_NO_LSOF") != "1") { - try { - std::regex lsofRegex(R"(^n(/.*)$)"); - auto lsofLines = - tokenizeString<std::vector<std::string>>(runProgram(LSOF, true, { "-n", "-w", "-F", "n" }), "\n"); - for (const auto & line : lsofLines) { - std::smatch match; - if (std::regex_match(line, match, lsofRegex)) - unchecked[match[1]].emplace("{lsof}"); - } - } catch (ExecError & e) { - /* lsof not installed, lsof failed */ + // N.B. This is (read: undertested!) fallback code only used for + // non-Darwin, non-Linux platforms. Both major platforms have + // platform-specific code in src/libstore/platform/ + try { + std::regex lsofRegex(R"(^n(/.*)$)"); + auto lsofLines = + tokenizeString<std::vector<std::string>>(runProgram(LSOF, true, { "-n", "-w", "-F", "n" }), "\n"); + for (const auto & line : lsofLines) { + std::smatch match; + if (std::regex_match(line, match, lsofRegex)) + unchecked[match[1]].emplace("{lsof}"); } + } catch (ExecError & e) { + /* lsof not installed, lsof failed */ } } diff --git a/src/libutil/url-parts.hh b/src/libutil/url-parts.hh index 6efcc7e50..1f570567c 100644 --- a/src/libutil/url-parts.hh +++ b/src/libutil/url-parts.hh @@ -46,4 +46,7 @@ const static std::string refAndOrRevRegex = "(?:(" + revRegexS + ")|(?:(" + refR const static std::string flakeIdRegexS = "[a-zA-Z][a-zA-Z0-9_-]*"; extern std::regex flakeIdRegex; +const static std::string flakeShorthandRegexS = "((" + flakeIdRegexS + ")(?:/(?:" + refAndOrRevRegex + "))?)"; +extern std::regex flakeShorthandRegex; + } diff --git a/src/libutil/url.cc b/src/libutil/url.cc index 46688cef5..87146ca56 100644 --- a/src/libutil/url.cc +++ b/src/libutil/url.cc @@ -9,6 +9,7 @@ std::regex refRegex(refRegexS, std::regex::ECMAScript); std::regex badGitRefRegex(badGitRefRegexS, std::regex::ECMAScript); std::regex revRegex(revRegexS, std::regex::ECMAScript); std::regex flakeIdRegex(flakeIdRegexS, std::regex::ECMAScript); +std::regex flakeShorthandRegex(flakeShorthandRegexS, std::regex::ECMAScript); ParsedURL parseURL(const std::string & url) { diff --git a/src/nix/registry-add.md b/src/nix/registry-add.md index a947fa0b3..90b54a596 100644 --- a/src/nix/registry-add.md +++ b/src/nix/registry-add.md @@ -31,8 +31,9 @@ R""( # Description This command adds an entry to the user registry that maps flake -reference *from-url* to flake reference *to-url*. If an entry for -*from-url* already exists, it is overwritten. +reference *from-url* to flake reference *to-url*, where *from-url* +must be a shorthand like 'nixpkgs' or 'nixpkgs/nixos-20.03'. If an +entry for *from-url* already exists, it is overwritten. Entries can be removed using [`nix registry remove`](./nix3-registry-remove.md). diff --git a/src/nix/registry.cc b/src/nix/registry.cc index f509ccae8..9619b85d4 100644 --- a/src/nix/registry.cc +++ b/src/nix/registry.cc @@ -5,6 +5,7 @@ #include "flake/flake.hh" #include "store-api.hh" #include "fetchers.hh" +#include "url-parts.hh" #include "registry.hh" using namespace nix; @@ -109,7 +110,14 @@ struct CmdRegistryAdd : MixEvalArgs, Command, RegistryCommand void run() override { + std::smatch match; + if (!std::regex_match(fromUrl, match, flakeShorthandRegex)) { + throw UsageError("'from-url' argument must be a shorthand like 'nixpkgs' or 'nixpkgs/nixos-20.03'"); + } auto fromRef = parseFlakeRef(fromUrl); + if (fromRef.input.direct) { + throw UsageError("'from-url' argument must be an indirect flakeref like 'nixpkgs' or 'flake:nixpkgs'"); + } auto toRef = parseFlakeRef(toUrl); auto registry = getRegistry(); fetchers::Attrs extraAttrs; diff --git a/tests/functional/build.sh b/tests/functional/build.sh index 95a20dc6a..a540cf8fd 100644 --- a/tests/functional/build.sh +++ b/tests/functional/build.sh @@ -142,6 +142,8 @@ test "$(<<<"$out" grep -E '^error:' | wc -l)" = 2 <<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x1\\.drv'" <<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x3\\.drv'" <<<"$out" grepQuiet -vE "hash mismatch in fixed-output derivation '.*-x2\\.drv'" +<<<"$out" grepQuiet -E "likely URL: https://meow.puppy.forge/puppy.tar.gz" +<<<"$out" grepQuiet -vE "likely URL: https://kitty.forge/cat.tar.gz" <<<"$out" grepQuiet -E "error: build of '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out', '.*-x[1-4]\\.drv\\^out' failed" out="$(nix build -f fod-failing.nix -L x1 x2 x3 --keep-going 2>&1)" && status=0 || status=$? @@ -151,6 +153,9 @@ test "$(<<<"$out" grep -E '^error:' | wc -l)" = 4 <<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x1\\.drv'" <<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x3\\.drv'" <<<"$out" grepQuiet -E "hash mismatch in fixed-output derivation '.*-x2\\.drv'" +<<<"$out" grepQuiet -E "likely URL: https://meow.puppy.forge/puppy.tar.gz" +<<<"$out" grepQuiet -E "likely URL: https://kitty.forge/cat.tar.gz" +<<<"$out" grepQuiet -E "likely URL: \(unknown\)" <<<"$out" grepQuiet -E "error: build of '.*-x[1-3]\\.drv\\^out', '.*-x[1-3]\\.drv\\^out', '.*-x[1-3]\\.drv\\^out' failed" out="$(nix build -f fod-failing.nix -L x4 2>&1)" && status=0 || status=$? diff --git a/tests/functional/flakes/flakes.sh b/tests/functional/flakes/flakes.sh index 68a2fd2ce..97dc6d818 100644 --- a/tests/functional/flakes/flakes.sh +++ b/tests/functional/flakes/flakes.sh @@ -366,6 +366,17 @@ nix registry pin flake1 flake3 nix registry remove flake1 [[ $(nix registry list | wc -l) == 5 ]] +# 'nix registry add' should accept flake shorthands (with or without branch or rev) +# in the from argument, but reject fully-qualified from-urls (direct or indirect). +nix registry add nixpkgz github:NixOS/nixpkgz +nix registry remove nixpkgz +nix registry add nixpkgz/branch github:NixOS/nixpkgz +nix registry remove nixpkgz/branch +nix registry add nixpkgz/branch/1db42b7fe3878f3f5f7a4f2dc210772fd080e205 github:NixOS/nixpkgz +nix registry remove nixpkgz/branch/1db42b7fe3878f3f5f7a4f2dc210772fd080e205 +! nix registry add flake:nixpkgz github:NixOS/nixpkgz +! nix registry add github:NixOS/nixpkgz github:NixOS/nixpkgz + # Test 'nix registry list' with a disabled global registry. nix registry add user-flake1 git+file://$flake1Dir nix registry add user-flake2 git+file://$flake2Dir diff --git a/tests/functional/fod-failing.nix b/tests/functional/fod-failing.nix index 37c04fe12..b63fbd900 100644 --- a/tests/functional/fod-failing.nix +++ b/tests/functional/fod-failing.nix @@ -6,6 +6,7 @@ rec { '' echo $name > $out ''; + url = "https://meow.puppy.forge/puppy.tar.gz"; outputHashMode = "recursive"; outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }; @@ -15,6 +16,7 @@ rec { '' echo $name > $out ''; + urls = "https://kitty.forge/cat.tar.gz"; outputHashMode = "recursive"; outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }; |