aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r--src/libstore/build.cc32
1 files changed, 21 insertions, 11 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 07b533783..8eb192059 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -733,7 +733,7 @@ private:
/* Whether to retry substituting the outputs after building the
inputs. */
- bool retrySubstitution = false;
+ bool retrySubstitution;
/* The derivation stored at drvPath. */
std::unique_ptr<BasicDerivation> drv;
@@ -1123,6 +1123,8 @@ void DerivationGoal::haveDerivation()
{
trace("have derivation");
+ retrySubstitution = false;
+
for (auto & i : drv->outputs)
worker.store.addTempRoot(i.second.path);
@@ -1161,7 +1163,7 @@ void DerivationGoal::outputsSubstituted()
/* If the substitutes form an incomplete closure, then we should
build the dependencies of this derivation, but after that, we
can still use the substitutes for this derivation itself. */
- if (nrIncompleteClosure > 0 && !retrySubstitution) retrySubstitution = true;
+ if (nrIncompleteClosure > 0) retrySubstitution = true;
nrFailed = nrNoSubstituters = nrIncompleteClosure = 0;
@@ -3524,8 +3526,8 @@ private:
/* The current substituter. */
std::shared_ptr<Store> sub;
- /* Whether any substituter can realise this path. */
- bool hasSubstitute;
+ /* Whether a substituter failed. */
+ bool substituterFailed = false;
/* Path info returned by the substituter's query info operation. */
std::shared_ptr<const ValidPathInfo> info;
@@ -3589,7 +3591,6 @@ public:
SubstitutionGoal::SubstitutionGoal(const Path & storePath, Worker & worker, RepairFlag repair)
: Goal(worker)
- , hasSubstitute(false)
, repair(repair)
{
this->storePath = storePath;
@@ -3653,9 +3654,9 @@ void SubstitutionGoal::tryNext()
/* Hack: don't indicate failure if there were no substituters.
In that case the calling derivation should just do a
build. */
- amDone(hasSubstitute ? ecFailed : ecNoSubstituters);
+ amDone(substituterFailed ? ecFailed : ecNoSubstituters);
- if (hasSubstitute) {
+ if (substituterFailed) {
worker.failedSubstitutions++;
worker.updateProgress();
}
@@ -3691,8 +3692,6 @@ void SubstitutionGoal::tryNext()
worker.updateProgress();
- hasSubstitute = true;
-
/* Bail out early if this substituter lacks a valid
signature. LocalStore::addToStore() also checks for this, but
only after we've downloaded the path. */
@@ -3807,8 +3806,19 @@ void SubstitutionGoal::finished()
state = &SubstitutionGoal::init;
worker.waitForAWhile(shared_from_this());
return;
- } catch (Error & e) {
- printError(e.msg());
+ } catch (std::exception & e) {
+ printError(e.what());
+
+ /* Cause the parent build to fail unless --fallback is given,
+ or the substitute has disappeared. The latter case behaves
+ the same as the substitute never having existed in the
+ first place. */
+ try {
+ throw;
+ } catch (SubstituteGone &) {
+ } catch (...) {
+ substituterFailed = true;
+ }
/* Try the next substitute. */
state = &SubstitutionGoal::tryNext;