From 57348b677b50bf2696f76fea0b62eefe41d18c96 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 14 May 2025 13:35:37 -0400 Subject: [PATCH] Restore dynamic derivations! This method does *not* create a new type of goal. We instead just make `DerivationGoal` more sophisticated, which is much easier to do now that `DerivationBuildingGoal` has been split from it (and so many fields are gone, or or local variables instead). This avoids the need for a secondarily trampoline goal that interacted poorly with `addWantedOutputs`. That, I hope, will mean the bugs from before do not reappear. There may in fact be a reason to introduce such a trampoline in the future, but it would only happen in conjunction with getting rid of `addWantedOutputs`. Restores the functionality (and tests) that was reverted in f4f28cdd0e01a9bfb0901e8a53ead719265fa9b8. --- .../build/derivation-building-goal.cc | 4 +- src/libstore/build/derivation-goal.cc | 98 +++++++++++++------ src/libstore/build/entry-points.cc | 2 +- src/libstore/build/worker.cc | 57 +++++++---- src/libstore/derived-path-map.cc | 4 + .../nix/store/build/derivation-goal.hh | 19 ++-- .../include/nix/store/build/worker.hh | 9 +- .../include/nix/store/derived-path-map.hh | 7 +- tests/functional/dyn-drv/build-built-drv.sh | 7 +- tests/functional/dyn-drv/dep-built-drv-2.sh | 4 +- tests/functional/dyn-drv/dep-built-drv.sh | 7 +- tests/functional/dyn-drv/failing-outer.sh | 4 +- 12 files changed, 145 insertions(+), 77 deletions(-) diff --git a/src/libstore/build/derivation-building-goal.cc b/src/libstore/build/derivation-building-goal.cc index 4169903f6..14c427b83 100644 --- a/src/libstore/build/derivation-building-goal.cc +++ b/src/libstore/build/derivation-building-goal.cc @@ -296,7 +296,7 @@ Goal::Co DerivationBuildingGoal::gaveUpOnSubstitution() // FIXME wanted outputs auto resolvedDrvGoal = worker.makeDerivationGoal( - pathResolved, OutputsSpec::All{}, buildMode); + makeConstantStorePathRef(pathResolved), OutputsSpec::All{}, buildMode); { Goals waitees{resolvedDrvGoal}; co_await await(std::move(waitees)); @@ -338,7 +338,7 @@ Goal::Co DerivationBuildingGoal::gaveUpOnSubstitution() throw Error( "derivation '%s' doesn't have expected output '%s' (derivation-goal.cc/realisation)", - worker.store.printStorePath(resolvedDrvGoal->drvPath), outputName); + resolvedDrvGoal->drvReq->to_string(worker.store), outputName); }(); if (!drv->type().isImpure()) { diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 5c8b75cb9..63dca3083 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -24,16 +24,16 @@ namespace nix { -DerivationGoal::DerivationGoal(const StorePath & drvPath, +DerivationGoal::DerivationGoal(ref drvReq, const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode) : Goal(worker, loadDerivation()) - , drvPath(drvPath) + , drvReq(drvReq) , wantedOutputs(wantedOutputs) , buildMode(buildMode) { name = fmt( "building of '%s' from .drv file", - DerivedPath::Built { makeConstantStorePathRef(drvPath), wantedOutputs }.to_string(worker.store)); + DerivedPath::Built { drvReq, wantedOutputs }.to_string(worker.store)); trace("created"); mcExpectedBuilds = std::make_unique>(worker.expectedBuilds); @@ -43,8 +43,8 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath, DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode) - : Goal(worker, haveDerivation()) - , drvPath(drvPath) + : Goal(worker, haveDerivation(drvPath)) + , drvReq(makeConstantStorePathRef(drvPath)) , wantedOutputs(wantedOutputs) , buildMode(buildMode) { @@ -52,7 +52,7 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation name = fmt( "building of '%s' from in-memory derivation", - DerivedPath::Built { makeConstantStorePathRef(drvPath), drv.outputNames() }.to_string(worker.store)); + DerivedPath::Built { drvReq, drv.outputNames() }.to_string(worker.store)); trace("created"); mcExpectedBuilds = std::make_unique>(worker.expectedBuilds); @@ -61,13 +61,24 @@ DerivationGoal::DerivationGoal(const StorePath & drvPath, const BasicDerivation } +static StorePath pathPartOfReq(const SingleDerivedPath & req) +{ + return std::visit( + overloaded{ + [&](const SingleDerivedPath::Opaque & bo) { return bo.path; }, + [&](const SingleDerivedPath::Built & bfd) { return pathPartOfReq(*bfd.drvPath); }, + }, + req.raw()); +} + + std::string DerivationGoal::key() { /* Ensure that derivations get built in order of their name, i.e. a derivation named "aardvark" always comes before "baboon". And substitution goals always happen before derivation goals (due to "b$"). */ - return "b$" + std::string(drvPath.name()) + "$" + worker.store.printStorePath(drvPath); + return "b$" + std::string(pathPartOfReq(*drvReq).name()) + "$" + drvReq->to_string(worker.store); } @@ -93,24 +104,46 @@ void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs) Goal::Co DerivationGoal::loadDerivation() { - trace("local derivation"); + trace("need to load derivation from file"); { /* The first thing to do is to make sure that the derivation - exists. If it doesn't, it may be created through a - substitute. */ + exists. If it doesn't, it may be built from another + derivation, or merely substituted. We can make goal to get it + and not worry about which method it takes to get the + derivation. */ - if (buildMode != bmNormal || !worker.evalStore.isValidPath(drvPath)) { - Goals waitees{upcast_goal(worker.makePathSubstitutionGoal(drvPath))}; + if (auto optDrvPath = [this]() -> std::optional { + if (buildMode != bmNormal) + return std::nullopt; + + auto drvPath = StorePath::dummy; + try { + drvPath = resolveDerivedPath(worker.store, *drvReq); + } catch (MissingRealisation &) { + return std::nullopt; + } + auto cond = worker.evalStore.isValidPath(drvPath) || worker.store.isValidPath(drvPath); + return cond ? std::optional{drvPath} : std::nullopt; + }()) { + trace( + fmt("already have drv '%s' for '%s', can go straight to building", + worker.store.printStorePath(*optDrvPath), + drvReq->to_string(worker.store))); + } else { + trace("need to obtain drv we want to build"); + Goals waitees{worker.makeGoal(DerivedPath::fromSingle(*drvReq))}; co_await await(std::move(waitees)); } trace("loading derivation"); if (nrFailed != 0) { - co_return done(BuildResult::MiscFailure, {}, Error("cannot build missing derivation '%s'", worker.store.printStorePath(drvPath))); + co_return amDone(ecFailed, Error("cannot build missing derivation '%s'", drvReq->to_string(worker.store))); } + StorePath drvPath = resolveDerivedPath(worker.store, *drvReq); + /* `drvPath' should already be a root, but let's be on the safe side: if the user forgot to make it a root, we wouldn't want things being garbage collected while we're busy. */ @@ -129,13 +162,13 @@ Goal::Co DerivationGoal::loadDerivation() { } } assert(drv); - } - co_return haveDerivation(); + co_return haveDerivation(drvPath); + } } -Goal::Co DerivationGoal::haveDerivation() +Goal::Co DerivationGoal::haveDerivation(StorePath drvPath) { trace("have derivation"); @@ -221,11 +254,11 @@ Goal::Co DerivationGoal::haveDerivation() { /* Check what outputs paths are not already valid. */ - auto [allValid, validOutputs] = checkPathValidity(); + auto [allValid, validOutputs] = checkPathValidity(drvPath); /* If they are all valid, then we're done. */ if (allValid && buildMode == bmNormal) { - co_return done(BuildResult::AlreadyValid, std::move(validOutputs)); + co_return done(drvPath, BuildResult::AlreadyValid, std::move(validOutputs)); } } @@ -262,7 +295,7 @@ Goal::Co DerivationGoal::haveDerivation() assert(!drv->type().isImpure()); if (nrFailed > 0 && nrFailed > nrNoSubstituters && !settings.tryFallback) { - co_return done(BuildResult::TransientFailure, {}, + co_return done(drvPath, BuildResult::TransientFailure, {}, Error("some substitutes for the outputs of derivation '%s' failed (usually happens due to networking issues); try '--fallback' to build derivation from source ", worker.store.printStorePath(drvPath))); } @@ -271,16 +304,16 @@ Goal::Co DerivationGoal::haveDerivation() if (needRestart == NeedRestartForMoreOutputs::OutputsAddedDoNeed) { needRestart = NeedRestartForMoreOutputs::OutputsUnmodifedDontNeed; - co_return haveDerivation(); + co_return haveDerivation(std::move(drvPath)); } - auto [allValid, validOutputs] = checkPathValidity(); + auto [allValid, validOutputs] = checkPathValidity(drvPath); if (buildMode == bmNormal && allValid) { - co_return done(BuildResult::Substituted, std::move(validOutputs)); + co_return done(drvPath, BuildResult::Substituted, std::move(validOutputs)); } if (buildMode == bmRepair && allValid) { - co_return repairClosure(); + co_return repairClosure(std::move(drvPath)); } if (buildMode == bmCheck && !allValid) throw Error("some outputs of '%s' are not valid, so checking is not possible", @@ -303,7 +336,7 @@ struct value_comparison }; -Goal::Co DerivationGoal::repairClosure() +Goal::Co DerivationGoal::repairClosure(StorePath drvPath) { assert(!drv->type().isImpure()); @@ -313,7 +346,7 @@ Goal::Co DerivationGoal::repairClosure() that produced those outputs. */ /* Get the output closure. */ - auto outputs = queryDerivationOutputMap(); + auto outputs = queryDerivationOutputMap(drvPath); StorePathSet outputClosure; for (auto & i : outputs) { if (!wantedOutputs.contains(i.first)) continue; @@ -371,11 +404,11 @@ Goal::Co DerivationGoal::repairClosure() throw Error("some paths in the output closure of derivation '%s' could not be repaired", worker.store.printStorePath(drvPath)); } - co_return done(BuildResult::AlreadyValid, assertPathValidity()); + co_return done(drvPath, BuildResult::AlreadyValid, assertPathValidity(drvPath)); } -std::map> DerivationGoal::queryPartialDerivationOutputMap() +std::map> DerivationGoal::queryPartialDerivationOutputMap(const StorePath & drvPath) { assert(!drv->type().isImpure()); @@ -391,7 +424,7 @@ std::map> DerivationGoal::queryPartialDeri return res; } -OutputPathMap DerivationGoal::queryDerivationOutputMap() +OutputPathMap DerivationGoal::queryDerivationOutputMap(const StorePath & drvPath) { assert(!drv->type().isImpure()); @@ -407,7 +440,7 @@ OutputPathMap DerivationGoal::queryDerivationOutputMap() } -std::pair DerivationGoal::checkPathValidity() +std::pair DerivationGoal::checkPathValidity(const StorePath & drvPath) { if (drv->type().isImpure()) return { false, {} }; @@ -422,7 +455,7 @@ std::pair DerivationGoal::checkPathValidity() }, wantedOutputs.raw); SingleDrvOutputs validOutputs; - for (auto & i : queryPartialDerivationOutputMap()) { + for (auto & i : queryPartialDerivationOutputMap(drvPath)) { auto initialOutput = get(initialOutputs, i.first); if (!initialOutput) // this is an invalid output, gets catched with (!wantedOutputsLeft.empty()) @@ -487,9 +520,9 @@ std::pair DerivationGoal::checkPathValidity() } -SingleDrvOutputs DerivationGoal::assertPathValidity() +SingleDrvOutputs DerivationGoal::assertPathValidity(const StorePath & drvPath) { - auto [allValid, validOutputs] = checkPathValidity(); + auto [allValid, validOutputs] = checkPathValidity(drvPath); if (!allValid) throw Error("some outputs are unexpectedly invalid"); return validOutputs; @@ -497,6 +530,7 @@ SingleDrvOutputs DerivationGoal::assertPathValidity() Goal::Done DerivationGoal::done( + const StorePath & drvPath, BuildResult::Status status, SingleDrvOutputs builtOutputs, std::optional ex) diff --git a/src/libstore/build/entry-points.cc b/src/libstore/build/entry-points.cc index c934b0704..39fd471c4 100644 --- a/src/libstore/build/entry-points.cc +++ b/src/libstore/build/entry-points.cc @@ -30,7 +30,7 @@ void Store::buildPaths(const std::vector & reqs, BuildMode buildMod if (i->exitCode != Goal::ecSuccess) { #ifndef _WIN32 // TODO Enable building on Windows if (auto i2 = dynamic_cast(i.get())) - failed.insert(printStorePath(i2->drvPath)); + failed.insert(i2->drvReq->to_string(*this)); else #endif if (auto i2 = dynamic_cast(i.get())) diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc index aaf4c149f..12d4aaa2d 100644 --- a/src/libstore/build/worker.cc +++ b/src/libstore/build/worker.cc @@ -54,11 +54,11 @@ std::shared_ptr Worker::initGoalIfNeeded(std::weak_ptr & goal_weak, Args & } std::shared_ptr Worker::makeDerivationGoalCommon( - const StorePath & drvPath, + ref drvReq, const OutputsSpec & wantedOutputs, std::function()> mkDrvGoal) { - std::weak_ptr & goal_weak = derivationGoals[drvPath]; + std::weak_ptr & goal_weak = derivationGoals.ensureSlot(*drvReq).value; std::shared_ptr goal = goal_weak.lock(); if (!goal) { goal = mkDrvGoal(); @@ -71,18 +71,18 @@ std::shared_ptr Worker::makeDerivationGoalCommon( } -std::shared_ptr Worker::makeDerivationGoal(const StorePath & drvPath, +std::shared_ptr Worker::makeDerivationGoal(ref drvReq, const OutputsSpec & wantedOutputs, BuildMode buildMode) { - return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() -> std::shared_ptr { - return std::make_shared(drvPath, wantedOutputs, *this, buildMode); + return makeDerivationGoalCommon(drvReq, wantedOutputs, [&]() -> std::shared_ptr { + return std::make_shared(drvReq, wantedOutputs, *this, buildMode); }); } std::shared_ptr Worker::makeBasicDerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, const OutputsSpec & wantedOutputs, BuildMode buildMode) { - return makeDerivationGoalCommon(drvPath, wantedOutputs, [&]() -> std::shared_ptr { + return makeDerivationGoalCommon(makeConstantStorePathRef(drvPath), wantedOutputs, [&]() -> std::shared_ptr { return std::make_shared(drvPath, drv, wantedOutputs, *this, buildMode); }); } @@ -118,10 +118,7 @@ GoalPtr Worker::makeGoal(const DerivedPath & req, BuildMode buildMode) { return std::visit(overloaded { [&](const DerivedPath::Built & bfd) -> GoalPtr { - if (auto bop = std::get_if(&*bfd.drvPath)) - return makeDerivationGoal(bop->path, bfd.outputs, buildMode); - else - throw UnimplementedError("Building dynamic derivations in one shot is not yet implemented."); + return makeDerivationGoal(bfd.drvPath, bfd.outputs, buildMode); }, [&](const DerivedPath::Opaque & bo) -> GoalPtr { return makePathSubstitutionGoal(bo.path, buildMode == bmRepair ? Repair : NoRepair); @@ -130,25 +127,45 @@ GoalPtr Worker::makeGoal(const DerivedPath & req, BuildMode buildMode) } +template +static void cullMap(std::map & goalMap, F f) +{ + for (auto i = goalMap.begin(); i != goalMap.end();) + if (!f(i->second)) + i = goalMap.erase(i); + else ++i; +} + + template static void removeGoal(std::shared_ptr goal, std::map> & goalMap) { /* !!! inefficient */ - for (auto i = goalMap.begin(); - i != goalMap.end(); ) - if (i->second.lock() == goal) { - auto j = i; ++j; - goalMap.erase(i); - i = j; - } - else ++i; + cullMap(goalMap, [&](const std::weak_ptr & gp) -> bool { + return gp.lock() != goal; + }); +} + +template +static void removeGoal(std::shared_ptr goal, std::map>::ChildNode> & goalMap); + +template +static void removeGoal(std::shared_ptr goal, std::map>::ChildNode> & goalMap) +{ + /* !!! inefficient */ + cullMap(goalMap, [&](DerivedPathMap>::ChildNode & node) -> bool { + if (node.value.lock() == goal) + node.value.reset(); + removeGoal(goal, node.childMap); + return !node.value.expired() || !node.childMap.empty(); + }); } void Worker::removeGoal(GoalPtr goal) { if (auto drvGoal = std::dynamic_pointer_cast(goal)) - nix::removeGoal(drvGoal, derivationGoals); + nix::removeGoal(drvGoal, derivationGoals.map); else if (auto drvBuildingGoal = std::dynamic_pointer_cast(goal)) nix::removeGoal(drvBuildingGoal, derivationBuildingGoals); else if (auto subGoal = std::dynamic_pointer_cast(goal)) @@ -297,7 +314,7 @@ void Worker::run(const Goals & _topGoals) topGoals.insert(i); if (auto goal = dynamic_cast(i.get())) { topPaths.push_back(DerivedPath::Built { - .drvPath = makeConstantStorePathRef(goal->drvPath), + .drvPath = goal->drvReq, .outputs = goal->wantedOutputs, }); } else diff --git a/src/libstore/derived-path-map.cc b/src/libstore/derived-path-map.cc index b785dddd9..408d1a6b9 100644 --- a/src/libstore/derived-path-map.cc +++ b/src/libstore/derived-path-map.cc @@ -52,6 +52,7 @@ typename DerivedPathMap::ChildNode * DerivedPathMap::findSlot(const Single // instantiations +#include "nix/store/build/derivation-goal.hh" namespace nix { template<> @@ -68,4 +69,7 @@ std::strong_ordering DerivedPathMap::ChildNode::operator <=> ( template struct DerivedPathMap::ChildNode; template struct DerivedPathMap; +template struct DerivedPathMap>; + + }; diff --git a/src/libstore/include/nix/store/build/derivation-goal.hh b/src/libstore/include/nix/store/build/derivation-goal.hh index 7118fd4a5..b422aec7a 100644 --- a/src/libstore/include/nix/store/build/derivation-goal.hh +++ b/src/libstore/include/nix/store/build/derivation-goal.hh @@ -27,7 +27,7 @@ void runPostBuildHook( struct DerivationGoal : public Goal { /** The path of the derivation. */ - StorePath drvPath; + ref drvReq; /** * The specific outputs that we need to build. @@ -62,7 +62,7 @@ struct DerivationGoal : public Goal NeedRestartForMoreOutputs needRestart = NeedRestartForMoreOutputs::OutputsUnmodifedDontNeed; /** - * The derivation stored at drvPath. + * The derivation stored at `drvReq`. */ std::unique_ptr drv; @@ -76,7 +76,7 @@ struct DerivationGoal : public Goal std::unique_ptr> mcExpectedBuilds; - DerivationGoal(const StorePath & drvPath, + DerivationGoal(ref drvReq, const OutputsSpec & wantedOutputs, Worker & worker, BuildMode buildMode = bmNormal); DerivationGoal(const StorePath & drvPath, const BasicDerivation & drv, @@ -97,15 +97,15 @@ struct DerivationGoal : public Goal * The states. */ Co loadDerivation(); - Co haveDerivation(); + Co haveDerivation(StorePath drvPath); /** * Wrappers around the corresponding Store methods that first consult the * derivation. This is currently needed because when there is no drv file * there also is no DB entry. */ - std::map> queryPartialDerivationOutputMap(); - OutputPathMap queryDerivationOutputMap(); + std::map> queryPartialDerivationOutputMap(const StorePath & drvPath); + OutputPathMap queryDerivationOutputMap(const StorePath & drvPath); /** * Update 'initialOutputs' to determine the current status of the @@ -113,17 +113,18 @@ struct DerivationGoal : public Goal * whether all outputs are valid and non-corrupt, and a * 'SingleDrvOutputs' structure containing the valid outputs. */ - std::pair checkPathValidity(); + std::pair checkPathValidity(const StorePath & drvPath); /** * Aborts if any output is not valid or corrupt, and otherwise * returns a 'SingleDrvOutputs' structure containing all outputs. */ - SingleDrvOutputs assertPathValidity(); + SingleDrvOutputs assertPathValidity(const StorePath & drvPath); - Co repairClosure(); + Co repairClosure(StorePath drvPath); Done done( + const StorePath & drvPath, BuildResult::Status status, SingleDrvOutputs builtOutputs = {}, std::optional ex = {}); diff --git a/src/libstore/include/nix/store/build/worker.hh b/src/libstore/include/nix/store/build/worker.hh index 46c4d181e..c70c72377 100644 --- a/src/libstore/include/nix/store/build/worker.hh +++ b/src/libstore/include/nix/store/build/worker.hh @@ -3,6 +3,7 @@ #include "nix/util/types.hh" #include "nix/store/store-api.hh" +#include "nix/store/derived-path-map.hh" #include "nix/store/build/goal.hh" #include "nix/store/realisation.hh" #include "nix/util/muxable-pipe.hh" @@ -104,7 +105,9 @@ private: * Maps used to prevent multiple instantiations of a goal for the * same derivation / path. */ - std::map> derivationGoals; + + DerivedPathMap> derivationGoals; + std::map> derivationBuildingGoals; std::map> substitutionGoals; std::map> drvOutputSubstitutionGoals; @@ -202,11 +205,11 @@ private: std::shared_ptr initGoalIfNeeded(std::weak_ptr & goal_weak, Args && ...args); std::shared_ptr makeDerivationGoalCommon( - const StorePath & drvPath, const OutputsSpec & wantedOutputs, + ref drvReq, const OutputsSpec & wantedOutputs, std::function()> mkDrvGoal); public: std::shared_ptr makeDerivationGoal( - const StorePath & drvPath, + ref drvReq, const OutputsSpec & wantedOutputs, BuildMode buildMode = bmNormal); std::shared_ptr makeBasicDerivationGoal( const StorePath & drvPath, const BasicDerivation & drv, diff --git a/src/libstore/include/nix/store/derived-path-map.hh b/src/libstore/include/nix/store/derived-path-map.hh index cad86d1b4..16ffeb05e 100644 --- a/src/libstore/include/nix/store/derived-path-map.hh +++ b/src/libstore/include/nix/store/derived-path-map.hh @@ -21,8 +21,11 @@ namespace nix { * * @param V A type to instantiate for each output. It should probably * should be an "optional" type so not every interior node has to have a - * value. `* const Something` or `std::optional` would be - * good choices for "optional" types. + * value. For example, the scheduler uses + * `DerivedPathMap>` to + * remember which goals correspond to which outputs. `* const Something` + * or `std::optional` would also be good choices for + * "optional" types. */ template struct DerivedPathMap { diff --git a/tests/functional/dyn-drv/build-built-drv.sh b/tests/functional/dyn-drv/build-built-drv.sh index 647be9457..49d61c6ce 100644 --- a/tests/functional/dyn-drv/build-built-drv.sh +++ b/tests/functional/dyn-drv/build-built-drv.sh @@ -18,4 +18,9 @@ clearStore drvDep=$(nix-instantiate ./text-hashed-output.nix -A producingDrv) -expectStderr 1 nix build "${drvDep}^out^out" --no-link | grepQuiet "Building dynamic derivations in one shot is not yet implemented" +# Store layer needs bugfix +requireDaemonNewerThan "2.30pre20250515" + +out2=$(nix build "${drvDep}^out^out" --no-link) + +test $out1 == $out2 diff --git a/tests/functional/dyn-drv/dep-built-drv-2.sh b/tests/functional/dyn-drv/dep-built-drv-2.sh index 3247720af..0e4cc7c12 100644 --- a/tests/functional/dyn-drv/dep-built-drv-2.sh +++ b/tests/functional/dyn-drv/dep-built-drv-2.sh @@ -3,7 +3,7 @@ source common.sh # Store layer needs bugfix -requireDaemonNewerThan "2.27pre20250205" +requireDaemonNewerThan "2.30pre20250515" TODO_NixOS # can't enable a sandbox feature easily @@ -13,4 +13,4 @@ restartDaemon NIX_BIN_DIR="$(dirname "$(type -p nix)")" export NIX_BIN_DIR -expectStderr 1 nix build -L --file ./non-trivial.nix --no-link | grepQuiet "Building dynamic derivations in one shot is not yet implemented" +nix build -L --file ./non-trivial.nix --no-link diff --git a/tests/functional/dyn-drv/dep-built-drv.sh b/tests/functional/dyn-drv/dep-built-drv.sh index 4f6e9b080..e9a8b6b83 100644 --- a/tests/functional/dyn-drv/dep-built-drv.sh +++ b/tests/functional/dyn-drv/dep-built-drv.sh @@ -4,8 +4,11 @@ source common.sh out1=$(nix-build ./text-hashed-output.nix -A hello --no-out-link) +# Store layer needs bugfix +requireDaemonNewerThan "2.30pre20250515" + clearStore -expectStderr 1 nix-build ./text-hashed-output.nix -A wrapper --no-out-link | grepQuiet "Building dynamic derivations in one shot is not yet implemented" +out2=$(nix-build ./text-hashed-output.nix -A wrapper --no-out-link) -# diff -r $out1 $out2 +diff -r $out1 $out2 diff --git a/tests/functional/dyn-drv/failing-outer.sh b/tests/functional/dyn-drv/failing-outer.sh index fbad70701..3feda74fb 100644 --- a/tests/functional/dyn-drv/failing-outer.sh +++ b/tests/functional/dyn-drv/failing-outer.sh @@ -3,9 +3,7 @@ source common.sh # Store layer needs bugfix -requireDaemonNewerThan "2.27pre20250205" - -skipTest "dyn drv input scheduling had to be reverted for 2.27" +requireDaemonNewerThan "2.30pre20250515" expected=100 if [[ -v NIX_DAEMON_PACKAGE ]]; then expected=1; fi # work around the daemon not returning a 100 status correctly