diff options
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/build/derivation-goal.cc | 18 | ||||
-rw-r--r-- | src/libstore/build/entry-points.cc | 20 | ||||
-rw-r--r-- | src/libstore/daemon.cc | 3 | ||||
-rw-r--r-- | src/libstore/derivations.cc | 11 | ||||
-rw-r--r-- | src/libstore/derivations.hh | 5 | ||||
-rw-r--r-- | src/libstore/legacy-ssh-store.cc | 4 | ||||
-rw-r--r-- | src/libstore/realisation.hh | 2 | ||||
-rw-r--r-- | src/libstore/remote-store.cc | 20 | ||||
-rw-r--r-- | src/libstore/serve-protocol.hh | 2 | ||||
-rw-r--r-- | src/libstore/store-api.hh | 2 | ||||
-rw-r--r-- | src/libstore/worker-protocol.hh | 4 |
11 files changed, 79 insertions, 12 deletions
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index 33c3aeb6e..924c69fb7 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -1147,13 +1147,13 @@ HookReply DerivationGoal::tryBuildHook() /* Tell the hooks the missing outputs that have to be copied back from the remote system. */ { - StorePathSet missingPaths; - for (auto & [_, status] : initialOutputs) { - if (!status.known) continue; - if (buildMode != bmCheck && status.known->isValid()) continue; - missingPaths.insert(status.known->path); + StringSet missingOutputs; + for (auto & [outputName, status] : initialOutputs) { + // XXX: Does this include known CA outputs? + if (buildMode != bmCheck && status.known && status.known->isValid()) continue; + missingOutputs.insert(outputName); } - worker_proto::write(worker.store, hook->sink, missingPaths); + worker_proto::write(worker.store, hook->sink, missingOutputs); } hook->sink = FdSink(); @@ -2988,11 +2988,11 @@ void DerivationGoal::registerOutputs() */ if (hook) { bool allValid = true; - for (auto & i : drv->outputsAndOptPaths(worker.store)) { - if (!i.second.second || !worker.store.isValidPath(*i.second.second)) + for (auto & [outputName, outputPath] : worker.store.queryPartialDerivationOutputMap(drvPath)) { + if (!outputPath || !worker.store.isValidPath(*outputPath)) allValid = false; else - finalOutputs.insert_or_assign(i.first, *i.second.second); + finalOutputs.insert_or_assign(outputName, *outputPath); } if (allValid) return; } diff --git a/src/libstore/build/entry-points.cc b/src/libstore/build/entry-points.cc index 9f97d40ba..3a05a022c 100644 --- a/src/libstore/build/entry-points.cc +++ b/src/libstore/build/entry-points.cc @@ -58,6 +58,26 @@ BuildResult Store::buildDerivation(const StorePath & drvPath, const BasicDerivat result.status = BuildResult::MiscFailure; result.errorMsg = e.msg(); } + // XXX: Should use `goal->queryPartialDerivationOutputMap()` once it's + // extended to return the full realisation for each output + auto staticDrvOutputs = drv.outputsAndOptPaths(*this); + auto outputHashes = staticOutputHashes(*this, drv); + for (auto & [outputName, staticOutput] : staticDrvOutputs) { + auto outputId = DrvOutput{outputHashes.at(outputName), outputName}; + if (staticOutput.second) + result.builtOutputs.insert_or_assign( + outputId, + Realisation{ outputId, *staticOutput.second} + ); + if (settings.isExperimentalFeatureEnabled("ca-derivations") && !derivationHasKnownOutputPaths(drv.type())) { + auto realisation = this->queryRealisation(outputId); + if (realisation) + result.builtOutputs.insert_or_assign( + outputId, + *realisation + ); + } + } return result; } diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index ba5788b64..ba7959263 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -575,6 +575,9 @@ static void performOp(TunnelLogger * logger, ref<Store> store, auto res = store->buildDerivation(drvPath, drv, buildMode); logger->stopWork(); to << res.status << res.errorMsg; + if (GET_PROTOCOL_MINOR(clientVersion) >= 0xc) { + worker_proto::write(*store, to, res.builtOutputs); + } break; } diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 6d0742b4f..fe98182bb 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -57,6 +57,17 @@ bool derivationIsFixed(DerivationType dt) { assert(false); } +bool derivationHasKnownOutputPaths(DerivationType dt) { + switch (dt) { + case DerivationType::InputAddressed: return true; + case DerivationType::CAFixed: return true; + case DerivationType::CAFloating: return false; + case DerivationType::DeferredInputAddressed: return false; + }; + assert(false); +} + + bool derivationIsImpure(DerivationType dt) { switch (dt) { case DerivationType::InputAddressed: return false; diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 4e5985fab..061d70f69 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -94,6 +94,11 @@ bool derivationIsFixed(DerivationType); derivation is controlled separately. Never true for non-CA derivations. */ bool derivationIsImpure(DerivationType); +/* Does the derivation knows its own output paths? + * Only true when there's no floating-ca derivation involved in the closure. + */ +bool derivationHasKnownOutputPaths(DerivationType); + struct BasicDerivation { DerivationOutputs outputs; /* keyed on symbolic IDs */ diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index 253c0033e..daf78042f 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -258,7 +258,9 @@ public: if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 3) conn->from >> status.timesBuilt >> status.isNonDeterministic >> status.startTime >> status.stopTime; - + if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 6) { + status.builtOutputs = worker_proto::read(*this, conn->from, Phantom<DrvOutputs> {}); + } return status; } diff --git a/src/libstore/realisation.hh b/src/libstore/realisation.hh index 7c91d802a..fc92d3c17 100644 --- a/src/libstore/realisation.hh +++ b/src/libstore/realisation.hh @@ -33,6 +33,8 @@ struct Realisation { GENERATE_CMP(Realisation, me->id, me->outPath); }; +typedef std::map<DrvOutput, Realisation> DrvOutputs; + struct OpaquePath { StorePath path; diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index be07f02dc..0d884389a 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -12,6 +12,7 @@ #include "logging.hh" #include "callback.hh" #include "filetransfer.hh" +#include <nlohmann/json.hpp> namespace nix { @@ -49,6 +50,21 @@ void write(const Store & store, Sink & out, const ContentAddress & ca) out << renderContentAddress(ca); } +Realisation read(const Store & store, Source & from, Phantom<Realisation> _) +{ + std::string rawInput = readString(from); + return Realisation::fromJSON( + nlohmann::json::parse(rawInput), + "remote-protocol" + ); +} +void write(const Store & store, Sink & out, const Realisation & realisation) +{ out << realisation.toJSON().dump(); } + +DrvOutput read(const Store & store, Source & from, Phantom<DrvOutput> _) +{ return DrvOutput::parse(readString(from)); } +void write(const Store & store, Sink & out, const DrvOutput & drvOutput) +{ out << drvOutput.to_string(); } std::optional<StorePath> read(const Store & store, Source & from, Phantom<std::optional<StorePath>> _) { @@ -664,6 +680,10 @@ BuildResult RemoteStore::buildDerivation(const StorePath & drvPath, const BasicD unsigned int status; conn->from >> status >> res.errorMsg; res.status = (BuildResult::Status) status; + if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 0xc) { + auto builtOutputs = worker_proto::read(*this, conn->from, Phantom<DrvOutputs> {}); + res.builtOutputs = builtOutputs; + } return res; } diff --git a/src/libstore/serve-protocol.hh b/src/libstore/serve-protocol.hh index 9fae6d534..0a17387cb 100644 --- a/src/libstore/serve-protocol.hh +++ b/src/libstore/serve-protocol.hh @@ -5,7 +5,7 @@ namespace nix { #define SERVE_MAGIC_1 0x390c9deb #define SERVE_MAGIC_2 0x5452eecb -#define SERVE_PROTOCOL_VERSION 0x205 +#define SERVE_PROTOCOL_VERSION 0x206 #define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00) #define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff) diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 742cd18db..71a28eeb8 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -162,6 +162,8 @@ struct BuildResult non-determinism.) */ bool isNonDeterministic = false; + DrvOutputs builtOutputs; + /* The start/stop times of the build (or one of the rounds, if it was repeated). */ time_t startTime = 0, stopTime = 0; diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh index f2cdc7ca3..95f08bc9a 100644 --- a/src/libstore/worker-protocol.hh +++ b/src/libstore/worker-protocol.hh @@ -9,7 +9,7 @@ namespace nix { #define WORKER_MAGIC_1 0x6e697863 #define WORKER_MAGIC_2 0x6478696f -#define PROTOCOL_VERSION 0x11b +#define PROTOCOL_VERSION 0x11c #define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00) #define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff) @@ -86,6 +86,8 @@ namespace worker_proto { MAKE_WORKER_PROTO(, std::string); MAKE_WORKER_PROTO(, StorePath); MAKE_WORKER_PROTO(, ContentAddress); +MAKE_WORKER_PROTO(, Realisation); +MAKE_WORKER_PROTO(, DrvOutput); MAKE_WORKER_PROTO(template<typename T>, std::set<T>); |