Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/manual/rl-next/dropped-compat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
synopsis: "Removed support for daemons and clients older than Nix 2.0"
prs: [13951]
---

We have dropped support in the daemon worker protocol for daemons and clients that don't speak at least version 18 of the protocol. This first Nix release that supports this version is Nix 2.0, released in February 2018.
76 changes: 21 additions & 55 deletions src/libstore/daemon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<DerivedPaths>::read(*store, rconn);
BuildMode mode = bmNormal;
if (GET_PROTOCOL_MINOR(conn.protoVersion) >= 15) {
mode = WorkerProto::Serialise<BuildMode>::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<BuildMode>::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();
Expand Down Expand Up @@ -805,13 +780,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();
Expand Down Expand Up @@ -876,19 +849,12 @@ static void performOp(
auto path = store->parseStorePath(readString(conn.from));
std::shared_ptr<const ValidPathInfo> 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<const UnkeyedValidPathInfo &>(*info));
} else {
assert(GET_PROTOCOL_MINOR(conn.protoVersion) >= 17);
conn.to << 0;
}
break;
Expand Down Expand Up @@ -1063,7 +1029,7 @@ void processConnection(ref<Store> store, FdSource && from, FdSink && to, Trusted
auto [protoVersion, features] =
WorkerProto::BasicServerConnection::handshake(to, from, PROTOCOL_VERSION, WorkerProto::allFeatures);

if (protoVersion < 0x10a)
if (protoVersion < 256 + 18)
throw Error("the Nix client version is too old");

WorkerProto::BasicServerConnection conn;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,6 @@ struct WorkerProto::BasicClientConnection : WorkerProto::BasicConnection
bool * daemonException,
const StorePath & path,
std::function<void(Source &)> fun);

void importPaths(const StoreDirConfig & store, bool * daemonException, Source & source);
};

struct WorkerProto::BasicServerConnection : WorkerProto::BasicConnection
Expand Down
2 changes: 0 additions & 2 deletions src/libstore/include/nix/store/worker-protocol.hh
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ enum struct WorkerProto::Op : uint64_t {
AddIndirectRoot = 12,
SyncWithGC = 13,
FindRoots = 14,
ExportPath = 16, // obsolete
QueryDeriver = 18, // obsolete
SetOptions = 19,
CollectGarbage = 20,
Expand All @@ -162,7 +161,6 @@ enum struct WorkerProto::Op : uint64_t {
QueryFailedPaths = 24,
ClearFailedPaths = 25,
QueryPathInfo = 26,
ImportPaths = 27, // obsolete
QueryDerivationOutputNames = 28, // obsolete
QueryPathFromHashPart = 29,
QuerySubstitutablePathInfos = 30,
Expand Down
175 changes: 56 additions & 119 deletions src/libstore/remote-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 < 256 + 18)
throw Error("the Nix daemon version is too old");
conn.protoVersion = protoVersion;
conn.features = features;
} catch (SerialisationError & e) {
Expand Down Expand Up @@ -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<std::string, nix::Config::SettingInfo> 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<std::string, nix::Config::SettingInfo> 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)
Expand Down Expand Up @@ -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()
Expand All @@ -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<StorePathSet>::read(*this, *conn);
}
conn->to << WorkerProto::Op::QuerySubstitutablePaths;
WorkerProto::write(*this, *conn, paths);
conn.processStderr();
return WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
}

void RemoteStore::querySubstitutablePathInfos(const StorePathCAMap & pathsMap, SubstitutablePathInfos & infos)
Expand All @@ -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<StorePathSet>::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<size_t>(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<StorePathSet>::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<size_t>(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<StorePathSet>::read(*this, *conn);
info.downloadSize = readLongLong(conn->from);
info.narSize = readLongLong(conn->from);
}
}

Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
}
Expand Down
8 changes: 0 additions & 8 deletions src/libstore/worker-protocol-connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<StorePathSet>::read(store, *this);
assert(importedPaths.size() <= importedPaths.size());
}
} // namespace nix
Loading