aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build/derivation-goal.cc18
-rw-r--r--src/libstore/build/entry-points.cc20
-rw-r--r--src/libstore/daemon.cc3
-rw-r--r--src/libstore/derivations.cc11
-rw-r--r--src/libstore/derivations.hh5
-rw-r--r--src/libstore/legacy-ssh-store.cc4
-rw-r--r--src/libstore/realisation.hh2
-rw-r--r--src/libstore/remote-store.cc20
-rw-r--r--src/libstore/serve-protocol.hh2
-rw-r--r--src/libstore/store-api.hh2
-rw-r--r--src/libstore/worker-protocol.hh4
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>);