diff --git a/src/libstore-tests/data/serve-protocol/handshake-to-client.bin b/src/libstore-tests/data/serve-protocol/handshake-to-client.bin index 15ba4b5e3d96..465daa532c4b 100644 Binary files a/src/libstore-tests/data/serve-protocol/handshake-to-client.bin and b/src/libstore-tests/data/serve-protocol/handshake-to-client.bin differ diff --git a/src/libstore-tests/serve-protocol.cc b/src/libstore-tests/serve-protocol.cc index 01d6058cbdee..4cd7f101b56f 100644 --- a/src/libstore-tests/serve-protocol.cc +++ b/src/libstore-tests/serve-protocol.cc @@ -20,9 +20,9 @@ struct ServeProtoTest : VersionedProtoTest { /** * For serializers that don't care about the minimum version, we - * used the oldest one: 1.0. + * used the oldest one: 2.5. */ - ServeProto::Version defaultVersion = 2 << 8 | 0; + ServeProto::Version defaultVersion = 2 << 8 | 5; }; VERSIONED_CHARACTERIZATION_TEST( diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 5451b1dd5bb1..38f3294e2bf1 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -546,47 +546,22 @@ static void performOp( break; } - case WorkerProto::Op::ExportPath: { - auto path = store->parseStorePath(readString(conn.from)); - readInt(conn.from); // obsolete - logger->startWork(); - TunnelSink sink(conn.to); - store->exportPath(path, sink); - logger->stopWork(); - conn.to << 1; - break; - } - - case WorkerProto::Op::ImportPaths: { - logger->startWork(); - TunnelSource source(conn.from, conn.to); - auto paths = store->importPaths(source, trusted ? NoCheckSigs : CheckSigs); - logger->stopWork(); - Strings paths2; - for (auto & i : paths) - paths2.push_back(store->printStorePath(i)); - conn.to << paths2; - break; - } - case WorkerProto::Op::BuildPaths: { auto drvs = WorkerProto::Serialise::read(*store, rconn); BuildMode mode = bmNormal; - if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 15) { - mode = WorkerProto::Serialise::read(*store, rconn); - - /* Repairing is not atomic, so disallowed for "untrusted" - clients. - - FIXME: layer violation in this message: the daemon code (i.e. - this file) knows whether a client/connection is trusted, but it - does not how how the client was authenticated. The mechanism - need not be getting the UID of the other end of a Unix Domain - Socket. - */ - if (mode == bmRepair && !trusted) - throw Error("repairing is not allowed because you are not in 'trusted-users'"); - } + mode = WorkerProto::Serialise::read(*store, rconn); + + /* Repairing is not atomic, so disallowed for "untrusted" + clients. + + FIXME: layer violation in this message: the daemon code (i.e. + this file) knows whether a client/connection is trusted, but it + does not how how the client was authenticated. The mechanism + need not be getting the UID of the other end of a Unix Domain + Socket. + */ + if (mode == bmRepair && !trusted) + throw Error("repairing is not allowed because you are not in 'trusted-users'"); logger->startWork(); store->buildPaths(drvs, mode); logger->stopWork(); @@ -806,13 +781,11 @@ static void performOp( clientSettings.buildCores = readInt(conn.from); clientSettings.useSubstitutes = readInt(conn.from); - if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 12) { - unsigned int n = readInt(conn.from); - for (unsigned int i = 0; i < n; i++) { - auto name = readString(conn.from); - auto value = readString(conn.from); - clientSettings.overrides.emplace(name, value); - } + unsigned int n = readInt(conn.from); + for (unsigned int i = 0; i < n; i++) { + auto name = readString(conn.from); + auto value = readString(conn.from); + clientSettings.overrides.emplace(name, value); } logger->startWork(); @@ -877,19 +850,12 @@ static void performOp( auto path = store->parseStorePath(readString(conn.from)); std::shared_ptr info; logger->startWork(); - try { - info = store->queryPathInfo(path); - } catch (InvalidPath &) { - if (GET_PROTOCOL_MINOR(conn.protoVersion) < 17) - throw; - } + info = store->queryPathInfo(path); logger->stopWork(); if (info) { - if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 17) - conn.to << 1; + conn.to << 1; WorkerProto::write(*store, wconn, static_cast(*info)); } else { - assert(GET_PROTOCOL_MINOR(conn.protoVersion) >= 17); conn.to << 0; } break; @@ -1064,7 +1030,7 @@ void processConnection(ref store, FdSource && from, FdSink && to, Trusted auto [protoVersion, features] = WorkerProto::BasicServerConnection::handshake(to, from, PROTOCOL_VERSION, WorkerProto::allFeatures); - if (protoVersion < 0x10a) + if (protoVersion < MINIMUM_PROTOCOL_VERSION) throw Error("the Nix client version is too old"); WorkerProto::BasicServerConnection conn; diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index d0e2989681a3..61b0ae398c34 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -65,7 +65,7 @@ struct DummyStore : virtual Store /** * The dummy store is incapable of *not* trusting! :) */ - virtual std::optional isTrustedClient() override + std::optional isTrustedClient() override { return Trusted; } @@ -80,7 +80,7 @@ struct DummyStore : virtual Store unsupported("addToStore"); } - virtual StorePath addToStoreFromDump( + StorePath addToStoreFromDump( Source & dump, std::string_view name, FileSerialisationMethod dumpMethod = FileSerialisationMethod::NixArchive, @@ -103,7 +103,7 @@ struct DummyStore : virtual Store callback(nullptr); } - virtual ref getFSAccessor(bool requireValidPath) override + ref getFSAccessor(bool requireValidPath) override { return makeEmptySourceAccessor(); } diff --git a/src/libstore/export-import.cc b/src/libstore/export-import.cc index 13444deb256a..a343b5837db4 100644 --- a/src/libstore/export-import.cc +++ b/src/libstore/export-import.cc @@ -1,3 +1,4 @@ +#include "nix/store/export-import.hh" #include "nix/util/serialise.hh" #include "nix/store/store-api.hh" #include "nix/util/archive.hh" @@ -8,27 +9,14 @@ namespace nix { -void Store::exportPaths(const StorePathSet & paths, Sink & sink) +static void exportPath(Store & store, const StorePath & path, Sink & sink) { - auto sorted = topoSortPaths(paths); - std::reverse(sorted.begin(), sorted.end()); - - for (auto & path : sorted) { - sink << 1; - exportPath(path, sink); - } - - sink << 0; -} - -void Store::exportPath(const StorePath & path, Sink & sink) -{ - auto info = queryPathInfo(path); + auto info = store.queryPathInfo(path); HashSink hashSink(HashAlgorithm::SHA256); TeeSink teeSink(sink, hashSink); - narFromPath(path, teeSink); + store.narFromPath(path, teeSink); /* Refuse to export paths that have changed. This prevents filesystem corruption from spreading to other machines. @@ -37,16 +25,29 @@ void Store::exportPath(const StorePath & path, Sink & sink) if (hash != info->narHash && info->narHash != Hash(info->narHash.algo)) throw Error( "hash of path '%s' has changed from '%s' to '%s'!", - printStorePath(path), + store.printStorePath(path), info->narHash.to_string(HashFormat::Nix32, true), hash.to_string(HashFormat::Nix32, true)); - teeSink << exportMagic << printStorePath(path); - CommonProto::write(*this, CommonProto::WriteConn{.to = teeSink}, info->references); - teeSink << (info->deriver ? printStorePath(*info->deriver) : "") << 0; + teeSink << exportMagic << store.printStorePath(path); + CommonProto::write(store, CommonProto::WriteConn{.to = teeSink}, info->references); + teeSink << (info->deriver ? store.printStorePath(*info->deriver) : "") << 0; +} + +void exportPaths(Store & store, const StorePathSet & paths, Sink & sink) +{ + auto sorted = store.topoSortPaths(paths); + std::reverse(sorted.begin(), sorted.end()); + + for (auto & path : sorted) { + sink << 1; + exportPath(store, path, sink); + } + + sink << 0; } -StorePaths Store::importPaths(Source & source, CheckSigsFlag checkSigs) +StorePaths importPaths(Store & store, Source & source, CheckSigsFlag checkSigs) { StorePaths res; while (true) { @@ -66,17 +67,17 @@ StorePaths Store::importPaths(Source & source, CheckSigsFlag checkSigs) if (magic != exportMagic) throw Error("Nix archive cannot be imported; wrong format"); - auto path = parseStorePath(readString(source)); + auto path = store.parseStorePath(readString(source)); // Activity act(*logger, lvlInfo, "importing path '%s'", info.path); - auto references = CommonProto::Serialise::read(*this, CommonProto::ReadConn{.from = source}); + auto references = CommonProto::Serialise::read(store, CommonProto::ReadConn{.from = source}); auto deriver = readString(source); auto narHash = hashString(HashAlgorithm::SHA256, saved.s); ValidPathInfo info{path, narHash}; if (deriver != "") - info.deriver = parseStorePath(deriver); + info.deriver = store.parseStorePath(deriver); info.references = references; info.narSize = saved.s.size(); @@ -86,7 +87,7 @@ StorePaths Store::importPaths(Source & source, CheckSigsFlag checkSigs) // Can't use underlying source, which would have been exhausted auto source = StringSource(saved.s); - addToStore(info, source, NoRepair, checkSigs); + store.addToStore(info, source, NoRepair, checkSigs); res.push_back(info.path); } diff --git a/src/libstore/include/nix/store/export-import.hh b/src/libstore/include/nix/store/export-import.hh new file mode 100644 index 000000000000..15092202f1f6 --- /dev/null +++ b/src/libstore/include/nix/store/export-import.hh @@ -0,0 +1,24 @@ +#pragma once + +#include "nix/store/store-api.hh" + +namespace nix { + +/** + * Magic header of exportPath() output (obsolete). + */ +const uint32_t exportMagic = 0x4558494e; + +/** + * Export multiple paths in the format expected by `nix-store + * --import`. The paths will be sorted topologically. + */ +void exportPaths(Store & store, const StorePathSet & paths, Sink & sink); + +/** + * Import a sequence of NAR dumps created by `exportPaths()` into the + * Nix store. + */ +StorePaths importPaths(Store & store, Source & source, CheckSigsFlag checkSigs = CheckSigs); + +} // namespace nix diff --git a/src/libstore/include/nix/store/legacy-ssh-store.hh b/src/libstore/include/nix/store/legacy-ssh-store.hh index 91e021433e5a..ac31506d021f 100644 --- a/src/libstore/include/nix/store/legacy-ssh-store.hh +++ b/src/libstore/include/nix/store/legacy-ssh-store.hh @@ -179,12 +179,6 @@ public: */ StorePathSet queryValidPaths(const StorePathSet & paths, bool lock, SubstituteFlag maybeSubstitute = NoSubstitute); - /** - * Just exists because this is exactly what Hydra was doing, and we - * don't yet want an algorithmic change. - */ - void addMultipleToStoreLegacy(Store & srcStore, const StorePathSet & paths); - void connect() override; unsigned int getProtocol() override; diff --git a/src/libstore/include/nix/store/meson.build b/src/libstore/include/nix/store/meson.build index 2c642ff6cf4d..d02fe0b5d854 100644 --- a/src/libstore/include/nix/store/meson.build +++ b/src/libstore/include/nix/store/meson.build @@ -34,6 +34,7 @@ headers = [ config_pub_h ] + files( 'derived-path-map.hh', 'derived-path.hh', 'downstream-placeholder.hh', + 'export-import.hh', 'filetransfer.hh', 'gc-store.hh', 'globals.hh', diff --git a/src/libstore/include/nix/store/serve-protocol-connection.hh b/src/libstore/include/nix/store/serve-protocol-connection.hh index fa50132c88be..873277db9021 100644 --- a/src/libstore/include/nix/store/serve-protocol-connection.hh +++ b/src/libstore/include/nix/store/serve-protocol-connection.hh @@ -82,8 +82,6 @@ struct ServeProto::BasicClientConnection BuildResult getBuildDerivationResponse(const StoreDirConfig & store); void narFromPath(const StoreDirConfig & store, const StorePath & path, std::function fun); - - void importPaths(const StoreDirConfig & store, std::function fun); }; struct ServeProto::BasicServerConnection diff --git a/src/libstore/include/nix/store/serve-protocol.hh b/src/libstore/include/nix/store/serve-protocol.hh index c8f3560d181f..5cb8a89a8d3c 100644 --- a/src/libstore/include/nix/store/serve-protocol.hh +++ b/src/libstore/include/nix/store/serve-protocol.hh @@ -108,8 +108,8 @@ enum struct ServeProto::Command : uint64_t { QueryValidPaths = 1, QueryPathInfos = 2, DumpStorePath = 3, - ImportPaths = 4, - ExportPaths = 5, + // ImportPaths = 4, // removed + // ExportPaths = 5, // removed BuildPaths = 6, QueryClosure = 7, BuildDerivation = 8, diff --git a/src/libstore/include/nix/store/store-api.hh b/src/libstore/include/nix/store/store-api.hh index 7922216f1359..79fc45e4d7f8 100644 --- a/src/libstore/include/nix/store/store-api.hh +++ b/src/libstore/include/nix/store/store-api.hh @@ -53,11 +53,6 @@ enum CheckSigsFlag : bool { NoCheckSigs = false, CheckSigs = true }; enum SubstituteFlag : bool { NoSubstitute = false, Substitute = true }; -/** - * Magic header of exportPath() output (obsolete). - */ -const uint32_t exportMagic = 0x4558494e; - enum BuildMode : uint8_t { bmNormal, bmRepair, bmCheck }; enum TrustedFlag : bool { NotTrusted = false, Trusted = true }; @@ -818,21 +813,6 @@ public: */ StorePaths topoSortPaths(const StorePathSet & paths); - /** - * Export multiple paths in the format expected by ‘nix-store - * --import’. - */ - void exportPaths(const StorePathSet & paths, Sink & sink); - - void exportPath(const StorePath & path, Sink & sink); - - /** - * Import a sequence of NAR dumps created by exportPaths() into the - * Nix store. Optionally, the contents of the NARs are preloaded - * into the specified FS accessor to speed up subsequent access. - */ - StorePaths importPaths(Source & source, CheckSigsFlag checkSigs = CheckSigs); - struct Stats { std::atomic narInfoRead{0}; diff --git a/src/libstore/include/nix/store/worker-protocol-connection.hh b/src/libstore/include/nix/store/worker-protocol-connection.hh index 73dd507192cf..31436395fe79 100644 --- a/src/libstore/include/nix/store/worker-protocol-connection.hh +++ b/src/libstore/include/nix/store/worker-protocol-connection.hh @@ -130,8 +130,6 @@ struct WorkerProto::BasicClientConnection : WorkerProto::BasicConnection bool * daemonException, const StorePath & path, std::function fun); - - void importPaths(const StoreDirConfig & store, bool * daemonException, Source & source); }; struct WorkerProto::BasicServerConnection : WorkerProto::BasicConnection diff --git a/src/libstore/include/nix/store/worker-protocol.hh b/src/libstore/include/nix/store/worker-protocol.hh index c7f8d589100b..6ae5fdcbc293 100644 --- a/src/libstore/include/nix/store/worker-protocol.hh +++ b/src/libstore/include/nix/store/worker-protocol.hh @@ -13,6 +13,7 @@ namespace nix { /* Note: you generally shouldn't change the protocol version. Define a new `WorkerProto::Feature` instead. */ #define PROTOCOL_VERSION (1 << 8 | 38) +#define MINIMUM_PROTOCOL_VERSION (1 << 8 | 18) #define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00) #define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff) @@ -152,7 +153,7 @@ enum struct WorkerProto::Op : uint64_t { AddIndirectRoot = 12, SyncWithGC = 13, FindRoots = 14, - ExportPath = 16, // obsolete + // ExportPath = 16, // removed QueryDeriver = 18, // obsolete SetOptions = 19, CollectGarbage = 20, @@ -162,7 +163,7 @@ enum struct WorkerProto::Op : uint64_t { QueryFailedPaths = 24, ClearFailedPaths = 25, QueryPathInfo = 26, - ImportPaths = 27, // obsolete + // ImportPaths = 27, // removed QueryDerivationOutputNames = 28, // obsolete QueryPathFromHashPart = 29, QuerySubstitutablePathInfos = 30, diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index 0e9ee35bf3af..f935de2069b6 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -105,9 +105,6 @@ std::map LegacySSHStore::queryPathInfosUncached { auto conn(connections->get()); - /* No longer support missing NAR hash */ - assert(GET_PROTOCOL_MINOR(conn->remoteVersion) >= 4); - debug( "querying remote host '%s' for info on '%s'", config->authority.host, @@ -152,40 +149,21 @@ void LegacySSHStore::addToStore(const ValidPathInfo & info, Source & source, Rep auto conn(connections->get()); - if (GET_PROTOCOL_MINOR(conn->remoteVersion) >= 5) { - - conn->to << ServeProto::Command::AddToStoreNar << printStorePath(info.path) - << (info.deriver ? printStorePath(*info.deriver) : "") - << info.narHash.to_string(HashFormat::Base16, false); - ServeProto::write(*this, *conn, info.references); - conn->to << info.registrationTime << info.narSize << info.ultimate << info.sigs - << renderContentAddress(info.ca); - try { - copyNAR(source, conn->to); - } catch (...) { - conn->good = false; - throw; - } - conn->to.flush(); - - if (readInt(conn->from) != 1) - throw Error( - "failed to add path '%s' to remote host '%s'", printStorePath(info.path), config->authority.host); - - } else { - - conn->importPaths(*this, [&](Sink & sink) { - try { - copyNAR(source, sink); - } catch (...) { - conn->good = false; - throw; - } - sink << exportMagic << printStorePath(info.path); - ServeProto::write(*this, *conn, info.references); - sink << (info.deriver ? printStorePath(*info.deriver) : "") << 0 << 0; - }); + conn->to << ServeProto::Command::AddToStoreNar << printStorePath(info.path) + << (info.deriver ? printStorePath(*info.deriver) : "") + << info.narHash.to_string(HashFormat::Base16, false); + ServeProto::write(*this, *conn, info.references); + conn->to << info.registrationTime << info.narSize << info.ultimate << info.sigs << renderContentAddress(info.ca); + try { + copyNAR(source, conn->to); + } catch (...) { + conn->good = false; + throw; } + conn->to.flush(); + + if (readInt(conn->from) != 1) + throw Error("failed to add path '%s' to remote host '%s'", printStorePath(info.path), config->authority.host); } void LegacySSHStore::narFromPath(const StorePath & path, Sink & sink) @@ -302,22 +280,6 @@ StorePathSet LegacySSHStore::queryValidPaths(const StorePathSet & paths, bool lo return conn->queryValidPaths(*this, lock, paths, maybeSubstitute); } -void LegacySSHStore::addMultipleToStoreLegacy(Store & srcStore, const StorePathSet & paths) -{ - auto conn(connections->get()); - conn->to << ServeProto::Command::ImportPaths; - try { - srcStore.exportPaths(paths, conn->to); - } catch (...) { - conn->good = false; - throw; - } - conn->to.flush(); - - if (readInt(conn->from) != 1) - throw Error("remote machine failed to import closure"); -} - void LegacySSHStore::connect() { auto conn(connections->get()); diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 8c0a815d87cc..1cfa5ffb0a33 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -73,6 +73,8 @@ void RemoteStore::initConnection(Connection & conn) try { auto [protoVersion, features] = WorkerProto::BasicClientConnection::handshake(conn.to, tee, PROTOCOL_VERSION, WorkerProto::allFeatures); + if (protoVersion < MINIMUM_PROTOCOL_VERSION) + throw Error("the Nix daemon version is too old"); conn.protoVersion = protoVersion; conn.features = features; } catch (SerialisationError & e) { @@ -109,24 +111,22 @@ void RemoteStore::setOptions(Connection & conn) << 0 /* obsolete print build trace */ << settings.buildCores << settings.useSubstitutes; - if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 12) { - std::map overrides; - settings.getSettings(overrides, true); // libstore settings - fileTransferSettings.getSettings(overrides, true); - overrides.erase(settings.keepFailed.name); - overrides.erase(settings.keepGoing.name); - overrides.erase(settings.tryFallback.name); - overrides.erase(settings.maxBuildJobs.name); - overrides.erase(settings.maxSilentTime.name); - overrides.erase(settings.buildCores.name); - overrides.erase(settings.useSubstitutes.name); - overrides.erase(loggerSettings.showTrace.name); - overrides.erase(experimentalFeatureSettings.experimentalFeatures.name); - overrides.erase("plugin-files"); - conn.to << overrides.size(); - for (auto & i : overrides) - conn.to << i.first << i.second.value; - } + std::map overrides; + settings.getSettings(overrides, true); // libstore settings + fileTransferSettings.getSettings(overrides, true); + overrides.erase(settings.keepFailed.name); + overrides.erase(settings.keepGoing.name); + overrides.erase(settings.tryFallback.name); + overrides.erase(settings.maxBuildJobs.name); + overrides.erase(settings.maxSilentTime.name); + overrides.erase(settings.buildCores.name); + overrides.erase(settings.useSubstitutes.name); + overrides.erase(loggerSettings.showTrace.name); + overrides.erase(experimentalFeatureSettings.experimentalFeatures.name); + overrides.erase("plugin-files"); + conn.to << overrides.size(); + for (auto & i : overrides) + conn.to << i.first << i.second.value; auto ex = conn.processStderrReturn(); if (ex) @@ -167,15 +167,7 @@ bool RemoteStore::isValidPathUncached(const StorePath & path) StorePathSet RemoteStore::queryValidPaths(const StorePathSet & paths, SubstituteFlag maybeSubstitute) { auto conn(getConnection()); - if (GET_PROTOCOL_MINOR(conn->protoVersion) < 12) { - StorePathSet res; - for (auto & i : paths) - if (isValidPath(i)) - res.insert(i); - return res; - } else { - return conn->queryValidPaths(*this, &conn.daemonException, paths, maybeSubstitute); - } + return conn->queryValidPaths(*this, &conn.daemonException, paths, maybeSubstitute); } StorePathSet RemoteStore::queryAllValidPaths() @@ -189,21 +181,10 @@ StorePathSet RemoteStore::queryAllValidPaths() StorePathSet RemoteStore::querySubstitutablePaths(const StorePathSet & paths) { auto conn(getConnection()); - if (GET_PROTOCOL_MINOR(conn->protoVersion) < 12) { - StorePathSet res; - for (auto & i : paths) { - conn->to << WorkerProto::Op::HasSubstitutes << printStorePath(i); - conn.processStderr(); - if (readInt(conn->from)) - res.insert(i); - } - return res; - } else { - conn->to << WorkerProto::Op::QuerySubstitutablePaths; - WorkerProto::write(*this, *conn, paths); - conn.processStderr(); - return WorkerProto::Serialise::read(*this, *conn); - } + conn->to << WorkerProto::Op::QuerySubstitutablePaths; + WorkerProto::write(*this, *conn, paths); + conn.processStderr(); + return WorkerProto::Serialise::read(*this, *conn); } void RemoteStore::querySubstitutablePathInfos(const StorePathCAMap & pathsMap, SubstitutablePathInfos & infos) @@ -213,45 +194,24 @@ void RemoteStore::querySubstitutablePathInfos(const StorePathCAMap & pathsMap, S auto conn(getConnection()); - if (GET_PROTOCOL_MINOR(conn->protoVersion) < 12) { - - for (auto & i : pathsMap) { - SubstitutablePathInfo info; - conn->to << WorkerProto::Op::QuerySubstitutablePathInfo << printStorePath(i.first); - conn.processStderr(); - unsigned int reply = readInt(conn->from); - if (reply == 0) - continue; - auto deriver = readString(conn->from); - if (deriver != "") - info.deriver = parseStorePath(deriver); - info.references = WorkerProto::Serialise::read(*this, *conn); - info.downloadSize = readLongLong(conn->from); - info.narSize = readLongLong(conn->from); - infos.insert_or_assign(i.first, std::move(info)); - } - - } else { - - conn->to << WorkerProto::Op::QuerySubstitutablePathInfos; - if (GET_PROTOCOL_MINOR(conn->protoVersion) < 22) { - StorePathSet paths; - for (auto & path : pathsMap) - paths.insert(path.first); - WorkerProto::write(*this, *conn, paths); - } else - WorkerProto::write(*this, *conn, pathsMap); - conn.processStderr(); - size_t count = readNum(conn->from); - for (size_t n = 0; n < count; n++) { - SubstitutablePathInfo & info(infos[parseStorePath(readString(conn->from))]); - auto deriver = readString(conn->from); - if (deriver != "") - info.deriver = parseStorePath(deriver); - info.references = WorkerProto::Serialise::read(*this, *conn); - info.downloadSize = readLongLong(conn->from); - info.narSize = readLongLong(conn->from); - } + conn->to << WorkerProto::Op::QuerySubstitutablePathInfos; + if (GET_PROTOCOL_MINOR(conn->protoVersion) < 22) { + StorePathSet paths; + for (auto & path : pathsMap) + paths.insert(path.first); + WorkerProto::write(*this, *conn, paths); + } else + WorkerProto::write(*this, *conn, pathsMap); + conn.processStderr(); + size_t count = readNum(conn->from); + for (size_t n = 0; n < count; n++) { + SubstitutablePathInfo & info(infos[parseStorePath(readString(conn->from))]); + auto deriver = readString(conn->from); + if (deriver != "") + info.deriver = parseStorePath(deriver); + info.references = WorkerProto::Serialise::read(*this, *conn); + info.downloadSize = readLongLong(conn->from); + info.narSize = readLongLong(conn->from); } } @@ -466,36 +426,20 @@ void RemoteStore::addToStore(const ValidPathInfo & info, Source & source, Repair { auto conn(getConnection()); - if (GET_PROTOCOL_MINOR(conn->protoVersion) < 18) { - auto source2 = sinkToSource([&](Sink & sink) { - sink << 1 // == path follows - ; - copyNAR(source, sink); - sink << exportMagic << printStorePath(info.path); - WorkerProto::write(*this, *conn, info.references); - sink << (info.deriver ? printStorePath(*info.deriver) : "") << 0 // == no legacy signature - << 0 // == no path follows - ; - }); - conn->importPaths(*this, &conn.daemonException, *source2); - } - - else { - conn->to << WorkerProto::Op::AddToStoreNar << printStorePath(info.path) - << (info.deriver ? printStorePath(*info.deriver) : "") - << info.narHash.to_string(HashFormat::Base16, false); - WorkerProto::write(*this, *conn, info.references); - conn->to << info.registrationTime << info.narSize << info.ultimate << info.sigs << renderContentAddress(info.ca) - << repair << !checkSigs; - - if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 23) { - conn.withFramedSink([&](Sink & sink) { copyNAR(source, sink); }); - } else if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 21) { - conn.processStderr(0, &source); - } else { - copyNAR(source, conn->to); - conn.processStderr(0, nullptr); - } + conn->to << WorkerProto::Op::AddToStoreNar << printStorePath(info.path) + << (info.deriver ? printStorePath(*info.deriver) : "") + << info.narHash.to_string(HashFormat::Base16, false); + WorkerProto::write(*this, *conn, info.references); + conn->to << info.registrationTime << info.narSize << info.ultimate << info.sigs << renderContentAddress(info.ca) + << repair << !checkSigs; + + if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 23) { + conn.withFramedSink([&](Sink & sink) { copyNAR(source, sink); }); + } else if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 21) { + conn.processStderr(0, &source); + } else { + copyNAR(source, conn->to); + conn.processStderr(0, nullptr); } } @@ -618,15 +562,8 @@ void RemoteStore::buildPaths( auto conn(getConnection()); conn->to << WorkerProto::Op::BuildPaths; - assert(GET_PROTOCOL_MINOR(conn->protoVersion) >= 13); WorkerProto::write(*this, *conn, drvPaths); - if (GET_PROTOCOL_MINOR(conn->protoVersion) >= 15) - conn->to << buildMode; - else - /* Old daemons did not take a 'buildMode' parameter, so we - need to validate it here on the client side. */ - if (buildMode != bmNormal) - throw Error("repairing or checking is not supported when building through the Nix daemon"); + conn->to << buildMode; conn.processStderr(); readInt(conn->from); } diff --git a/src/libstore/serve-protocol-connection.cc b/src/libstore/serve-protocol-connection.cc index 908994f4e9ae..a90b104a68e0 100644 --- a/src/libstore/serve-protocol-connection.cc +++ b/src/libstore/serve-protocol-connection.cc @@ -15,7 +15,7 @@ ServeProto::Version ServeProto::BasicClientConnection::handshake( if (magic != SERVE_MAGIC_2) throw Error("'nix-store --serve' protocol mismatch from '%s'", host); auto remoteVersion = readInt(from); - if (GET_PROTOCOL_MAJOR(remoteVersion) != 0x200) + if (GET_PROTOCOL_MAJOR(remoteVersion) != 0x200 || GET_PROTOCOL_MINOR(remoteVersion) < 5) throw Error("unsupported 'nix-store --serve' protocol version on '%s'", host); return std::min(remoteVersion, localVersion); } @@ -93,14 +93,4 @@ void ServeProto::BasicClientConnection::narFromPath( fun(from); } -void ServeProto::BasicClientConnection::importPaths(const StoreDirConfig & store, std::function fun) -{ - to << ServeProto::Command::ImportPaths; - fun(to); - to.flush(); - - if (readInt(from) != 1) - throw Error("remote machine failed to import closure"); -} - } // namespace nix diff --git a/src/libstore/worker-protocol-connection.cc b/src/libstore/worker-protocol-connection.cc index 987d0c8dde8b..8a37662904d5 100644 --- a/src/libstore/worker-protocol-connection.cc +++ b/src/libstore/worker-protocol-connection.cc @@ -313,12 +313,4 @@ void WorkerProto::BasicClientConnection::narFromPath( fun(from); } -void WorkerProto::BasicClientConnection::importPaths( - const StoreDirConfig & store, bool * daemonException, Source & source) -{ - to << WorkerProto::Op::ImportPaths; - processStderr(daemonException, 0, &source); - auto importedPaths = WorkerProto::Serialise::read(store, *this); - assert(importedPaths.size() <= importedPaths.size()); -} } // namespace nix diff --git a/src/nix/nix-store/nix-store.cc b/src/nix/nix-store/nix-store.cc index 4191ea0d6fc9..5f85e06f0b27 100644 --- a/src/nix/nix-store/nix-store.cc +++ b/src/nix/nix-store/nix-store.cc @@ -14,6 +14,7 @@ #include "nix/util/posix-source-accessor.hh" #include "nix/store/globals.hh" #include "nix/store/path-with-outputs.hh" +#include "nix/store/export-import.hh" #include "man-pages.hh" @@ -774,7 +775,7 @@ static void opExport(Strings opFlags, Strings opArgs) paths.insert(store->followLinksToStorePath(i)); FdSink sink(getStandardOutput()); - store->exportPaths(paths, sink); + exportPaths(*store, paths, sink); sink.flush(); } @@ -787,7 +788,7 @@ static void opImport(Strings opFlags, Strings opArgs) throw UsageError("no arguments expected"); FdSource source(STDIN_FILENO); - auto paths = store->importPaths(source, NoCheckSigs); + auto paths = importPaths(*store, source, NoCheckSigs); for (auto & i : paths) cout << fmt("%s\n", store->printStorePath(i)) << std::flush; @@ -985,20 +986,6 @@ static void opServe(Strings opFlags, Strings opArgs) store->narFromPath(store->parseStorePath(readString(in)), out); break; - case ServeProto::Command::ImportPaths: { - if (!writeAllowed) - throw Error("importing paths is not allowed"); - store->importPaths(in, NoCheckSigs); // FIXME: should we skip sig checking? - out << 1; // indicate success - break; - } - - case ServeProto::Command::ExportPaths: { - readInt(in); // obsolete - store->exportPaths(ServeProto::Serialise::read(*store, rconn), out); - break; - } - case ServeProto::Command::BuildPaths: { if (!writeAllowed) diff --git a/src/perl/lib/Nix/Store.xs b/src/perl/lib/Nix/Store.xs index edcb6d72a5eb..7aa918ba0c69 100644 --- a/src/perl/lib/Nix/Store.xs +++ b/src/perl/lib/Nix/Store.xs @@ -11,6 +11,7 @@ #include "nix/store/globals.hh" #include "nix/store/store-open.hh" #include "nix/util/posix-source-accessor.hh" +#include "nix/store/export-import.hh" #include #include @@ -233,7 +234,7 @@ StoreWrapper::exportPaths(int fd, ...) StorePathSet paths; for (int n = 2; n < items; ++n) paths.insert(THIS->store->parseStorePath(SvPV_nolen(ST(n)))); FdSink sink(fd); - THIS->store->exportPaths(paths, sink); + exportPaths(*THIS->store, paths, sink); } catch (Error & e) { croak("%s", e.what()); } @@ -244,7 +245,7 @@ StoreWrapper::importPaths(int fd, int dontCheckSigs) PPCODE: try { FdSource source(fd); - THIS->store->importPaths(source, dontCheckSigs ? NoCheckSigs : CheckSigs); + importPaths(*THIS->store, source, dontCheckSigs ? NoCheckSigs : CheckSigs); } catch (Error & e) { croak("%s", e.what()); }