forked from lix-project/lix
Merge pull request #4939 from NixOS/ca/recursive-nix
Make CA derivations compatible with recursive Nix
This commit is contained in:
commit
08270af7fe
|
@ -1333,13 +1333,18 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
||||||
std::optional<const Realisation> queryRealisation(const DrvOutput & id) override
|
std::optional<const Realisation> queryRealisation(const DrvOutput & id) override
|
||||||
// XXX: This should probably be allowed if the realisation corresponds to
|
// XXX: This should probably be allowed if the realisation corresponds to
|
||||||
// an allowed derivation
|
// an allowed derivation
|
||||||
{ throw Error("queryRealisation"); }
|
{
|
||||||
|
if (!goal.isAllowed(id))
|
||||||
|
throw InvalidPath("cannot query an unknown output id '%s' in recursive Nix", id.to_string());
|
||||||
|
return next->queryRealisation(id);
|
||||||
|
}
|
||||||
|
|
||||||
void buildPaths(const std::vector<DerivedPath> & paths, BuildMode buildMode) override
|
void buildPaths(const std::vector<DerivedPath> & paths, BuildMode buildMode) override
|
||||||
{
|
{
|
||||||
if (buildMode != bmNormal) throw Error("unsupported build mode");
|
if (buildMode != bmNormal) throw Error("unsupported build mode");
|
||||||
|
|
||||||
StorePathSet newPaths;
|
StorePathSet newPaths;
|
||||||
|
std::set<Realisation> newRealisations;
|
||||||
|
|
||||||
for (auto & req : paths) {
|
for (auto & req : paths) {
|
||||||
if (!goal.isAllowed(req))
|
if (!goal.isAllowed(req))
|
||||||
|
@ -1352,16 +1357,28 @@ struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual Lo
|
||||||
auto p = std::get_if<DerivedPath::Built>(&path);
|
auto p = std::get_if<DerivedPath::Built>(&path);
|
||||||
if (!p) continue;
|
if (!p) continue;
|
||||||
auto & bfd = *p;
|
auto & bfd = *p;
|
||||||
|
auto drv = readDerivation(bfd.drvPath);
|
||||||
|
auto drvHashes = staticOutputHashes(*this, drv);
|
||||||
auto outputs = next->queryDerivationOutputMap(bfd.drvPath);
|
auto outputs = next->queryDerivationOutputMap(bfd.drvPath);
|
||||||
for (auto & [outputName, outputPath] : outputs)
|
for (auto & [outputName, outputPath] : outputs)
|
||||||
if (wantOutput(outputName, bfd.outputs))
|
if (wantOutput(outputName, bfd.outputs)) {
|
||||||
newPaths.insert(outputPath);
|
newPaths.insert(outputPath);
|
||||||
|
if (settings.isExperimentalFeatureEnabled("ca-derivations")) {
|
||||||
|
auto thisRealisation = next->queryRealisation(
|
||||||
|
DrvOutput{drvHashes.at(outputName), outputName}
|
||||||
|
);
|
||||||
|
assert(thisRealisation);
|
||||||
|
newRealisations.insert(*thisRealisation);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StorePathSet closure;
|
StorePathSet closure;
|
||||||
next->computeFSClosure(newPaths, closure);
|
next->computeFSClosure(newPaths, closure);
|
||||||
for (auto & path : closure)
|
for (auto & path : closure)
|
||||||
goal.addDependency(path);
|
goal.addDependency(path);
|
||||||
|
for (auto & real : Realisation::closure(*next, newRealisations))
|
||||||
|
goal.addedDrvOutputs.insert(real.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildResult buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
|
BuildResult buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
|
||||||
|
|
|
@ -108,6 +108,9 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||||
/* Paths that were added via recursive Nix calls. */
|
/* Paths that were added via recursive Nix calls. */
|
||||||
StorePathSet addedPaths;
|
StorePathSet addedPaths;
|
||||||
|
|
||||||
|
/* Realisations that were added via recursive Nix calls. */
|
||||||
|
std::set<DrvOutput> addedDrvOutputs;
|
||||||
|
|
||||||
/* Recursive Nix calls are only allowed to build or realize paths
|
/* Recursive Nix calls are only allowed to build or realize paths
|
||||||
in the original input closure or added via a recursive Nix call
|
in the original input closure or added via a recursive Nix call
|
||||||
(so e.g. you can't do 'nix-store -r /nix/store/<bla>' where
|
(so e.g. you can't do 'nix-store -r /nix/store/<bla>' where
|
||||||
|
@ -116,6 +119,11 @@ struct LocalDerivationGoal : public DerivationGoal
|
||||||
{
|
{
|
||||||
return inputPaths.count(path) || addedPaths.count(path);
|
return inputPaths.count(path) || addedPaths.count(path);
|
||||||
}
|
}
|
||||||
|
bool isAllowed(const DrvOutput & id)
|
||||||
|
{
|
||||||
|
return addedDrvOutputs.count(id);
|
||||||
|
}
|
||||||
|
|
||||||
bool isAllowed(const DerivedPath & req);
|
bool isAllowed(const DerivedPath & req);
|
||||||
|
|
||||||
friend struct RestrictedStore;
|
friend struct RestrictedStore;
|
||||||
|
|
11
tests/ca/recursive.sh
Executable file
11
tests/ca/recursive.sh
Executable file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
source common.sh
|
||||||
|
|
||||||
|
sed -i 's/experimental-features .*/& ca-derivations ca-references nix-command flakes/' "$NIX_CONF_DIR"/nix.conf
|
||||||
|
|
||||||
|
export NIX_TESTS_CA_BY_DEFAULT=1
|
||||||
|
cd ..
|
||||||
|
source ./recursive.sh
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ nix_tests = \
|
||||||
ca/signatures.sh \
|
ca/signatures.sh \
|
||||||
ca/nix-shell.sh \
|
ca/nix-shell.sh \
|
||||||
ca/nix-run.sh \
|
ca/nix-run.sh \
|
||||||
|
ca/recursive.sh \
|
||||||
ca/nix-copy.sh
|
ca/nix-copy.sh
|
||||||
# parallel.sh
|
# parallel.sh
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ rm -f $TEST_ROOT/result
|
||||||
|
|
||||||
export unreachable=$(nix store add-path ./recursive.sh)
|
export unreachable=$(nix store add-path ./recursive.sh)
|
||||||
|
|
||||||
NIX_BIN_DIR=$(dirname $(type -p nix)) nix --experimental-features 'nix-command recursive-nix' build -o $TEST_ROOT/result -L --impure --expr '
|
NIX_BIN_DIR=$(dirname $(type -p nix)) nix --extra-experimental-features 'nix-command recursive-nix' build -o $TEST_ROOT/result -L --impure --expr '
|
||||||
with import ./config.nix;
|
with import ./config.nix;
|
||||||
mkDerivation {
|
mkDerivation rec {
|
||||||
name = "recursive";
|
name = "recursive";
|
||||||
dummy = builtins.toFile "dummy" "bla bla";
|
dummy = builtins.toFile "dummy" "bla bla";
|
||||||
SHELL = shell;
|
SHELL = shell;
|
||||||
|
@ -19,11 +19,13 @@ NIX_BIN_DIR=$(dirname $(type -p nix)) nix --experimental-features 'nix-command r
|
||||||
# Note: this is a string without context.
|
# Note: this is a string without context.
|
||||||
unreachable = builtins.getEnv "unreachable";
|
unreachable = builtins.getEnv "unreachable";
|
||||||
|
|
||||||
|
NIX_TESTS_CA_BY_DEFAULT = builtins.getEnv "NIX_TESTS_CA_BY_DEFAULT";
|
||||||
|
|
||||||
requiredSystemFeatures = [ "recursive-nix" ];
|
requiredSystemFeatures = [ "recursive-nix" ];
|
||||||
|
|
||||||
buildCommand = '\'\''
|
buildCommand = '\'\''
|
||||||
mkdir $out
|
mkdir $out
|
||||||
opts="--experimental-features nix-command"
|
opts="--experimental-features nix-command ${if (NIX_TESTS_CA_BY_DEFAULT == "1") then "--extra-experimental-features ca-derivations" else ""}"
|
||||||
|
|
||||||
PATH=${builtins.getEnv "NIX_BIN_DIR"}:$PATH
|
PATH=${builtins.getEnv "NIX_BIN_DIR"}:$PATH
|
||||||
|
|
||||||
|
@ -46,16 +48,15 @@ NIX_BIN_DIR=$(dirname $(type -p nix)) nix --experimental-features 'nix-command r
|
||||||
# Add it to our closure.
|
# Add it to our closure.
|
||||||
ln -s $foobar $out/foobar
|
ln -s $foobar $out/foobar
|
||||||
|
|
||||||
[[ $(nix $opts path-info --all | wc -l) -eq 3 ]]
|
[[ $(nix $opts path-info --all | wc -l) -eq 4 ]]
|
||||||
|
|
||||||
# Build a derivation.
|
# Build a derivation.
|
||||||
nix $opts build -L --impure --expr '\''
|
nix $opts build -L --impure --expr '\''
|
||||||
derivation {
|
with import ${./config.nix};
|
||||||
|
mkDerivation {
|
||||||
name = "inner1";
|
name = "inner1";
|
||||||
builder = builtins.getEnv "SHELL";
|
buildCommand = "echo $fnord blaat > $out";
|
||||||
system = builtins.getEnv "system";
|
|
||||||
fnord = builtins.toFile "fnord" "fnord";
|
fnord = builtins.toFile "fnord" "fnord";
|
||||||
args = [ "-c" "echo $fnord blaat > $out" ];
|
|
||||||
}
|
}
|
||||||
'\''
|
'\''
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue