mirror of
https://github.com/NixOS/nix
synced 2025-06-25 14:51: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 [accessor, lockedRef] = flakeRef.resolve(state.store).lazyFetch(state.store);
|
||||||
auto storePath = nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
auto storePath = nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
||||||
state.allowPath(storePath);
|
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,
|
state.fetchSettings,
|
||||||
EvalSettings::resolvePseudoUrl(s));
|
EvalSettings::resolvePseudoUrl(s));
|
||||||
auto storePath = fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy);
|
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:")) {
|
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 [accessor, lockedRef] = flakeRef.resolve(state.store).lazyFetch(state.store);
|
||||||
auto storePath = nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
auto storePath = nix::fetchToStore(*state.store, SourcePath(accessor), FetchMode::Copy, lockedRef.input.getName());
|
||||||
state.allowPath(storePath);
|
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) == '>') {
|
else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
|
||||||
|
|
|
@ -246,20 +246,36 @@ EvalState::EvalState(
|
||||||
, repair(NoRepair)
|
, repair(NoRepair)
|
||||||
, emptyBindings(0)
|
, emptyBindings(0)
|
||||||
, rootFS(
|
, rootFS(
|
||||||
settings.restrictEval || settings.pureEval
|
({
|
||||||
? ref<SourceAccessor>(AllowListSourceAccessor::create(getFSSourceAccessor(), {},
|
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 {
|
[&settings](const CanonPath & path) -> RestrictedPathError {
|
||||||
auto modeInformation = settings.pureEval
|
auto modeInformation = settings.pureEval
|
||||||
? "in pure evaluation mode (use '--impure' to override)"
|
? "in pure evaluation mode (use '--impure' to override)"
|
||||||
: "in restricted mode";
|
: "in restricted mode";
|
||||||
throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation);
|
throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation);
|
||||||
}))
|
});
|
||||||
: getFSSourceAccessor())
|
|
||||||
, storeFS(
|
accessor;
|
||||||
makeMountedSourceAccessor(
|
|
||||||
{
|
|
||||||
{CanonPath::root, makeEmptySourceAccessor()},
|
|
||||||
{CanonPath(store->storeDir), makeFSSourceAccessor(dirOf(store->toRealPath(StorePath::dummy)))}
|
|
||||||
}))
|
}))
|
||||||
, corepkgsFS(make_ref<MemorySourceAccessor>())
|
, corepkgsFS(make_ref<MemorySourceAccessor>())
|
||||||
, internalFS(make_ref<MemorySourceAccessor>())
|
, internalFS(make_ref<MemorySourceAccessor>())
|
||||||
|
@ -350,7 +366,7 @@ void EvalState::allowPath(const Path & path)
|
||||||
void EvalState::allowPath(const StorePath & storePath)
|
void EvalState::allowPath(const StorePath & storePath)
|
||||||
{
|
{
|
||||||
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
|
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)
|
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();
|
auto path = coerceToString(pos, v, context, errorCtx, false, false, true).toOwned();
|
||||||
if (path == "" || path[0] != '/')
|
if (path == "" || path[0] != '/')
|
||||||
error<EvalError>("string '%1%' doesn't represent an absolute path", path).withTrace(pos, errorCtx).debugThrow();
|
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,
|
fetchSettings,
|
||||||
EvalSettings::resolvePseudoUrl(value));
|
EvalSettings::resolvePseudoUrl(value));
|
||||||
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
|
auto storePath = fetchToStore(*store, SourcePath(accessor), FetchMode::Copy);
|
||||||
return finish(rootPath(store->toRealPath(storePath)));
|
return finish(rootPath(store->printStorePath(storePath)));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
logWarning({
|
logWarning({
|
||||||
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
.msg = HintFmt("Nix search path entry '%1%' cannot be downloaded, ignoring", value)
|
||||||
|
|
|
@ -250,11 +250,6 @@ public:
|
||||||
*/
|
*/
|
||||||
const ref<SourceAccessor> rootFS;
|
const ref<SourceAccessor> rootFS;
|
||||||
|
|
||||||
/**
|
|
||||||
* The accessor for the store.
|
|
||||||
*/
|
|
||||||
const ref<SourceAccessor> storeFS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The in-memory filesystem for <nix/...> paths.
|
* The in-memory filesystem for <nix/...> paths.
|
||||||
*/
|
*/
|
||||||
|
@ -394,18 +389,6 @@ public:
|
||||||
*/
|
*/
|
||||||
SourcePath rootPath(PathView path);
|
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.
|
* Allow access to a path.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -13,10 +13,4 @@ SourcePath EvalState::rootPath(PathView path)
|
||||||
return {rootFS, CanonPath(absPath(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");
|
auto path = state.coerceToPath(noPos, v, context, "while realising the context of a path");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!context.empty() && path.accessor == state.storeFS) {
|
if (!context.empty() && path.accessor == state.rootFS) {
|
||||||
auto rewrites = state.realiseContext(context);
|
auto rewrites = state.realiseContext(context);
|
||||||
path = {path.accessor, CanonPath(rewriteStrings(path.path.abs(), rewrites))};
|
path = {path.accessor, CanonPath(rewriteStrings(path.path.abs(), rewrites))};
|
||||||
}
|
}
|
||||||
|
@ -2480,7 +2480,7 @@ static void addPath(
|
||||||
try {
|
try {
|
||||||
StorePathSet refs;
|
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
|
// FIXME: handle CA derivation outputs (where path needs to
|
||||||
// be rewritten to the actual output).
|
// be rewritten to the actual output).
|
||||||
auto rewrites = state.realiseContext(context);
|
auto rewrites = state.realiseContext(context);
|
||||||
|
|
|
@ -337,7 +337,7 @@ static Flake readFlake(
|
||||||
auto storePath = fetchToStore(*state.store, setting.value->path(), FetchMode::Copy);
|
auto storePath = fetchToStore(*state.store, setting.value->path(), FetchMode::Copy);
|
||||||
flake.config.settings.emplace(
|
flake.config.settings.emplace(
|
||||||
state.symbols[setting.name],
|
state.symbols[setting.name],
|
||||||
state.store->toRealPath(storePath));
|
state.store->printStorePath(storePath));
|
||||||
}
|
}
|
||||||
else if (setting.value->type() == nInt)
|
else if (setting.value->type() == nInt)
|
||||||
flake.config.settings.emplace(
|
flake.config.settings.emplace(
|
||||||
|
@ -423,7 +423,7 @@ static Flake getFlake(
|
||||||
auto storePath = copyInputToStore(state, lockedRef.input, originalRef.input, accessor);
|
auto storePath = copyInputToStore(state, lockedRef.input, originalRef.input, accessor);
|
||||||
|
|
||||||
// Re-parse flake.nix from the store.
|
// 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)
|
Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool useRegistries)
|
||||||
|
@ -784,7 +784,7 @@ LockedFlake lockFlake(
|
||||||
// FIXME: allow input to be lazy.
|
// FIXME: allow input to be lazy.
|
||||||
auto storePath = copyInputToStore(state, lockedRef.input, input.ref->input, accessor);
|
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