mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-29 00:56:15 +02:00
Query path infos (plural) and handshake version minimum for hydra
1. Hydra currently queries for multiple path infos at once, so let us make a connection item for that. 2. The minimum of the two versions should always be used, see #9584. (The issue remains open because the daemon protocol needs to be likewise updated.)
This commit is contained in:
parent
8953bdbf32
commit
8b369f90fd
4 changed files with 50 additions and 18 deletions
|
@ -105,24 +105,26 @@ void LegacySSHStore::queryPathInfoUncached(const StorePath & path,
|
||||||
|
|
||||||
debug("querying remote host '%s' for info on '%s'", host, printStorePath(path));
|
debug("querying remote host '%s' for info on '%s'", host, printStorePath(path));
|
||||||
|
|
||||||
conn->to << ServeProto::Command::QueryPathInfos << PathSet{printStorePath(path)};
|
auto infos = conn->queryPathInfos(*this, {path});
|
||||||
conn->to.flush();
|
|
||||||
|
|
||||||
auto p = readString(conn->from);
|
switch (infos.size()) {
|
||||||
if (p.empty()) return callback(nullptr);
|
case 0:
|
||||||
auto path2 = parseStorePath(p);
|
return callback(nullptr);
|
||||||
assert(path == path2);
|
case 1: {
|
||||||
auto info = std::make_shared<ValidPathInfo>(
|
auto & [path2, info] = *infos.begin();
|
||||||
path,
|
|
||||||
ServeProto::Serialise<UnkeyedValidPathInfo>::read(*this, *conn));
|
|
||||||
|
|
||||||
if (info->narHash == Hash::dummy)
|
if (info.narHash == Hash::dummy)
|
||||||
throw Error("NAR hash is now mandatory");
|
throw Error("NAR hash is now mandatory");
|
||||||
|
|
||||||
auto s = readString(conn->from);
|
assert(path == path2);
|
||||||
assert(s == "");
|
return callback(std::make_shared<ValidPathInfo>(
|
||||||
|
std::move(path),
|
||||||
callback(std::move(info));
|
std::move(info)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw Error("More path infos returned than queried");
|
||||||
|
}
|
||||||
} catch (...) { callback.rethrow(); }
|
} catch (...) { callback.rethrow(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ ServeProto::Version ServeProto::BasicClientConnection::handshake(
|
||||||
auto remoteVersion = readInt(from);
|
auto remoteVersion = readInt(from);
|
||||||
if (GET_PROTOCOL_MAJOR(remoteVersion) != 0x200)
|
if (GET_PROTOCOL_MAJOR(remoteVersion) != 0x200)
|
||||||
throw Error("unsupported 'nix-store --serve' protocol version on '%s'", host);
|
throw Error("unsupported 'nix-store --serve' protocol version on '%s'", host);
|
||||||
return remoteVersion;
|
return std::min(remoteVersion, localVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
ServeProto::Version ServeProto::BasicServerConnection::handshake(
|
ServeProto::Version ServeProto::BasicServerConnection::handshake(
|
||||||
|
@ -31,7 +31,8 @@ ServeProto::Version ServeProto::BasicServerConnection::handshake(
|
||||||
if (magic != SERVE_MAGIC_1) throw Error("protocol mismatch");
|
if (magic != SERVE_MAGIC_1) throw Error("protocol mismatch");
|
||||||
to << SERVE_MAGIC_2 << localVersion;
|
to << SERVE_MAGIC_2 << localVersion;
|
||||||
to.flush();
|
to.flush();
|
||||||
return readInt(from);
|
auto remoteVersion = readInt(from);
|
||||||
|
return std::min(remoteVersion, localVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,6 +52,30 @@ StorePathSet ServeProto::BasicClientConnection::queryValidPaths(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::map<StorePath, UnkeyedValidPathInfo> ServeProto::BasicClientConnection::queryPathInfos(
|
||||||
|
const Store & store,
|
||||||
|
const StorePathSet & paths)
|
||||||
|
{
|
||||||
|
std::map<StorePath, UnkeyedValidPathInfo> infos;
|
||||||
|
|
||||||
|
to << ServeProto::Command::QueryPathInfos;
|
||||||
|
ServeProto::write(store, *this, paths);
|
||||||
|
to.flush();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
auto storePathS = readString(from);
|
||||||
|
if (storePathS == "") break;
|
||||||
|
|
||||||
|
auto storePath = store.parseStorePath(storePathS);
|
||||||
|
assert(paths.count(storePath) == 1);
|
||||||
|
auto info = ServeProto::Serialise<UnkeyedValidPathInfo>::read(store, *this);
|
||||||
|
infos.insert_or_assign(std::move(storePath), std::move(info));
|
||||||
|
}
|
||||||
|
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ServeProto::BasicClientConnection::putBuildDerivationRequest(
|
void ServeProto::BasicClientConnection::putBuildDerivationRequest(
|
||||||
const Store & store,
|
const Store & store,
|
||||||
const StorePath & drvPath, const BasicDerivation & drv,
|
const StorePath & drvPath, const BasicDerivation & drv,
|
||||||
|
|
|
@ -122,6 +122,10 @@ struct ServeProto::BasicClientConnection
|
||||||
bool lock, const StorePathSet & paths,
|
bool lock, const StorePathSet & paths,
|
||||||
SubstituteFlag maybeSubstitute);
|
SubstituteFlag maybeSubstitute);
|
||||||
|
|
||||||
|
std::map<StorePath, UnkeyedValidPathInfo> queryPathInfos(
|
||||||
|
const Store & store,
|
||||||
|
const StorePathSet & paths);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just the request half, because Hydra may do other things between
|
* Just the request half, because Hydra may do other things between
|
||||||
* issuing the request and reading the `BuildResult` response.
|
* issuing the request and reading the `BuildResult` response.
|
||||||
|
|
|
@ -505,7 +505,8 @@ TEST_F(ServeProtoTest, handshake_client_corrupted_throws)
|
||||||
} else {
|
} else {
|
||||||
auto ver = ServeProto::BasicClientConnection::handshake(
|
auto ver = ServeProto::BasicClientConnection::handshake(
|
||||||
nullSink, in, defaultVersion, "blah");
|
nullSink, in, defaultVersion, "blah");
|
||||||
EXPECT_NE(ver, defaultVersion);
|
// `std::min` of this and the other version saves us
|
||||||
|
EXPECT_EQ(ver, defaultVersion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue