Merge pull request #10043 from edolstra/fix-readonly-fetchToStore

fetchToStore(): Don't always respect settings.readOnlyMode
This commit is contained in:
Théophane Hufschmitt 2024-02-20 12:07:48 +01:00 committed by GitHub
commit 6f4bb1b584
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 30 additions and 8 deletions

View file

@ -45,7 +45,7 @@ ref<InstallableValue> InstallableValue::require(ref<Installable> installable)
std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx) std::optional<DerivedPathWithInfo> InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::string_view errorCtx)
{ {
if (v.type() == nPath) { if (v.type() == nPath) {
auto storePath = fetchToStore(*state->store, v.path()); auto storePath = fetchToStore(*state->store, v.path(), FetchMode::Copy);
return {{ return {{
.path = DerivedPath::Opaque { .path = DerivedPath::Opaque {
.path = std::move(storePath), .path = std::move(storePath),

View file

@ -2339,7 +2339,14 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
auto dstPath = i != srcToStore.end() auto dstPath = i != srcToStore.end()
? i->second ? i->second
: [&]() { : [&]() {
auto dstPath = fetchToStore(*store, path.resolveSymlinks(), path.baseName(), FileIngestionMethod::Recursive, nullptr, repair); auto dstPath = fetchToStore(
*store,
path.resolveSymlinks(),
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
path.baseName(),
FileIngestionMethod::Recursive,
nullptr,
repair);
allowPath(dstPath); allowPath(dstPath);
srcToStore.insert_or_assign(path, dstPath); srcToStore.insert_or_assign(path, dstPath);
printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, store->printStorePath(dstPath)); printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, store->printStorePath(dstPath));

View file

@ -2231,7 +2231,14 @@ static void addPath(
}); });
if (!expectedHash || !state.store->isValidPath(*expectedStorePath)) { if (!expectedHash || !state.store->isValidPath(*expectedStorePath)) {
auto dstPath = fetchToStore(*state.store, path.resolveSymlinks(), name, method, filter.get(), state.repair); auto dstPath = fetchToStore(
*state.store,
path.resolveSymlinks(),
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
name,
method,
filter.get(),
state.repair);
if (expectedHash && expectedStorePath != dstPath) if (expectedHash && expectedStorePath != dstPath)
state.error<EvalError>( state.error<EvalError>(
"store path mismatch in (possibly filtered) path added from '%s'", "store path mismatch in (possibly filtered) path added from '%s'",

View file

@ -7,6 +7,7 @@ namespace nix {
StorePath fetchToStore( StorePath fetchToStore(
Store & store, Store & store,
const SourcePath & path, const SourcePath & path,
FetchMode mode,
std::string_view name, std::string_view name,
ContentAddressMethod method, ContentAddressMethod method,
PathFilter * filter, PathFilter * filter,
@ -33,18 +34,19 @@ StorePath fetchToStore(
} else } else
debug("source path '%s' is uncacheable", path); debug("source path '%s' is uncacheable", path);
Activity act(*logger, lvlChatty, actUnknown, fmt("copying '%s' to the store", path)); Activity act(*logger, lvlChatty, actUnknown,
fmt(mode == FetchMode::DryRun ? "hashing '%s'" : "copying '%s' to the store", path));
auto filter2 = filter ? *filter : defaultPathFilter; auto filter2 = filter ? *filter : defaultPathFilter;
auto storePath = auto storePath =
settings.readOnlyMode mode == FetchMode::DryRun
? store.computeStorePath( ? store.computeStorePath(
name, *path.accessor, path.path, method, HashAlgorithm::SHA256, {}, filter2).first name, *path.accessor, path.path, method, HashAlgorithm::SHA256, {}, filter2).first
: store.addToStore( : store.addToStore(
name, *path.accessor, path.path, method, HashAlgorithm::SHA256, {}, filter2, repair); name, *path.accessor, path.path, method, HashAlgorithm::SHA256, {}, filter2, repair);
if (cacheKey) if (cacheKey && mode == FetchMode::Copy)
fetchers::getCache()->add(store, *cacheKey, {}, storePath, true); fetchers::getCache()->add(store, *cacheKey, {}, storePath, true);
return storePath; return storePath;

View file

@ -8,12 +8,15 @@
namespace nix { namespace nix {
enum struct FetchMode { DryRun, Copy };
/** /**
* Copy the `path` to the Nix store. * Copy the `path` to the Nix store.
*/ */
StorePath fetchToStore( StorePath fetchToStore(
Store & store, Store & store,
const SourcePath & path, const SourcePath & path,
FetchMode mode,
std::string_view name = "source", std::string_view name = "source",
ContentAddressMethod method = FileIngestionMethod::Recursive, ContentAddressMethod method = FileIngestionMethod::Recursive,
PathFilter * filter = nullptr, PathFilter * filter = nullptr,

View file

@ -376,7 +376,7 @@ void InputScheme::clone(const Input & input, const Path & destDir) const
std::pair<StorePath, Input> InputScheme::fetch(ref<Store> store, const Input & input) std::pair<StorePath, Input> InputScheme::fetch(ref<Store> store, const Input & input)
{ {
auto [accessor, input2] = getAccessor(store, input); auto [accessor, input2] = getAccessor(store, input);
auto storePath = fetchToStore(*store, SourcePath(accessor), input2.getName()); auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy, input2.getName());
return {storePath, input2}; return {storePath, input2};
} }

View file

@ -30,7 +30,10 @@ echo hello >> $TEST_ROOT/worktree/hello
rev2=$(git -C $repo rev-parse HEAD) rev2=$(git -C $repo rev-parse HEAD)
git -C $repo tag -a tag2 -m tag2 git -C $repo tag -a tag2 -m tag2
# Fetch a worktree # Check whether fetching in read-only mode works.
nix-instantiate --eval -E "builtins.readFile ((builtins.fetchGit file://$TEST_ROOT/worktree) + \"/hello\") == \"utrecht\\n\""
# Fetch a worktree.
unset _NIX_FORCE_HTTP unset _NIX_FORCE_HTTP
path0=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath") path0=$(nix eval --impure --raw --expr "(builtins.fetchGit file://$TEST_ROOT/worktree).outPath")
path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = file://$TEST_ROOT/worktree; }).outPath") path0_=$(nix eval --impure --raw --expr "(builtins.fetchTree { type = \"git\"; url = file://$TEST_ROOT/worktree; }).outPath")