aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorregnat <rg@regnat.ovh>2021-01-26 10:48:41 +0100
committerregnat <rg@regnat.ovh>2021-02-23 08:04:03 +0100
commit6fbf3fe636bc1d9a9aba4bacb2a70191c1d6b1a7 (patch)
treea98ab8a829322f113b5b74e21c670ab416fed0ce /src
parent35205e2e922952fc0654260a07fc3191c5afc2cc (diff)
Make the build-hook work with ca derivations
- Pass it the name of the outputs rather than their output paths (as these don't exist for ca derivations) - Get the built output paths from the remote builder - Register the new received realisations
Diffstat (limited to 'src')
-rw-r--r--src/build-remote/build-remote.cc36
-rw-r--r--src/libstore/build/derivation-goal.cc9
-rw-r--r--src/libstore/realisation.hh2
-rw-r--r--src/libstore/remote-store.cc16
-rw-r--r--src/libstore/store-api.hh2
-rw-r--r--src/libstore/worker-protocol.hh2
6 files changed, 55 insertions, 12 deletions
diff --git a/src/build-remote/build-remote.cc b/src/build-remote/build-remote.cc
index 5b8ab3387..c2319a3d1 100644
--- a/src/build-remote/build-remote.cc
+++ b/src/build-remote/build-remote.cc
@@ -248,7 +248,7 @@ connected:
std::cerr << "# accept\n" << storeUri << "\n";
auto inputs = readStrings<PathSet>(source);
- auto outputs = readStrings<PathSet>(source);
+ auto wantedOutputs = readStrings<StringSet>(source);
AutoCloseFD uploadLock = openLockFile(currentLoad + "/" + escapeUri(storeUri) + ".upload-lock", true);
@@ -273,6 +273,7 @@ connected:
uploadLock = -1;
auto drv = store->readDerivation(*drvPath);
+ auto outputHashes = staticOutputHashes(*store, drv);
drv.inputSrcs = store->parseStorePathSet(inputs);
auto result = sshStore->buildDerivation(*drvPath, drv);
@@ -280,16 +281,35 @@ connected:
if (!result.success())
throw Error("build of '%s' on '%s' failed: %s", store->printStorePath(*drvPath), storeUri, result.errorMsg);
- StorePathSet missing;
- for (auto & path : outputs)
- if (!store->isValidPath(store->parseStorePath(path))) missing.insert(store->parseStorePath(path));
+ std::set<Realisation> missingRealisations;
+ StorePathSet missingPaths;
+ if (settings.isExperimentalFeatureEnabled("ca-derivations")) {
+ for (auto & outputName : wantedOutputs) {
+ auto thisOutputHash = outputHashes.at(outputName);
+ auto thisOutputId = DrvOutput{ thisOutputHash, outputName };
+ if (!store->queryRealisation(thisOutputId)) {
+ notice("Missing output %s", outputName);
+ assert(result.builtOutputs.count(thisOutputId));
+ auto newRealisation = result.builtOutputs.at(thisOutputId);
+ missingRealisations.insert(newRealisation);
+ missingPaths.insert(newRealisation.outPath);
+ }
+ }
+ } else {
+ auto outputPaths = drv.outputsAndOptPaths(*store);
+ for (auto & [outputName, hopefullyOutputPath] : outputPaths) {
+ assert(hopefullyOutputPath.second);
+ if (!store->isValidPath(*hopefullyOutputPath.second))
+ missingPaths.insert(*hopefullyOutputPath.second);
+ }
+ }
- if (!missing.empty()) {
+ if (!missingPaths.empty()) {
Activity act(*logger, lvlTalkative, actUnknown, fmt("copying outputs from '%s'", storeUri));
if (auto localStore = store.dynamic_pointer_cast<LocalStore>())
- for (auto & i : missing)
- localStore->locksHeld.insert(store->printStorePath(i)); /* FIXME: ugly */
- copyPaths(ref<Store>(sshStore), store, missing, NoRepair, NoCheckSigs, NoSubstitute);
+ for (auto & path : missingPaths)
+ localStore->locksHeld.insert(store->printStorePath(path)); /* FIXME: ugly */
+ copyPaths(ref<Store>(sshStore), store, missingPaths, NoRepair, NoCheckSigs, NoSubstitute);
}
return 0;
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index d8a89a2d0..b074410b0 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -1159,13 +1159,14 @@ 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) {
+ StringSet missingOutputs;
+ for (auto & [outputName, status] : initialOutputs) {
if (!status.known) continue;
if (buildMode != bmCheck && status.known->isValid()) continue;
- missingPaths.insert(status.known->path);
+ missingOutputs.insert(outputName);
+ /* missingPaths.insert(status.known->path); */
}
- worker_proto::write(worker.store, hook->sink, missingPaths);
+ worker_proto::write(worker.store, hook->sink, missingOutputs);
}
hook->sink = FdSink();
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..52d633372 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>> _)
{
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 6dcd43ed1..ea6389ba4 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..5e094c378 100644
--- a/src/libstore/worker-protocol.hh
+++ b/src/libstore/worker-protocol.hh
@@ -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>);