1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 12:06:01 +01:00

Merge pull request #13906 from obsidiansystems/derivation-builder-simpler

More `DerivationBuilder` simplifications
This commit is contained in:
Jörg Thalheim 2025-09-10 09:58:07 +02:00 committed by GitHub
commit 7d26bf8cc7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 38 additions and 55 deletions

View file

@ -689,6 +689,8 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
#else #else
assert(!hook); assert(!hook);
Descriptor builderOut;
// Will continue here while waiting for a build user below // Will continue here while waiting for a build user below
while (true) { while (true) {
@ -716,11 +718,6 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
~DerivationBuildingGoalCallbacks() override = default; ~DerivationBuildingGoalCallbacks() override = default;
void childStarted(Descriptor builderOut) override
{
goal.worker.childStarted(goal.shared_from_this(), {builderOut}, true, true);
}
void childTerminated() override void childTerminated() override
{ {
goal.worker.childTerminated(&goal); goal.worker.childTerminated(&goal);
@ -786,7 +783,17 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
}); });
} }
if (!builder->prepareBuild()) { std::optional<Descriptor> builderOutOpt;
try {
/* Okay, we have to build. */
builderOutOpt = builder->startBuild();
} catch (BuildError & e) {
builder.reset();
outputLocks.unlock();
worker.permanentFailure = true;
co_return doneFailure(std::move(e)); // InputRejected
}
if (!builderOutOpt) {
if (!actLock) if (!actLock)
actLock = std::make_unique<Activity>( actLock = std::make_unique<Activity>(
*logger, *logger,
@ -795,24 +802,16 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
fmt("waiting for a free build user ID for '%s'", Magenta(worker.store.printStorePath(drvPath)))); fmt("waiting for a free build user ID for '%s'", Magenta(worker.store.printStorePath(drvPath))));
co_await waitForAWhile(); co_await waitForAWhile();
continue; continue;
} } else {
builderOut = *std::move(builderOutOpt);
};
break; break;
} }
actLock.reset(); actLock.reset();
try { worker.childStarted(shared_from_this(), {builderOut}, true, true);
/* Okay, we have to build. */
builder->startBuilder();
} catch (BuildError & e) {
builder.reset();
outputLocks.unlock();
worker.permanentFailure = true;
co_return doneFailure(std::move(e)); // InputRejected
}
started(); started();
co_await Suspend{}; co_await Suspend{};

View file

@ -76,10 +76,7 @@ struct DerivationBuilderParams
*/ */
const StorePathSet & inputPaths; const StorePathSet & inputPaths;
/** const std::map<std::string, InitialOutput> & initialOutputs;
* @note we do in fact mutate this
*/
std::map<std::string, InitialOutput> & initialOutputs;
const BuildMode & buildMode; const BuildMode & buildMode;
@ -117,13 +114,6 @@ struct DerivationBuilderCallbacks
*/ */
virtual void closeLogFile() = 0; virtual void closeLogFile() = 0;
/**
* Hook up `builderOut` to some mechanism to ingest the log
*
* @todo this should be reworked
*/
virtual void childStarted(Descriptor builderOut) = 0;
/** /**
* @todo this should be reworked * @todo this should be reworked
*/ */
@ -157,15 +147,15 @@ struct DerivationBuilder : RestrictionContext
* locks as needed). After this is run, the builder should be * locks as needed). After this is run, the builder should be
* started. * started.
* *
* @returns true if successful, false if we could not acquire a build * @returns logging pipe if successful, `std::nullopt` if we could
* user. In that case, the caller must wait and then try again. * not acquire a build user. In that case, the caller must wait and
* then try again.
*
* @note "success" just means that we were able to set up the environment
* and start the build. The builder could have immediately exited with
* failure, and that would still be considered a successful start.
*/ */
virtual bool prepareBuild() = 0; virtual std::optional<Descriptor> startBuild() = 0;
/**
* Start building a derivation.
*/
virtual void startBuilder() = 0;
/** /**
* Tear down build environment after the builder exits (either on * Tear down build environment after the builder exits (either on

View file

@ -214,9 +214,7 @@ protected:
public: public:
bool prepareBuild() override; std::optional<Descriptor> startBuild() override;
void startBuilder() override;
SingleDrvOutputs unprepareBuild() override; SingleDrvOutputs unprepareBuild() override;
@ -470,19 +468,6 @@ bool DerivationBuilderImpl::killChild()
return ret; return ret;
} }
bool DerivationBuilderImpl::prepareBuild()
{
if (useBuildUsers()) {
if (!buildUser)
buildUser = getBuildUser();
if (!buildUser)
return false;
}
return true;
}
SingleDrvOutputs DerivationBuilderImpl::unprepareBuild() SingleDrvOutputs DerivationBuilderImpl::unprepareBuild()
{ {
/* Since we got an EOF on the logger pipe, the builder is presumed /* Since we got an EOF on the logger pipe, the builder is presumed
@ -679,8 +664,16 @@ static bool checkNotWorldWritable(std::filesystem::path path)
return true; return true;
} }
void DerivationBuilderImpl::startBuilder() std::optional<Descriptor> DerivationBuilderImpl::startBuild()
{ {
if (useBuildUsers()) {
if (!buildUser)
buildUser = getBuildUser();
if (!buildUser)
return std::nullopt;
}
/* Make sure that no other processes are executing under the /* Make sure that no other processes are executing under the
sandbox uids. This must be done before any chownToBuilder() sandbox uids. This must be done before any chownToBuilder()
calls. */ calls. */
@ -841,9 +834,10 @@ void DerivationBuilderImpl::startBuilder()
startChild(); startChild();
pid.setSeparatePG(true); pid.setSeparatePG(true);
miscMethods->childStarted(builderOut.get());
processSandboxSetupMessages(); processSandboxSetupMessages();
return builderOut.get();
} }
PathsInChroot DerivationBuilderImpl::getPathsInSandbox() PathsInChroot DerivationBuilderImpl::getPathsInSandbox()