1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-30 06:01:00 +01:00

Support locking path inputs

This commit is contained in:
Eelco Dolstra 2022-08-16 16:05:43 +02:00
parent 4adb32f7d5
commit a218dd80d6
4 changed files with 43 additions and 21 deletions

View file

@ -134,11 +134,6 @@ std::pair<StorePath, Input> Input::fetchToStore(ref<Store> 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'",

View file

@ -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<bool> { 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<std::string> getFingerprint(ref<Store> store, const Input & input) const override