diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2018-06-05T14·04+0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2018-06-05T14·04+0200 |
commit | 4ac4f675df3da01b6d814cd328dd3219dd472ac9 (patch) | |
tree | bfedf55a309956d4f7d5247be9d619c19b2717bd /src/libstore/build.cc | |
parent | 691b7582c76e05774548e84aba92ff0eb19b2589 (diff) |
Don't require --fallback to recover from disappeared binary cache NARs
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r-- | src/libstore/build.cc | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 07b533783931..8eb19205970d 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; |