mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 03:56:01 +01:00
Merge pull request #14050 from NixOS/fix-fetch-to-store-caching
Fix fetchToStore caching
This commit is contained in:
commit
1e709554d5
21 changed files with 188 additions and 92 deletions
|
|
@ -236,24 +236,17 @@ EvalState::EvalState(
|
|||
{CanonPath(store->storeDir), store->getFSAccessor(settings.pureEval)},
|
||||
}))
|
||||
, rootFS([&] {
|
||||
auto accessor = [&]() -> decltype(rootFS) {
|
||||
/* In pure eval mode, we provide a filesystem that only
|
||||
contains the Nix store. */
|
||||
if (settings.pureEval)
|
||||
return storeFS;
|
||||
/* In pure eval mode, we provide a filesystem that only
|
||||
contains the Nix store.
|
||||
|
||||
/* If we have a chroot store and pure eval is not enabled,
|
||||
use a union accessor to make the chroot store available
|
||||
at its logical location while still having the underlying
|
||||
directory available. This is necessary for instance if
|
||||
we're evaluating a file from the physical /nix/store
|
||||
while using a chroot store. */
|
||||
auto realStoreDir = dirOf(store->toRealPath(StorePath::dummy));
|
||||
if (store->storeDir != realStoreDir)
|
||||
return makeUnionSourceAccessor({getFSSourceAccessor(), storeFS});
|
||||
|
||||
return getFSSourceAccessor();
|
||||
}();
|
||||
Otherwise, use a union accessor to make the augmented store
|
||||
available at its logical location while still having the
|
||||
underlying directory available. This is necessary for
|
||||
instance if we're evaluating a file from the physical
|
||||
/nix/store while using a chroot store, and also for lazy
|
||||
mounted fetchTree. */
|
||||
auto accessor = settings.pureEval ? storeFS.cast<SourceAccessor>()
|
||||
: makeUnionSourceAccessor({getFSSourceAccessor(), storeFS});
|
||||
|
||||
/* Apply access control if needed. */
|
||||
if (settings.restrictEval || settings.pureEval)
|
||||
|
|
@ -3133,6 +3126,11 @@ SourcePath EvalState::findFile(const LookupPath & lookupPath, const std::string_
|
|||
auto res = (r / CanonPath(suffix)).resolveSymlinks();
|
||||
if (res.pathExists())
|
||||
return res;
|
||||
|
||||
// Backward compatibility hack: throw an exception if access
|
||||
// to this path is not allowed.
|
||||
if (auto accessor = res.accessor.dynamic_pointer_cast<FilteringSourceAccessor>())
|
||||
accessor->checkAccess(res.path);
|
||||
}
|
||||
|
||||
if (hasPrefix(path, "nix/"))
|
||||
|
|
@ -3199,6 +3197,11 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
|
|||
if (path.resolveSymlinks().pathExists())
|
||||
return finish(std::move(path));
|
||||
else {
|
||||
// Backward compatibility hack: throw an exception if access
|
||||
// to this path is not allowed.
|
||||
if (auto accessor = path.accessor.dynamic_pointer_cast<FilteringSourceAccessor>())
|
||||
accessor->checkAccess(path.path);
|
||||
|
||||
logWarning({.msg = HintFmt("Nix search path entry '%1%' does not exist, ignoring", value)});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class Store;
|
|||
namespace fetchers {
|
||||
struct Settings;
|
||||
struct InputCache;
|
||||
struct Input;
|
||||
} // namespace fetchers
|
||||
struct EvalSettings;
|
||||
class EvalState;
|
||||
|
|
@ -575,6 +576,11 @@ public:
|
|||
|
||||
void checkURI(const std::string & uri);
|
||||
|
||||
/**
|
||||
* Mount an input on the Nix store.
|
||||
*/
|
||||
StorePath mountInput(fetchers::Input & input, const fetchers::Input & originalInput, ref<SourceAccessor> accessor);
|
||||
|
||||
/**
|
||||
* Parse a Nix expression from the specified file.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "nix/store/store-api.hh"
|
||||
#include "nix/expr/eval.hh"
|
||||
#include "nix/util/mounted-source-accessor.hh"
|
||||
#include "nix/fetchers/fetch-to-store.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
|
|
@ -18,4 +20,27 @@ SourcePath EvalState::storePath(const StorePath & path)
|
|||
return {rootFS, CanonPath{store->printStorePath(path)}};
|
||||
}
|
||||
|
||||
StorePath
|
||||
EvalState::mountInput(fetchers::Input & input, const fetchers::Input & originalInput, ref<SourceAccessor> accessor)
|
||||
{
|
||||
auto storePath = fetchToStore(fetchSettings, *store, accessor, FetchMode::Copy, input.getName());
|
||||
|
||||
allowPath(storePath); // FIXME: should just whitelist the entire virtual store
|
||||
|
||||
storeFS->mount(CanonPath(store->printStorePath(storePath)), accessor);
|
||||
|
||||
auto narHash = store->queryPathInfo(storePath)->narHash;
|
||||
input.attrs.insert_or_assign("narHash", narHash.to_string(HashFormat::SRI, true));
|
||||
|
||||
if (originalInput.getNarHash() && narHash != *originalInput.getNarHash())
|
||||
throw Error(
|
||||
(unsigned int) 102,
|
||||
"NAR hash mismatch in input '%s', expected '%s' but got '%s'",
|
||||
originalInput.to_string(),
|
||||
narHash.to_string(HashFormat::SRI, true),
|
||||
originalInput.getNarHash()->to_string(HashFormat::SRI, true));
|
||||
|
||||
return storePath;
|
||||
}
|
||||
|
||||
} // namespace nix
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include "nix/util/url.hh"
|
||||
#include "nix/expr/value-to-json.hh"
|
||||
#include "nix/fetchers/fetch-to-store.hh"
|
||||
#include "nix/fetchers/input-cache.hh"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
|
|
@ -218,11 +219,11 @@ static void fetchTree(
|
|||
throw Error("input '%s' is not allowed to use the '__final' attribute", input.to_string());
|
||||
}
|
||||
|
||||
auto [storePath, input2] = input.fetchToStore(state.store);
|
||||
auto cachedInput = state.inputCache->getAccessor(state.store, input, fetchers::UseRegistries::No);
|
||||
|
||||
state.allowPath(storePath);
|
||||
auto storePath = state.mountInput(cachedInput.lockedInput, input, cachedInput.accessor);
|
||||
|
||||
emitTreeAttrs(state, storePath, input2, v, params.emptyRevFallback, false);
|
||||
emitTreeAttrs(state, storePath, cachedInput.lockedInput, v, params.emptyRevFallback, false);
|
||||
}
|
||||
|
||||
static void prim_fetchTree(EvalState & state, const PosIdx pos, Value ** args, Value & v)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue