From 057c6203b5337cb4833958f4a4f29f6587f4eb2f Mon Sep 17 00:00:00 2001 From: regnat Date: Mon, 7 Sep 2020 11:26:09 +0200 Subject: [PATCH] gracefully handle old daemon versions Add a fallback path in `queryPartialDerivationOutputMap` for daemons that don't support it. Also upstreams a couple methods from `SSHStore` to `RemoteStore` as this is needed to handle the fallback path. --- src/libstore/remote-store.cc | 37 ++++++++++++++++++++++++++++++++---- src/libstore/remote-store.hh | 10 ++++++++++ src/libstore/ssh-store.cc | 17 ----------------- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 8bcf92301..dc61951d3 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -1,5 +1,6 @@ #include "serialise.hh" #include "util.hh" +#include "remote-fs-accessor.hh" #include "remote-store.hh" #include "worker-protocol.hh" #include "archive.hh" @@ -479,10 +480,26 @@ StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path) std::map> RemoteStore::queryPartialDerivationOutputMap(const StorePath & path) { - auto conn(getConnection()); - conn->to << wopQueryDerivationOutputMap << printStorePath(path); - conn.processStderr(); - return worker_proto::read(*this, conn->from, Phantom>> {}); + if (GET_PROTOCOL_MINOR(getProtocol()) >= 0x16) { + auto conn(getConnection()); + conn->to << wopQueryDerivationOutputMap << printStorePath(path); + conn.processStderr(); + return worker_proto::read(*this, conn->from, Phantom>> {}); + } else { + // Fallback for old daemon versions. + // For floating-CA derivations (and their co-dependencies) this is an + // under-approximation as it only returns the paths that can be inferred + // from the derivation itself (and not the ones that are known because + // the have been built), but as old stores don't handle floating-CA + // derivations this shouldn't matter + auto derivation = readDerivation(path); + auto outputsWithOptPaths = derivation.outputsAndOptPaths(*this); + std::map> ret; + for (auto & [outputName, outputAndPath] : outputsWithOptPaths) { + ret.emplace(outputName, outputAndPath.second); + } + return ret; + } } @@ -871,6 +888,18 @@ RemoteStore::Connection::~Connection() } } +void RemoteStore::narFromPath(const StorePath & path, Sink & sink) +{ + auto conn(connections->get()); + conn->to << wopNarFromPath << printStorePath(path); + conn->processStderr(); + copyNAR(conn->from, sink); +} + +ref RemoteStore::getFSAccessor() +{ + return make_ref(ref(shared_from_this())); +} static Logger::Fields readFields(Source & from) { diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 7cf4c4d12..6f05f2197 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -131,6 +131,10 @@ protected: friend struct ConnectionHandle; + virtual ref getFSAccessor() override; + + virtual void narFromPath(const StorePath & path, Sink & sink) override; + private: std::atomic_bool failed{false}; @@ -149,6 +153,12 @@ public: bool sameMachine() override { return true; } + ref getFSAccessor() override + { return LocalFSStore::getFSAccessor(); } + + void narFromPath(const StorePath & path, Sink & sink) override + { LocalFSStore::narFromPath(path, sink); } + private: ref openConnection() override; diff --git a/src/libstore/ssh-store.cc b/src/libstore/ssh-store.cc index caae6b596..6cb97c1f1 100644 --- a/src/libstore/ssh-store.cc +++ b/src/libstore/ssh-store.cc @@ -40,10 +40,6 @@ public: bool sameMachine() override { return false; } - void narFromPath(const StorePath & path, Sink & sink) override; - - ref getFSAccessor() override; - private: struct Connection : RemoteStore::Connection @@ -68,19 +64,6 @@ private: }; }; -void SSHStore::narFromPath(const StorePath & path, Sink & sink) -{ - auto conn(connections->get()); - conn->to << wopNarFromPath << printStorePath(path); - conn->processStderr(); - copyNAR(conn->from, sink); -} - -ref SSHStore::getFSAccessor() -{ - return make_ref(ref(shared_from_this())); -} - ref SSHStore::openConnection() { auto conn = make_ref();