mirror of
https://github.com/NixOS/nix
synced 2025-07-06 21:41:48 +02:00
Allow substituting drv outputs when building
This commit is contained in:
parent
5d1c05b075
commit
df9d4f88d5
5 changed files with 185 additions and 12 deletions
95
src/libstore/build/drv-output-substitution-goal.cc
Normal file
95
src/libstore/build/drv-output-substitution-goal.cc
Normal file
|
@ -0,0 +1,95 @@
|
|||
#include "drv-output-substitution-goal.hh"
|
||||
#include "worker.hh"
|
||||
#include "substitution-goal.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
DrvOutputSubstitutionGoal::DrvOutputSubstitutionGoal(const DrvOutput& id, Worker & worker, RepairFlag repair, std::optional<ContentAddress> ca)
|
||||
: Goal(worker)
|
||||
, id(id)
|
||||
{
|
||||
state = &DrvOutputSubstitutionGoal::init;
|
||||
name = fmt("substitution of '%s'", id.to_string());
|
||||
trace("created");
|
||||
}
|
||||
|
||||
|
||||
void DrvOutputSubstitutionGoal::init()
|
||||
{
|
||||
trace("init");
|
||||
subs = settings.useSubstitutes ? getDefaultSubstituters() : std::list<ref<Store>>();
|
||||
tryNext();
|
||||
}
|
||||
|
||||
void DrvOutputSubstitutionGoal::tryNext()
|
||||
{
|
||||
trace("Trying next substituter");
|
||||
|
||||
if (subs.size() == 0) {
|
||||
/* None left. Terminate this goal and let someone else deal
|
||||
with it. */
|
||||
debug("drv output '%s' is required, but there is no substituter that can provide it", id.to_string());
|
||||
|
||||
/* Hack: don't indicate failure if there were no substituters.
|
||||
In that case the calling derivation should just do a
|
||||
build. */
|
||||
amDone(substituterFailed ? ecFailed : ecNoSubstituters);
|
||||
|
||||
if (substituterFailed) {
|
||||
worker.failedSubstitutions++;
|
||||
worker.updateProgress();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
auto sub = subs.front();
|
||||
subs.pop_front();
|
||||
|
||||
// FIXME: Make async
|
||||
outputInfo = sub->queryRealisation(id);
|
||||
if (!outputInfo) {
|
||||
tryNext();
|
||||
return;
|
||||
}
|
||||
|
||||
addWaitee(worker.makePathSubstitutionGoal(outputInfo->outPath));
|
||||
|
||||
if (waitees.empty()) outPathValid();
|
||||
else state = &DrvOutputSubstitutionGoal::outPathValid;
|
||||
}
|
||||
|
||||
void DrvOutputSubstitutionGoal::outPathValid()
|
||||
{
|
||||
assert(outputInfo);
|
||||
trace("Output path substituted");
|
||||
|
||||
if (nrFailed > 0) {
|
||||
debug("The output path of the derivation output '%s' could not be substituted", id.to_string());
|
||||
amDone(nrNoSubstituters > 0 || nrIncompleteClosure > 0 ? ecIncompleteClosure : ecFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
worker.store.registerDrvOutput(*outputInfo);
|
||||
finished();
|
||||
}
|
||||
|
||||
void DrvOutputSubstitutionGoal::finished()
|
||||
{
|
||||
trace("finished");
|
||||
amDone(ecSuccess);
|
||||
}
|
||||
|
||||
string DrvOutputSubstitutionGoal::key()
|
||||
{
|
||||
/* "a$" ensures substitution goals happen before derivation
|
||||
goals. */
|
||||
return "a$" + std::string(id.to_string());
|
||||
}
|
||||
|
||||
void DrvOutputSubstitutionGoal::work()
|
||||
{
|
||||
(this->*state)();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue