From a218dd80d6907246dc56b248f6941d29743c304c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 16 Aug 2022 16:05:43 +0200 Subject: [PATCH] Support locking path inputs --- src/libfetchers/fetchers.cc | 5 ----- src/libfetchers/path.cc | 38 +++++++++++++++++++++++++++++++++--- tests/flakes/flakes.sh | 11 +++++------ tests/flakes/follow-paths.sh | 10 +++------- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc index 9347da86e..33a36338c 100644 --- a/src/libfetchers/fetchers.cc +++ b/src/libfetchers/fetchers.cc @@ -134,11 +134,6 @@ std::pair Input::fetchToStore(ref store) const void Input::checkLocks(Input & input) const { - #if 0 - auto narHash = store.queryPathInfo(storePath)->narHash; - input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true)); - #endif - if (auto prevNarHash = getNarHash()) { if (input.getNarHash() != prevNarHash) throw Error((unsigned int) 102, "NAR hash mismatch in input '%s', expected '%s'", diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc index 3cb4dad02..72596841f 100644 --- a/src/libfetchers/path.cc +++ b/src/libfetchers/path.cc @@ -27,6 +27,8 @@ struct PathInputScheme : InputScheme else throw Error("path URL '%s' has invalid parameter '%s'", url.to_string(), name); } + else if (name == "lock") + input.attrs.emplace(name, Explicit { value == "1" }); else throw Error("path URL '%s' has unsupported parameter '%s'", url.to_string(), name); @@ -38,6 +40,7 @@ struct PathInputScheme : InputScheme if (maybeGetStrAttr(attrs, "type") != "path") return {}; getStrAttr(attrs, "path"); + maybeGetBoolAttr(attrs, "lock"); for (auto & [name, value] : attrs) /* Allow the user to pass in "fake" tree info @@ -47,8 +50,8 @@ struct PathInputScheme : InputScheme FIXME: remove this hack once we have a prepopulated flake input cache mechanism. */ - if (name == "type" || name == "rev" || name == "revCount" || name == "lastModified" || name == "narHash" || name == "path") - // checked in Input::fromAttrs + if (name == "type" || name == "rev" || name == "revCount" || name == "lastModified" || name == "narHash" || name == "path" || name == "lock") + // checked elsewhere ; else throw Error("unsupported path input attribute '%s'", name); @@ -58,6 +61,11 @@ struct PathInputScheme : InputScheme return input; } + bool getLockAttr(const Input & input) const + { + return maybeGetBoolAttr(input.attrs, "lock").value_or(false); + } + ParsedURL toURL(const Input & input) const override { auto query = attrsToQuery(input.attrs); @@ -112,7 +120,31 @@ struct PathInputScheme : InputScheme auto absPath = getAbsPath(input); auto input2(input); input2.attrs.emplace("path", (std::string) absPath.abs()); - return {makeFSInputAccessor(absPath), std::move(input2)}; + + if (getLockAttr(input2)) { + + auto storePath = store->maybeParseStorePath(absPath.abs()); + + if (!storePath || storePath->name() != input.getName() || !store->isValidPath(*storePath)) { + Activity act(*logger, lvlChatty, actUnknown, fmt("copying '%s' to the store", absPath)); + storePath = store->addToStore(input.getName(), absPath.abs()); + auto narHash = store->queryPathInfo(*storePath)->narHash; + input2.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true)); + } else + input2.attrs.erase("narHash"); + + input2.attrs.erase("lastModified"); + + auto makeNotAllowedError = [absPath](const CanonPath & path) -> RestrictedPathError + { + return RestrictedPathError("path '%s' does not exist'", absPath + path); + }; + + return {makeStorePathAccessor(store, *storePath, std::move(makeNotAllowedError)), std::move(input2)}; + + } else { + return {makeFSInputAccessor(absPath), std::move(input2)}; + } } std::optional getFingerprint(ref store, const Input & input) const override diff --git a/tests/flakes/flakes.sh b/tests/flakes/flakes.sh index 8cdb26231..f998dab19 100644 --- a/tests/flakes/flakes.sh +++ b/tests/flakes/flakes.sh @@ -221,11 +221,10 @@ cat > $flake3Dir/flake.nix < $flake3Dir/flake.nix < \$out + [[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]] ''; - # [[ \$(cat \${inputs.nonFlake}/README.md) = \$(cat \${inputs.nonFlakeFile}) ]] # [[ \${inputs.nonFlakeFile} = \${inputs.nonFlakeFile2} ]] }; }; diff --git a/tests/flakes/follow-paths.sh b/tests/flakes/follow-paths.sh index 6b0cb6cba..737ba30a4 100644 --- a/tests/flakes/follow-paths.sh +++ b/tests/flakes/follow-paths.sh @@ -27,9 +27,7 @@ cat > $flakeFollowsA/flake.nix < $flakeFollowsB/flake.nix < $flakeFollowsC/flake.nix <