forked from lix-project/lix
Merge changes from topic "protocol" into main
* changes: libstore client: remove remaining dead code libstore: refuse to serialise ancient protocols libstore client: remove support for <2.3 clients libstore daemon: remove very old protocol support (<2.3) Delete old ValidPathInfo test, fix UnkeyedValidPathInfo Set up minimum protocol version
This commit is contained in:
commit
ce2b48aa41
|
@ -47,10 +47,15 @@ struct TunnelLogger : public Logger
|
||||||
|
|
||||||
Sync<State> state_;
|
Sync<State> state_;
|
||||||
|
|
||||||
WorkerProto::Version clientVersion;
|
/**
|
||||||
|
* Worker protocol version of the other side. May be newer than this daemon.
|
||||||
|
*/
|
||||||
|
const WorkerProto::Version clientVersion;
|
||||||
|
|
||||||
TunnelLogger(FdSink & to, WorkerProto::Version clientVersion)
|
TunnelLogger(FdSink & to, WorkerProto::Version clientVersion)
|
||||||
: to(to), clientVersion(clientVersion) { }
|
: to(to), clientVersion(clientVersion) {
|
||||||
|
assert(clientVersion >= MIN_SUPPORTED_WORKER_PROTO_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
void enqueueMsg(const std::string & s)
|
void enqueueMsg(const std::string & s)
|
||||||
{
|
{
|
||||||
|
@ -129,12 +134,6 @@ struct TunnelLogger : public Logger
|
||||||
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
|
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
|
||||||
const std::string & s, const Fields & fields, ActivityId parent) override
|
const std::string & s, const Fields & fields, ActivityId parent) override
|
||||||
{
|
{
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) < 20) {
|
|
||||||
if (!s.empty())
|
|
||||||
log(lvl, s + "...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringSink buf;
|
StringSink buf;
|
||||||
buf << STDERR_START_ACTIVITY << act << lvl << type << s << fields << parent;
|
buf << STDERR_START_ACTIVITY << act << lvl << type << s << fields << parent;
|
||||||
enqueueMsg(buf.s);
|
enqueueMsg(buf.s);
|
||||||
|
@ -142,7 +141,6 @@ struct TunnelLogger : public Logger
|
||||||
|
|
||||||
void stopActivity(ActivityId act) override
|
void stopActivity(ActivityId act) override
|
||||||
{
|
{
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) < 20) return;
|
|
||||||
StringSink buf;
|
StringSink buf;
|
||||||
buf << STDERR_STOP_ACTIVITY << act;
|
buf << STDERR_STOP_ACTIVITY << act;
|
||||||
enqueueMsg(buf.s);
|
enqueueMsg(buf.s);
|
||||||
|
@ -150,7 +148,6 @@ struct TunnelLogger : public Logger
|
||||||
|
|
||||||
void result(ActivityId act, ResultType type, const Fields & fields) override
|
void result(ActivityId act, ResultType type, const Fields & fields) override
|
||||||
{
|
{
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) < 20) return;
|
|
||||||
StringSink buf;
|
StringSink buf;
|
||||||
buf << STDERR_RESULT << act << type << fields;
|
buf << STDERR_RESULT << act << type << fields;
|
||||||
enqueueMsg(buf.s);
|
enqueueMsg(buf.s);
|
||||||
|
@ -267,14 +264,8 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
||||||
TrustedFlag trusted, RecursiveFlag recursive, WorkerProto::Version clientVersion,
|
TrustedFlag trusted, RecursiveFlag recursive, WorkerProto::Version clientVersion,
|
||||||
Source & from, BufferedSink & to, WorkerProto::Op op)
|
Source & from, BufferedSink & to, WorkerProto::Op op)
|
||||||
{
|
{
|
||||||
WorkerProto::ReadConn rconn {
|
WorkerProto::ReadConn rconn{from, clientVersion};
|
||||||
.from = from,
|
WorkerProto::WriteConn wconn{to, clientVersion};
|
||||||
.version = clientVersion,
|
|
||||||
};
|
|
||||||
WorkerProto::WriteConn wconn {
|
|
||||||
.to = to,
|
|
||||||
.version = clientVersion,
|
|
||||||
};
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
||||||
|
@ -527,22 +518,19 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
||||||
|
|
||||||
case WorkerProto::Op::BuildPaths: {
|
case WorkerProto::Op::BuildPaths: {
|
||||||
auto drvs = WorkerProto::Serialise<DerivedPaths>::read(*store, rconn);
|
auto drvs = WorkerProto::Serialise<DerivedPaths>::read(*store, rconn);
|
||||||
BuildMode mode = bmNormal;
|
BuildMode mode = buildModeFromInteger(readInt(from));
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 15) {
|
|
||||||
mode = buildModeFromInteger(readInt(from));
|
|
||||||
|
|
||||||
/* Repairing is not atomic, so disallowed for "untrusted"
|
/* Repairing is not atomic, so disallowed for "untrusted"
|
||||||
clients.
|
clients.
|
||||||
|
|
||||||
FIXME: layer violation in this message: the daemon code (i.e.
|
FIXME: layer violation in this message: the daemon code (i.e.
|
||||||
this file) knows whether a client/connection is trusted, but it
|
this file) knows whether a client/connection is trusted, but it
|
||||||
does not how how the client was authenticated. The mechanism
|
does not how how the client was authenticated. The mechanism
|
||||||
need not be getting the UID of the other end of a Unix Domain
|
need not be getting the UID of the other end of a Unix Domain
|
||||||
Socket.
|
Socket.
|
||||||
*/
|
*/
|
||||||
if (mode == bmRepair && !trusted)
|
if (mode == bmRepair && !trusted)
|
||||||
throw Error("repairing is not allowed because you are not in 'trusted-users'");
|
throw Error("repairing is not allowed because you are not in 'trusted-users'");
|
||||||
}
|
|
||||||
logger->startWork();
|
logger->startWork();
|
||||||
store->buildPaths(drvs, mode);
|
store->buildPaths(drvs, mode);
|
||||||
logger->stopWork();
|
logger->stopWork();
|
||||||
|
@ -746,13 +734,11 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
||||||
clientSettings.buildCores = readInt(from);
|
clientSettings.buildCores = readInt(from);
|
||||||
clientSettings.useSubstitutes = readInt(from);
|
clientSettings.useSubstitutes = readInt(from);
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 12) {
|
unsigned int n = readInt(from);
|
||||||
unsigned int n = readInt(from);
|
for (unsigned int i = 0; i < n; i++) {
|
||||||
for (unsigned int i = 0; i < n; i++) {
|
auto name = readString(from);
|
||||||
auto name = readString(from);
|
auto value = readString(from);
|
||||||
auto value = readString(from);
|
clientSettings.overrides.emplace(name, value);
|
||||||
clientSettings.overrides.emplace(name, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger->startWork();
|
logger->startWork();
|
||||||
|
@ -822,15 +808,14 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
||||||
try {
|
try {
|
||||||
info = store->queryPathInfo(path);
|
info = store->queryPathInfo(path);
|
||||||
} catch (InvalidPath &) {
|
} catch (InvalidPath &) {
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) < 17) throw;
|
// The path being invalid isn't fatal here since it will just be
|
||||||
|
// sent as not present.
|
||||||
}
|
}
|
||||||
logger->stopWork();
|
logger->stopWork();
|
||||||
if (info) {
|
if (info) {
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 17)
|
to << 1;
|
||||||
to << 1;
|
|
||||||
WorkerProto::write(*store, wconn, static_cast<const UnkeyedValidPathInfo &>(*info));
|
WorkerProto::write(*store, wconn, static_cast<const UnkeyedValidPathInfo &>(*info));
|
||||||
} else {
|
} else {
|
||||||
assert(GET_PROTOCOL_MINOR(clientVersion) >= 17);
|
|
||||||
to << 0;
|
to << 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -904,12 +889,7 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
|
||||||
else {
|
else {
|
||||||
std::unique_ptr<Source> source;
|
std::unique_ptr<Source> source;
|
||||||
StringSink saved;
|
StringSink saved;
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 21)
|
source = std::make_unique<TunnelSource>(from, to);
|
||||||
source = std::make_unique<TunnelSource>(from, to);
|
|
||||||
else {
|
|
||||||
copyNAR(from, saved);
|
|
||||||
source = std::make_unique<StringSource>(saved.s);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger->startWork();
|
logger->startWork();
|
||||||
|
|
||||||
|
@ -1011,7 +991,7 @@ void processConnection(
|
||||||
to.flush();
|
to.flush();
|
||||||
WorkerProto::Version clientVersion = readInt(from);
|
WorkerProto::Version clientVersion = readInt(from);
|
||||||
|
|
||||||
if (clientVersion < 0x10a)
|
if (clientVersion < MIN_SUPPORTED_WORKER_PROTO_VERSION)
|
||||||
throw Error("the Nix client version is too old");
|
throw Error("the Nix client version is too old");
|
||||||
|
|
||||||
auto tunnelLogger = new TunnelLogger(to, clientVersion);
|
auto tunnelLogger = new TunnelLogger(to, clientVersion);
|
||||||
|
@ -1027,13 +1007,13 @@ void processConnection(
|
||||||
printMsgUsing(prevLogger, lvlDebug, "%d operations", opCount);
|
printMsgUsing(prevLogger, lvlDebug, "%d operations", opCount);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 14 && readInt(from)) {
|
// FIXME: what is *supposed* to be in this even?
|
||||||
|
if (readInt(from)) {
|
||||||
// Obsolete CPU affinity.
|
// Obsolete CPU affinity.
|
||||||
readInt(from);
|
readInt(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 11)
|
readInt(from); // obsolete reserveSpace
|
||||||
readInt(from); // obsolete reserveSpace
|
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 33)
|
if (GET_PROTOCOL_MINOR(clientVersion) >= 33)
|
||||||
to << nixVersion;
|
to << nixVersion;
|
||||||
|
@ -1044,10 +1024,7 @@ void processConnection(
|
||||||
auto temp = trusted
|
auto temp = trusted
|
||||||
? store->isTrustedClient()
|
? store->isTrustedClient()
|
||||||
: std::optional { NotTrusted };
|
: std::optional { NotTrusted };
|
||||||
WorkerProto::WriteConn wconn {
|
WorkerProto::WriteConn wconn {to, clientVersion};
|
||||||
.to = to,
|
|
||||||
.version = clientVersion,
|
|
||||||
};
|
|
||||||
WorkerProto::write(*store, wconn, temp);
|
WorkerProto::write(*store, wconn, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,8 @@ struct RemoteStore::Connection
|
||||||
FdSource from;
|
FdSource from;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Worker protocol version used for the connection.
|
* The worker protocol version of the connected daemon. This may be newer
|
||||||
*
|
* than this Lix supports.
|
||||||
* Despite its name, I think it is actually the maximum version both
|
|
||||||
* sides support. (If the maximum doesn't exist, we would fail to
|
|
||||||
* establish a connection and produce a value of this type.)
|
|
||||||
*/
|
*/
|
||||||
WorkerProto::Version daemonVersion;
|
WorkerProto::Version daemonVersion;
|
||||||
|
|
||||||
|
@ -71,10 +68,7 @@ struct RemoteStore::Connection
|
||||||
*/
|
*/
|
||||||
operator WorkerProto::ReadConn ()
|
operator WorkerProto::ReadConn ()
|
||||||
{
|
{
|
||||||
return WorkerProto::ReadConn {
|
return WorkerProto::ReadConn {from, daemonVersion};
|
||||||
.from = from,
|
|
||||||
.version = daemonVersion,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,10 +81,7 @@ struct RemoteStore::Connection
|
||||||
*/
|
*/
|
||||||
operator WorkerProto::WriteConn ()
|
operator WorkerProto::WriteConn ()
|
||||||
{
|
{
|
||||||
return WorkerProto::WriteConn {
|
return WorkerProto::WriteConn {to, daemonVersion};
|
||||||
.to = to,
|
|
||||||
.version = daemonVersion,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~Connection();
|
virtual ~Connection();
|
||||||
|
|
|
@ -75,17 +75,14 @@ void RemoteStore::initConnection(Connection & conn)
|
||||||
conn.from >> conn.daemonVersion;
|
conn.from >> conn.daemonVersion;
|
||||||
if (GET_PROTOCOL_MAJOR(conn.daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION))
|
if (GET_PROTOCOL_MAJOR(conn.daemonVersion) != GET_PROTOCOL_MAJOR(PROTOCOL_VERSION))
|
||||||
throw Error("Nix daemon protocol version not supported");
|
throw Error("Nix daemon protocol version not supported");
|
||||||
if (GET_PROTOCOL_MINOR(conn.daemonVersion) < 10)
|
if (GET_PROTOCOL_MINOR(conn.daemonVersion) < MIN_SUPPORTED_MINOR_WORKER_PROTO_VERSION)
|
||||||
throw Error("the Nix daemon version is too old");
|
throw Error("the Nix daemon version is too old");
|
||||||
conn.to << PROTOCOL_VERSION;
|
conn.to << PROTOCOL_VERSION;
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 14) {
|
// Obsolete CPU affinity.
|
||||||
// Obsolete CPU affinity.
|
conn.to << 0;
|
||||||
conn.to << 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 11)
|
conn.to << false; // obsolete reserveSpace
|
||||||
conn.to << false; // obsolete reserveSpace
|
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 33) {
|
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 33) {
|
||||||
conn.to.flush();
|
conn.to.flush();
|
||||||
|
@ -126,24 +123,22 @@ void RemoteStore::setOptions(Connection & conn)
|
||||||
<< settings.buildCores
|
<< settings.buildCores
|
||||||
<< settings.useSubstitutes;
|
<< settings.useSubstitutes;
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(conn.daemonVersion) >= 12) {
|
std::map<std::string, Config::SettingInfo> overrides;
|
||||||
std::map<std::string, Config::SettingInfo> overrides;
|
settings.getSettings(overrides, true); // libstore settings
|
||||||
settings.getSettings(overrides, true); // libstore settings
|
fileTransferSettings.getSettings(overrides, true);
|
||||||
fileTransferSettings.getSettings(overrides, true);
|
overrides.erase(settings.keepFailed.name);
|
||||||
overrides.erase(settings.keepFailed.name);
|
overrides.erase(settings.keepGoing.name);
|
||||||
overrides.erase(settings.keepGoing.name);
|
overrides.erase(settings.tryFallback.name);
|
||||||
overrides.erase(settings.tryFallback.name);
|
overrides.erase(settings.maxBuildJobs.name);
|
||||||
overrides.erase(settings.maxBuildJobs.name);
|
overrides.erase(settings.maxSilentTime.name);
|
||||||
overrides.erase(settings.maxSilentTime.name);
|
overrides.erase(settings.buildCores.name);
|
||||||
overrides.erase(settings.buildCores.name);
|
overrides.erase(settings.useSubstitutes.name);
|
||||||
overrides.erase(settings.useSubstitutes.name);
|
overrides.erase(loggerSettings.showTrace.name);
|
||||||
overrides.erase(loggerSettings.showTrace.name);
|
overrides.erase(experimentalFeatureSettings.experimentalFeatures.name);
|
||||||
overrides.erase(experimentalFeatureSettings.experimentalFeatures.name);
|
overrides.erase(settings.pluginFiles.name);
|
||||||
overrides.erase(settings.pluginFiles.name);
|
conn.to << overrides.size();
|
||||||
conn.to << overrides.size();
|
for (auto & i : overrides)
|
||||||
for (auto & i : overrides)
|
conn.to << i.first << i.second.value;
|
||||||
conn.to << i.first << i.second.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ex = conn.processStderr();
|
auto ex = conn.processStderr();
|
||||||
if (ex) std::rethrow_exception(ex);
|
if (ex) std::rethrow_exception(ex);
|
||||||
|
@ -207,20 +202,13 @@ bool RemoteStore::isValidPathUncached(const StorePath & path)
|
||||||
StorePathSet RemoteStore::queryValidPaths(const StorePathSet & paths, SubstituteFlag maybeSubstitute)
|
StorePathSet RemoteStore::queryValidPaths(const StorePathSet & paths, SubstituteFlag maybeSubstitute)
|
||||||
{
|
{
|
||||||
auto conn(getConnection());
|
auto conn(getConnection());
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 12) {
|
conn->to << WorkerProto::Op::QueryValidPaths;
|
||||||
StorePathSet res;
|
WorkerProto::write(*this, *conn, paths);
|
||||||
for (auto & i : paths)
|
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 27) {
|
||||||
if (isValidPath(i)) res.insert(i);
|
conn->to << maybeSubstitute;
|
||||||
return res;
|
|
||||||
} else {
|
|
||||||
conn->to << WorkerProto::Op::QueryValidPaths;
|
|
||||||
WorkerProto::write(*this, *conn, paths);
|
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 27) {
|
|
||||||
conn->to << maybeSubstitute;
|
|
||||||
}
|
|
||||||
conn.processStderr();
|
|
||||||
return WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
|
||||||
}
|
}
|
||||||
|
conn.processStderr();
|
||||||
|
return WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,20 +224,10 @@ StorePathSet RemoteStore::queryAllValidPaths()
|
||||||
StorePathSet RemoteStore::querySubstitutablePaths(const StorePathSet & paths)
|
StorePathSet RemoteStore::querySubstitutablePaths(const StorePathSet & paths)
|
||||||
{
|
{
|
||||||
auto conn(getConnection());
|
auto conn(getConnection());
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 12) {
|
conn->to << WorkerProto::Op::QuerySubstitutablePaths;
|
||||||
StorePathSet res;
|
WorkerProto::write(*this, *conn, paths);
|
||||||
for (auto & i : paths) {
|
conn.processStderr();
|
||||||
conn->to << WorkerProto::Op::HasSubstitutes << printStorePath(i);
|
return WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -259,45 +237,25 @@ void RemoteStore::querySubstitutablePathInfos(const StorePathCAMap & pathsMap, S
|
||||||
|
|
||||||
auto conn(getConnection());
|
auto conn(getConnection());
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 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->daemonVersion) < 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->daemonVersion) < 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,10 +272,10 @@ std::shared_ptr<const ValidPathInfo> RemoteStore::queryPathInfoUncached(const St
|
||||||
return nullptr;
|
return nullptr;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 17) {
|
|
||||||
bool valid; conn->from >> valid;
|
bool valid; conn->from >> valid;
|
||||||
if (!valid) return nullptr;
|
if (!valid) return nullptr;
|
||||||
}
|
|
||||||
return std::make_shared<ValidPathInfo>(
|
return std::make_shared<ValidPathInfo>(
|
||||||
StorePath{path},
|
StorePath{path},
|
||||||
WorkerProto::Serialise<UnkeyedValidPathInfo>::read(*this, *conn));
|
WorkerProto::Serialise<UnkeyedValidPathInfo>::read(*this, *conn));
|
||||||
|
@ -346,7 +304,7 @@ StorePathSet RemoteStore::queryValidDerivers(const StorePath & path)
|
||||||
|
|
||||||
StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path)
|
StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path)
|
||||||
{
|
{
|
||||||
if (GET_PROTOCOL_MINOR(getProtocol()) >= 0x16) {
|
if (GET_PROTOCOL_MINOR(getProtocol()) >= 22) {
|
||||||
return Store::queryDerivationOutputs(path);
|
return Store::queryDerivationOutputs(path);
|
||||||
}
|
}
|
||||||
auto conn(getConnection());
|
auto conn(getConnection());
|
||||||
|
@ -358,7 +316,7 @@ StorePathSet RemoteStore::queryDerivationOutputs(const StorePath & path)
|
||||||
|
|
||||||
std::map<std::string, std::optional<StorePath>> RemoteStore::queryPartialDerivationOutputMap(const StorePath & path, Store * evalStore_)
|
std::map<std::string, std::optional<StorePath>> RemoteStore::queryPartialDerivationOutputMap(const StorePath & path, Store * evalStore_)
|
||||||
{
|
{
|
||||||
if (GET_PROTOCOL_MINOR(getProtocol()) >= 0x16) {
|
if (GET_PROTOCOL_MINOR(getProtocol()) >= 22) {
|
||||||
if (!evalStore_) {
|
if (!evalStore_) {
|
||||||
auto conn(getConnection());
|
auto conn(getConnection());
|
||||||
conn->to << WorkerProto::Op::QueryDerivationOutputMap << printStorePath(path);
|
conn->to << WorkerProto::Op::QueryDerivationOutputMap << printStorePath(path);
|
||||||
|
@ -498,51 +456,21 @@ void RemoteStore::addToStore(const ValidPathInfo & info, Source & source,
|
||||||
{
|
{
|
||||||
auto conn(getConnection());
|
auto conn(getConnection());
|
||||||
|
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 18) {
|
conn->to << WorkerProto::Op::AddToStoreNar
|
||||||
conn->to << WorkerProto::Op::ImportPaths;
|
<< printStorePath(info.path)
|
||||||
|
<< (info.deriver ? printStorePath(*info.deriver) : "")
|
||||||
|
<< info.narHash.to_string(Base16, false);
|
||||||
|
WorkerProto::write(*this, *conn, info.references);
|
||||||
|
conn->to << info.registrationTime << info.narSize
|
||||||
|
<< info.ultimate << info.sigs << renderContentAddress(info.ca)
|
||||||
|
<< repair << !checkSigs;
|
||||||
|
|
||||||
auto source2 = sinkToSource([&](Sink & sink) {
|
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 23) {
|
||||||
sink << 1 // == path follows
|
conn.withFramedSink([&](Sink & sink) {
|
||||||
;
|
|
||||||
copyNAR(source, sink);
|
copyNAR(source, sink);
|
||||||
sink
|
|
||||||
<< exportMagic
|
|
||||||
<< printStorePath(info.path);
|
|
||||||
WorkerProto::WriteConn nested { .to = sink, .version = conn->daemonVersion };
|
|
||||||
WorkerProto::write(*this, nested, info.references);
|
|
||||||
sink
|
|
||||||
<< (info.deriver ? printStorePath(*info.deriver) : "")
|
|
||||||
<< 0 // == no legacy signature
|
|
||||||
<< 0 // == no path follows
|
|
||||||
;
|
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
conn.processStderr(0, source2.get());
|
conn.processStderr(0, &source);
|
||||||
|
|
||||||
auto importedPaths = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
|
||||||
assert(importedPaths.size() <= 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
conn->to << WorkerProto::Op::AddToStoreNar
|
|
||||||
<< printStorePath(info.path)
|
|
||||||
<< (info.deriver ? printStorePath(*info.deriver) : "")
|
|
||||||
<< info.narHash.to_string(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->daemonVersion) >= 23) {
|
|
||||||
conn.withFramedSink([&](Sink & sink) {
|
|
||||||
copyNAR(source, sink);
|
|
||||||
});
|
|
||||||
} else if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 21) {
|
|
||||||
conn.processStderr(0, &source);
|
|
||||||
} else {
|
|
||||||
copyNAR(source, conn->to);
|
|
||||||
conn.processStderr(0, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,14 +481,13 @@ void RemoteStore::addMultipleToStore(
|
||||||
RepairFlag repair,
|
RepairFlag repair,
|
||||||
CheckSigsFlag checkSigs)
|
CheckSigsFlag checkSigs)
|
||||||
{
|
{
|
||||||
|
auto remoteVersion = getProtocol();
|
||||||
|
|
||||||
auto source = sinkToSource([&](Sink & sink) {
|
auto source = sinkToSource([&](Sink & sink) {
|
||||||
sink << pathsToCopy.size();
|
sink << pathsToCopy.size();
|
||||||
for (auto & [pathInfo, pathSource] : pathsToCopy) {
|
for (auto & [pathInfo, pathSource] : pathsToCopy) {
|
||||||
WorkerProto::Serialise<ValidPathInfo>::write(*this,
|
WorkerProto::Serialise<ValidPathInfo>::write(*this,
|
||||||
WorkerProto::WriteConn {
|
WorkerProto::WriteConn {sink, remoteVersion},
|
||||||
.to = sink,
|
|
||||||
.version = 16,
|
|
||||||
},
|
|
||||||
pathInfo);
|
pathInfo);
|
||||||
pathSource->drainInto(sink);
|
pathSource->drainInto(sink);
|
||||||
}
|
}
|
||||||
|
@ -667,15 +594,8 @@ void RemoteStore::buildPaths(const std::vector<DerivedPath> & drvPaths, BuildMod
|
||||||
|
|
||||||
auto conn(getConnection());
|
auto conn(getConnection());
|
||||||
conn->to << WorkerProto::Op::BuildPaths;
|
conn->to << WorkerProto::Op::BuildPaths;
|
||||||
assert(GET_PROTOCOL_MINOR(conn->daemonVersion) >= 13);
|
|
||||||
WorkerProto::write(*this, *conn, drvPaths);
|
WorkerProto::write(*this, *conn, drvPaths);
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 15)
|
conn->to << buildMode;
|
||||||
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.processStderr();
|
conn.processStderr();
|
||||||
readInt(conn->from);
|
readInt(conn->from);
|
||||||
}
|
}
|
||||||
|
@ -866,25 +786,14 @@ void RemoteStore::queryMissing(const std::vector<DerivedPath> & targets,
|
||||||
StorePathSet & willBuild, StorePathSet & willSubstitute, StorePathSet & unknown,
|
StorePathSet & willBuild, StorePathSet & willSubstitute, StorePathSet & unknown,
|
||||||
uint64_t & downloadSize, uint64_t & narSize)
|
uint64_t & downloadSize, uint64_t & narSize)
|
||||||
{
|
{
|
||||||
{
|
auto conn(getConnection());
|
||||||
auto conn(getConnection());
|
conn->to << WorkerProto::Op::QueryMissing;
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 19)
|
WorkerProto::write(*this, *conn, targets);
|
||||||
// Don't hold the connection handle in the fallback case
|
conn.processStderr();
|
||||||
// to prevent a deadlock.
|
willBuild = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
||||||
goto fallback;
|
willSubstitute = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
||||||
conn->to << WorkerProto::Op::QueryMissing;
|
unknown = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
||||||
WorkerProto::write(*this, *conn, targets);
|
conn->from >> downloadSize >> narSize;
|
||||||
conn.processStderr();
|
|
||||||
willBuild = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
|
||||||
willSubstitute = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
|
||||||
unknown = WorkerProto::Serialise<StorePathSet>::read(*this, *conn);
|
|
||||||
conn->from >> downloadSize >> narSize;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fallback:
|
|
||||||
return Store::queryMissing(targets, willBuild, willSubstitute,
|
|
||||||
unknown, downloadSize, narSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -368,15 +368,14 @@ void Store::addMultipleToStore(
|
||||||
RepairFlag repair,
|
RepairFlag repair,
|
||||||
CheckSigsFlag checkSigs)
|
CheckSigsFlag checkSigs)
|
||||||
{
|
{
|
||||||
|
auto remoteVersion = getProtocol();
|
||||||
|
|
||||||
auto expected = readNum<uint64_t>(source);
|
auto expected = readNum<uint64_t>(source);
|
||||||
for (uint64_t i = 0; i < expected; ++i) {
|
for (uint64_t i = 0; i < expected; ++i) {
|
||||||
// FIXME we should not be using the worker protocol here, let
|
// FIXME we should not be using the worker protocol here at all!
|
||||||
// alone the worker protocol with a hard-coded version!
|
|
||||||
auto info = WorkerProto::Serialise<ValidPathInfo>::read(*this,
|
auto info = WorkerProto::Serialise<ValidPathInfo>::read(*this,
|
||||||
WorkerProto::ReadConn {
|
WorkerProto::ReadConn {source, remoteVersion}
|
||||||
.from = source,
|
);
|
||||||
.version = 16,
|
|
||||||
});
|
|
||||||
info.ultimate = false;
|
info.ultimate = false;
|
||||||
addToStore(info, source, repair, checkSigs);
|
addToStore(info, source, repair, checkSigs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,11 +165,11 @@ UnkeyedValidPathInfo WorkerProto::Serialise<UnkeyedValidPathInfo>::read(const St
|
||||||
if (deriver != "") info.deriver = store.parseStorePath(deriver);
|
if (deriver != "") info.deriver = store.parseStorePath(deriver);
|
||||||
info.references = WorkerProto::Serialise<StorePathSet>::read(store, conn);
|
info.references = WorkerProto::Serialise<StorePathSet>::read(store, conn);
|
||||||
conn.from >> info.registrationTime >> info.narSize;
|
conn.from >> info.registrationTime >> info.narSize;
|
||||||
if (GET_PROTOCOL_MINOR(conn.version) >= 16) {
|
|
||||||
conn.from >> info.ultimate;
|
conn.from >> info.ultimate;
|
||||||
info.sigs = readStrings<StringSet>(conn.from);
|
info.sigs = readStrings<StringSet>(conn.from);
|
||||||
info.ca = ContentAddress::parseOpt(readString(conn.from));
|
info.ca = ContentAddress::parseOpt(readString(conn.from));
|
||||||
}
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,12 +180,11 @@ void WorkerProto::Serialise<UnkeyedValidPathInfo>::write(const Store & store, Wr
|
||||||
<< pathInfo.narHash.to_string(Base16, false);
|
<< pathInfo.narHash.to_string(Base16, false);
|
||||||
WorkerProto::write(store, conn, pathInfo.references);
|
WorkerProto::write(store, conn, pathInfo.references);
|
||||||
conn.to << pathInfo.registrationTime << pathInfo.narSize;
|
conn.to << pathInfo.registrationTime << pathInfo.narSize;
|
||||||
if (GET_PROTOCOL_MINOR(conn.version) >= 16) {
|
|
||||||
conn.to
|
conn.to
|
||||||
<< pathInfo.ultimate
|
<< pathInfo.ultimate
|
||||||
<< pathInfo.sigs
|
<< pathInfo.sigs
|
||||||
<< renderContentAddress(pathInfo.ca);
|
<< renderContentAddress(pathInfo.ca);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,16 @@ namespace nix {
|
||||||
#define WORKER_MAGIC_1 0x6e697863
|
#define WORKER_MAGIC_1 0x6e697863
|
||||||
#define WORKER_MAGIC_2 0x6478696f
|
#define WORKER_MAGIC_2 0x6478696f
|
||||||
|
|
||||||
|
// This must remain 1.35 (Nix 2.18) forever in Lix, since the protocol has
|
||||||
|
// diverged in CppNix such that we cannot assign newer versions ourselves, the
|
||||||
|
// protocol is bad in design and implementation and Lix intends to replace it
|
||||||
|
// entirely.
|
||||||
#define PROTOCOL_VERSION (1 << 8 | 35)
|
#define PROTOCOL_VERSION (1 << 8 | 35)
|
||||||
|
// Nix 2.3 is protocol 1.21 (see RemoteStore::initConnection for client,
|
||||||
|
// processConnection for server).
|
||||||
|
#define MIN_SUPPORTED_MINOR_WORKER_PROTO_VERSION 21
|
||||||
|
#define MIN_SUPPORTED_WORKER_PROTO_VERSION (1 << 8 | MIN_SUPPORTED_MINOR_WORKER_PROTO_VERSION)
|
||||||
|
|
||||||
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
#define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00)
|
||||||
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
#define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff)
|
||||||
|
|
||||||
|
@ -63,6 +72,10 @@ struct WorkerProto
|
||||||
struct ReadConn {
|
struct ReadConn {
|
||||||
Source & from;
|
Source & from;
|
||||||
Version version;
|
Version version;
|
||||||
|
|
||||||
|
ReadConn(Source & from, Version version) : from(from), version(version) {
|
||||||
|
assert(version >= MIN_SUPPORTED_WORKER_PROTO_VERSION);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,6 +85,10 @@ struct WorkerProto
|
||||||
struct WriteConn {
|
struct WriteConn {
|
||||||
Sink & to;
|
Sink & to;
|
||||||
Version version;
|
Version version;
|
||||||
|
|
||||||
|
WriteConn(Sink & to, Version version) : to(to), version(version) {
|
||||||
|
assert(version >= MIN_SUPPORTED_WORKER_PROTO_VERSION);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -39,10 +39,8 @@ public:
|
||||||
StringSource from { expected };
|
StringSource from { expected };
|
||||||
Proto::template Serialise<T>::read(
|
Proto::template Serialise<T>::read(
|
||||||
*LibStoreTest::store,
|
*LibStoreTest::store,
|
||||||
typename Proto::ReadConn {
|
typename Proto::ReadConn {from, version}
|
||||||
.from = from,
|
);
|
||||||
.version = version,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
ASSERT_EQ(got, value);
|
ASSERT_EQ(got, value);
|
||||||
|
@ -60,10 +58,7 @@ public:
|
||||||
StringSink to;
|
StringSink to;
|
||||||
Proto::write(
|
Proto::write(
|
||||||
*LibStoreTest::store,
|
*LibStoreTest::store,
|
||||||
typename Proto::WriteConn {
|
typename Proto::WriteConn {to, version},
|
||||||
.to = to,
|
|
||||||
.version = version,
|
|
||||||
},
|
|
||||||
value);
|
value);
|
||||||
|
|
||||||
if (testAccept())
|
if (testAccept())
|
||||||
|
|
|
@ -18,9 +18,9 @@ struct WorkerProtoTest : VersionedProtoTest<WorkerProto, workerProtoDir>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* For serializers that don't care about the minimum version, we
|
* For serializers that don't care about the minimum version, we
|
||||||
* used the oldest one: 1.0.
|
* have to use the minimum supported to not throw an assert.
|
||||||
*/
|
*/
|
||||||
WorkerProto::Version defaultVersion = 1 << 8 | 0;
|
WorkerProto::Version defaultVersion = MIN_SUPPORTED_WORKER_PROTO_VERSION;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -331,9 +331,9 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||||
|
|
||||||
VERSIONED_CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
unkeyedValidPathInfo_1_15,
|
unkeyedValidPathInfo,
|
||||||
"unkeyed-valid-path-info-1.15",
|
"unkeyed-valid-path-info",
|
||||||
1 << 8 | 15,
|
defaultVersion,
|
||||||
(std::tuple<UnkeyedValidPathInfo, UnkeyedValidPathInfo> {
|
(std::tuple<UnkeyedValidPathInfo, UnkeyedValidPathInfo> {
|
||||||
({
|
({
|
||||||
UnkeyedValidPathInfo info {
|
UnkeyedValidPathInfo info {
|
||||||
|
@ -363,56 +363,9 @@ VERSIONED_CHARACTERIZATION_TEST(
|
||||||
|
|
||||||
VERSIONED_CHARACTERIZATION_TEST(
|
VERSIONED_CHARACTERIZATION_TEST(
|
||||||
WorkerProtoTest,
|
WorkerProtoTest,
|
||||||
validPathInfo_1_15,
|
validPathInfo,
|
||||||
"valid-path-info-1.15",
|
"valid-path-info",
|
||||||
1 << 8 | 15,
|
defaultVersion,
|
||||||
(std::tuple<ValidPathInfo, ValidPathInfo> {
|
|
||||||
({
|
|
||||||
ValidPathInfo info {
|
|
||||||
StorePath {
|
|
||||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
|
||||||
},
|
|
||||||
UnkeyedValidPathInfo {
|
|
||||||
Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
info.registrationTime = 23423;
|
|
||||||
info.narSize = 34878;
|
|
||||||
info;
|
|
||||||
}),
|
|
||||||
({
|
|
||||||
ValidPathInfo info {
|
|
||||||
StorePath {
|
|
||||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
|
||||||
},
|
|
||||||
UnkeyedValidPathInfo {
|
|
||||||
Hash::parseSRI("sha256-FePFYIlMuycIXPZbWi7LGEiMmZSX9FMbaQenWBzm1Sc="),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
info.deriver = StorePath {
|
|
||||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar.drv",
|
|
||||||
};
|
|
||||||
info.references = {
|
|
||||||
// other reference
|
|
||||||
StorePath {
|
|
||||||
"g1w7hyyyy1w7hy3qg1w7hy3qgqqqqy3q-foo",
|
|
||||||
},
|
|
||||||
// self reference
|
|
||||||
StorePath {
|
|
||||||
"g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-bar",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
info.registrationTime = 23423;
|
|
||||||
info.narSize = 34878;
|
|
||||||
info;
|
|
||||||
}),
|
|
||||||
}))
|
|
||||||
|
|
||||||
VERSIONED_CHARACTERIZATION_TEST(
|
|
||||||
WorkerProtoTest,
|
|
||||||
validPathInfo_1_16,
|
|
||||||
"valid-path-info-1.16",
|
|
||||||
1 << 8 | 16,
|
|
||||||
(std::tuple<ValidPathInfo, ValidPathInfo, ValidPathInfo> {
|
(std::tuple<ValidPathInfo, ValidPathInfo, ValidPathInfo> {
|
||||||
({
|
({
|
||||||
ValidPathInfo info {
|
ValidPathInfo info {
|
||||||
|
|
Loading…
Reference in a new issue