mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
Use UnionSourceAccessor to mount the chroot store on top of the real store directory
This commit is contained in:
parent
5b7c240ebd
commit
99e78c37f7
6 changed files with 42 additions and 49 deletions
|
@ -37,7 +37,7 @@ EvalSettings evalSettings {
|
|||
auto [accessor, lockedRef] = flakeRef.resolve(state.store).lazyFetch(state.store);
|
||||
auto storePath = nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
||||
state.allowPath(storePath);
|
||||
return state.rootPath(state.store->toRealPath(storePath));
|
||||
return state.rootPath(state.store->printStorePath(storePath));
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -179,7 +179,7 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * bas
|
|||
state.fetchSettings,
|
||||
EvalSettings::resolvePseudoUrl(s));
|
||||
auto storePath = fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy);
|
||||
return state.rootPath(CanonPath(state.store->toRealPath(storePath)));
|
||||
return state.rootPath(CanonPath(state.store->printStorePath(storePath)));
|
||||
}
|
||||
|
||||
else if (hasPrefix(s, "flake:")) {
|
||||
|
@ -188,7 +188,7 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const Path * bas
|
|||
auto [accessor, lockedRef] = flakeRef.resolve(state.store).lazyFetch(state.store);
|
||||
auto storePath = nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
||||
state.allowPath(storePath);
|
||||
return state.rootPath(CanonPath(state.store->toRealPath(storePath)));
|
||||
return state.rootPath(CanonPath(state.store->printStorePath(storePath)));
|
||||
}
|
||||
|
||||
else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
|
||||
|
|
|
@ -246,21 +246,37 @@ EvalState::EvalState(
|
|||
, repair(NoRepair)
|
||||
, emptyBindings(0)
|
||||
, rootFS(
|
||||
settings.restrictEval || settings.pureEval
|
||||
? ref<SourceAccessor>(AllowListSourceAccessor::create(getFSSourceAccessor(), {},
|
||||
[&settings](const CanonPath & path) -> RestrictedPathError {
|
||||
auto modeInformation = settings.pureEval
|
||||
? "in pure evaluation mode (use '--impure' to override)"
|
||||
: "in restricted mode";
|
||||
throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation);
|
||||
}))
|
||||
: getFSSourceAccessor())
|
||||
, storeFS(
|
||||
makeMountedSourceAccessor(
|
||||
{
|
||||
{CanonPath::root, makeEmptySourceAccessor()},
|
||||
{CanonPath(store->storeDir), makeFSSourceAccessor(dirOf(store->toRealPath(StorePath::dummy)))}
|
||||
}))
|
||||
({
|
||||
auto accessor = getFSSourceAccessor();
|
||||
|
||||
/* If we have a chroot store, make 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) {
|
||||
auto storeFS = makeMountedSourceAccessor(
|
||||
{
|
||||
{CanonPath::root, makeEmptySourceAccessor()},
|
||||
{CanonPath(store->storeDir), makeFSSourceAccessor(realStoreDir)}
|
||||
});
|
||||
accessor = makeUnionSourceAccessor({accessor, storeFS});
|
||||
}
|
||||
|
||||
/* Apply access control if needed. */
|
||||
if (settings.restrictEval || settings.pureEval)
|
||||
accessor = AllowListSourceAccessor::create(accessor, {},
|
||||
[&settings](const CanonPath & path) -> RestrictedPathError {
|
||||
auto modeInformation = settings.pureEval
|
||||
? "in pure evaluation mode (use '--impure' to override)"
|
||||
: "in restricted mode";
|
||||
throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation);
|
||||
});
|
||||
|
||||
accessor;
|
||||
}))
|
||||
, corepkgsFS(make_ref<MemorySourceAccessor>())
|
||||
, internalFS(make_ref<MemorySourceAccessor>())
|
||||
, derivationInternal{corepkgsFS->addFile(
|
||||
|
@ -350,7 +366,7 @@ void EvalState::allowPath(const Path & path)
|
|||
void EvalState::allowPath(const StorePath & storePath)
|
||||
{
|
||||
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
|
||||
rootFS2->allowPrefix(CanonPath(store->toRealPath(storePath)));
|
||||
rootFS2->allowPrefix(CanonPath(store->printStorePath(storePath)));
|
||||
}
|
||||
|
||||
void EvalState::allowClosure(const StorePath & storePath)
|
||||
|
@ -2428,7 +2444,7 @@ SourcePath EvalState::coerceToPath(const PosIdx pos, Value & v, NixStringContext
|
|||
auto path = coerceToString(pos, v, context, errorCtx, false, false, true).toOwned();
|
||||
if (path == "" || path[0] != '/')
|
||||
error<EvalError>("string '%1%' doesn't represent an absolute path", path).withTrace(pos, errorCtx).debugThrow();
|
||||
return stringWithContextToPath(path, context);
|
||||
return rootPath(path);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3082,7 +3098,7 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
|
|||
fetchSettings,
|
||||
EvalSettings::resolvePseudoUrl(value));
|
||||
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
|
||||
return finish(rootPath(store->toRealPath(storePath)));
|
||||
return finish(rootPath(store->printStorePath(storePath)));
|
||||
} catch (Error & e) {
|
||||
logWarning({
|
||||
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
||||
|
|
|
@ -250,11 +250,6 @@ public:
|
|||
*/
|
||||
const ref<SourceAccessor> rootFS;
|
||||
|
||||
/**
|
||||
* The accessor for the store.
|
||||
*/
|
||||
const ref<SourceAccessor> storeFS;
|
||||
|
||||
/**
|
||||
* The in-memory filesystem for <nix/...> paths.
|
||||
*/
|
||||
|
@ -394,18 +389,6 @@ public:
|
|||
*/
|
||||
SourcePath rootPath(PathView path);
|
||||
|
||||
/**
|
||||
* Convert `s` to a path. If `context` is not empty, the resulting
|
||||
* path will use the `storeFS` accessor; otherwise it will use
|
||||
* `rootFS`. When using a chroot store, this allows us to
|
||||
* distinguish between store paths resulting from
|
||||
* import-from-derivation and sources stored in the actual
|
||||
* /nix/store.
|
||||
*/
|
||||
SourcePath stringWithContextToPath(
|
||||
std::string_view s,
|
||||
const NixStringContext & context);
|
||||
|
||||
/**
|
||||
* Allow access to a path.
|
||||
*/
|
||||
|
|
|
@ -13,10 +13,4 @@ SourcePath EvalState::rootPath(PathView path)
|
|||
return {rootFS, CanonPath(absPath(path))};
|
||||
}
|
||||
|
||||
SourcePath EvalState::stringWithContextToPath(std::string_view s, const NixStringContext & context)
|
||||
{
|
||||
auto path = CanonPath(s);
|
||||
return !context.empty() ? SourcePath{storeFS, std::move(path)} : rootPath(std::move(path));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ static SourcePath realisePath(EvalState & state, const PosIdx pos, Value & v, st
|
|||
auto path = state.coerceToPath(noPos, v, context, "while realising the context of a path");
|
||||
|
||||
try {
|
||||
if (!context.empty() && path.accessor == state.storeFS) {
|
||||
if (!context.empty() && path.accessor == state.rootFS) {
|
||||
auto rewrites = state.realiseContext(context);
|
||||
path = {path.accessor, CanonPath(rewriteStrings(path.path.abs(), rewrites))};
|
||||
}
|
||||
|
@ -2480,7 +2480,7 @@ static void addPath(
|
|||
try {
|
||||
StorePathSet refs;
|
||||
|
||||
if (path.accessor == state.storeFS && state.store->isInStore(path.path.abs())) {
|
||||
if (path.accessor == state.rootFS && state.store->isInStore(path.path.abs())) {
|
||||
// FIXME: handle CA derivation outputs (where path needs to
|
||||
// be rewritten to the actual output).
|
||||
auto rewrites = state.realiseContext(context);
|
||||
|
|
|
@ -337,7 +337,7 @@ static Flake readFlake(
|
|||
auto storePath = fetchToStore(*state.store, setting.value->path(), FetchMode::Copy);
|
||||
flake.config.settings.emplace(
|
||||
state.symbols[setting.name],
|
||||
state.store->toRealPath(storePath));
|
||||
state.store->printStorePath(storePath));
|
||||
}
|
||||
else if (setting.value->type() == nInt)
|
||||
flake.config.settings.emplace(
|
||||
|
@ -423,7 +423,7 @@ static Flake getFlake(
|
|||
auto storePath = copyInputToStore(state, lockedRef.input, originalRef.input, accessor);
|
||||
|
||||
// Re-parse flake.nix from the store.
|
||||
return readFlake(state, originalRef, resolvedRef, lockedRef, state.rootPath(state.store->toRealPath(storePath)), lockRootAttrPath);
|
||||
return readFlake(state, originalRef, resolvedRef, lockedRef, state.rootPath(state.store->printStorePath(storePath)), lockRootAttrPath);
|
||||
}
|
||||
|
||||
Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries)
|
||||
|
@ -784,7 +784,7 @@ LockedFlake lockFlake(
|
|||
// FIXME: allow input to be lazy.
|
||||
auto storePath = copyInputToStore(state, lockedRef.input, input.ref->input, accessor);
|
||||
|
||||
return {state.rootPath(state.store->toRealPath(storePath)), lockedRef};
|
||||
return {state.rootPath(state.store->printStorePath(storePath)), lockedRef};
|
||||
}
|
||||
}();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue