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:
commit
7d26bf8cc7
3 changed files with 38 additions and 55 deletions
|
|
@ -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{};
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue