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.cc44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index e1d812b09..9753db7b1 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -297,7 +297,7 @@ public:
GoalPtr makeDerivationGoal(const StorePath & drvPath, const StringSet & wantedOutputs, BuildMode buildMode = bmNormal);
std::shared_ptr<DerivationGoal> makeBasicDerivationGoal(const StorePath & drvPath,
const BasicDerivation & drv, BuildMode buildMode = bmNormal);
- GoalPtr makeSubstitutionGoal(const StorePath & storePath, RepairFlag repair = NoRepair);
+ GoalPtr makeSubstitutionGoal(const StorePath & storePath, RepairFlag repair = NoRepair, std::optional<std::string> ca = std::nullopt);
/* Remove a dead goal. */
void removeGoal(GoalPtr goal);
@@ -1206,7 +1206,7 @@ void DerivationGoal::haveDerivation()
them. */
if (settings.useSubstitutes && parsedDrv->substitutesAllowed())
for (auto & i : invalidOutputs)
- addWaitee(worker.makeSubstitutionGoal(i, buildMode == bmRepair ? Repair : NoRepair));
+ addWaitee(worker.makeSubstitutionGoal(i, buildMode == bmRepair ? Repair : NoRepair, getDerivationCA(*drv)));
if (waitees.empty()) /* to prevent hang (no wake-up event) */
outputsSubstituted();
@@ -4295,8 +4295,11 @@ private:
typedef void (SubstitutionGoal::*GoalState)();
GoalState state;
+ /* Content address for recomputing store path */
+ std::optional<std::string> ca;
+
public:
- SubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair = NoRepair);
+ SubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair = NoRepair, std::optional<std::string> ca = std::nullopt);
~SubstitutionGoal();
void timedOut(Error && ex) override { abort(); };
@@ -4326,10 +4329,11 @@ public:
};
-SubstitutionGoal::SubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair)
+SubstitutionGoal::SubstitutionGoal(const StorePath & storePath, Worker & worker, RepairFlag repair, std::optional<std::string> ca)
: Goal(worker)
, storePath(storePath)
, repair(repair)
+ , ca(ca)
{
state = &SubstitutionGoal::init;
name = fmt("substitution of '%s'", worker.store.printStorePath(this->storePath));
@@ -4404,14 +4408,13 @@ void SubstitutionGoal::tryNext()
sub = subs.front();
subs.pop_front();
- if (sub->storeDir != worker.store.storeDir) {
- tryNext();
- return;
- }
+ auto subPath = storePath;
+ if (ca && (hasPrefix(*ca, "fixed:") || hasPrefix(*ca, "text:")))
+ subPath = sub->makeFixedOutputPathFromCA(storePath.name(), *ca);
try {
// FIXME: make async
- info = sub->queryPathInfo(storePath);
+ info = sub->queryPathInfo(subPath);
} catch (InvalidPath &) {
tryNext();
return;
@@ -4430,6 +4433,19 @@ void SubstitutionGoal::tryNext()
throw;
}
+ if (info->path != storePath) {
+ if (info->isContentAddressed(*sub)) {
+ auto info2 = std::const_pointer_cast<ValidPathInfo>(std::shared_ptr<const ValidPathInfo>(info));
+ info2->path = storePath;
+ info = info2;
+ } else {
+ printError("asked '%s' for '%s' but got '%s'",
+ sub->getUri(), worker.store.printStorePath(storePath), sub->printStorePath(info->path));
+ tryNext();
+ return;
+ }
+ }
+
/* Update the total expected download size. */
auto narInfo = std::dynamic_pointer_cast<const NarInfo>(info);
@@ -4518,8 +4534,12 @@ void SubstitutionGoal::tryToRun()
Activity act(*logger, actSubstitute, Logger::Fields{worker.store.printStorePath(storePath), sub->getUri()});
PushActivity pact(act.id);
+ auto subPath = storePath;
+ if (ca && (hasPrefix(*ca, "fixed:") || hasPrefix(*ca, "text:")))
+ subPath = sub->makeFixedOutputPathFromCA(storePath.name(), *ca);
+
copyStorePath(ref<Store>(sub), ref<Store>(worker.store.shared_from_this()),
- storePath, repair, sub->isTrusted ? NoCheckSigs : CheckSigs);
+ subPath, repair, sub->isTrusted ? NoCheckSigs : CheckSigs);
promise.set_value();
} catch (...) {
@@ -4652,11 +4672,11 @@ std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const StorePath
}
-GoalPtr Worker::makeSubstitutionGoal(const StorePath & path, RepairFlag repair)
+GoalPtr Worker::makeSubstitutionGoal(const StorePath & path, RepairFlag repair, std::optional<std::string> ca)
{
GoalPtr goal = substitutionGoals[path].lock(); // FIXME
if (!goal) {
- goal = std::make_shared<SubstitutionGoal>(path, *this, repair);
+ goal = std::make_shared<SubstitutionGoal>(path, *this, repair, ca);
substitutionGoals.insert_or_assign(path, goal);
wakeUp(goal);
}