2024-05-23 23:40:05 +03:00
|
|
|
#include "serve-protocol-connection.hh"
|
2022-02-20 21:24:07 +02:00
|
|
|
#include "serve-protocol-impl.hh"
|
|
|
|
#include "build-result.hh"
|
|
|
|
#include "derivations.hh"
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
2022-02-20 21:24:07 +02:00
|
|
|
ServeProto::Version ServeProto::BasicClientConnection::handshake(
|
2024-05-23 23:40:05 +03:00
|
|
|
BufferedSink & to, Source & from, ServeProto::Version localVersion, std::string_view host)
|
2022-02-20 21:24:07 +02:00
|
|
|
{
|
|
|
|
to << SERVE_MAGIC_1 << localVersion;
|
|
|
|
to.flush();
|
|
|
|
|
|
|
|
unsigned int magic = readInt(from);
|
|
|
|
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)
|
|
|
|
throw Error("unsupported 'nix-store --serve' protocol version on '%s'", host);
|
2024-05-21 00:41:12 +03:00
|
|
|
return std::min(remoteVersion, localVersion);
|
2022-02-20 21:24:07 +02:00
|
|
|
}
|
|
|
|
|
2024-05-23 23:40:05 +03:00
|
|
|
ServeProto::Version
|
|
|
|
ServeProto::BasicServerConnection::handshake(BufferedSink & to, Source & from, ServeProto::Version localVersion)
|
2024-01-19 23:38:08 +02:00
|
|
|
{
|
|
|
|
unsigned int magic = readInt(from);
|
2024-05-23 23:40:05 +03:00
|
|
|
if (magic != SERVE_MAGIC_1)
|
|
|
|
throw Error("protocol mismatch");
|
2024-01-19 23:38:08 +02:00
|
|
|
to << SERVE_MAGIC_2 << localVersion;
|
|
|
|
to.flush();
|
2024-05-21 00:41:12 +03:00
|
|
|
auto remoteVersion = readInt(from);
|
|
|
|
return std::min(remoteVersion, localVersion);
|
2024-01-19 23:38:08 +02:00
|
|
|
}
|
|
|
|
|
2022-02-20 21:24:07 +02:00
|
|
|
StorePathSet ServeProto::BasicClientConnection::queryValidPaths(
|
2024-05-23 23:40:05 +03:00
|
|
|
const StoreDirConfig & store, bool lock, const StorePathSet & paths, SubstituteFlag maybeSubstitute)
|
2022-02-20 21:24:07 +02:00
|
|
|
{
|
2024-05-23 23:40:05 +03:00
|
|
|
to << ServeProto::Command::QueryValidPaths << lock << maybeSubstitute;
|
2022-02-20 21:24:07 +02:00
|
|
|
write(store, *this, paths);
|
|
|
|
to.flush();
|
|
|
|
|
|
|
|
return Serialise<StorePathSet>::read(store, *this);
|
|
|
|
}
|
|
|
|
|
2024-05-23 23:40:05 +03:00
|
|
|
std::map<StorePath, UnkeyedValidPathInfo>
|
|
|
|
ServeProto::BasicClientConnection::queryPathInfos(const StoreDirConfig & store, const StorePathSet & paths)
|
2024-05-21 00:41:12 +03:00
|
|
|
{
|
|
|
|
std::map<StorePath, UnkeyedValidPathInfo> infos;
|
|
|
|
|
|
|
|
to << ServeProto::Command::QueryPathInfos;
|
|
|
|
ServeProto::write(store, *this, paths);
|
|
|
|
to.flush();
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
auto storePathS = readString(from);
|
2024-05-23 23:40:05 +03:00
|
|
|
if (storePathS == "")
|
|
|
|
break;
|
2024-05-21 00:41:12 +03:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-02-20 21:24:07 +02:00
|
|
|
void ServeProto::BasicClientConnection::putBuildDerivationRequest(
|
2024-05-23 23:40:05 +03:00
|
|
|
const StoreDirConfig & store,
|
|
|
|
const StorePath & drvPath,
|
|
|
|
const BasicDerivation & drv,
|
2022-02-20 21:24:07 +02:00
|
|
|
const ServeProto::BuildOptions & options)
|
|
|
|
{
|
2024-05-23 23:40:05 +03:00
|
|
|
to << ServeProto::Command::BuildDerivation << store.printStorePath(drvPath);
|
2022-02-20 21:24:07 +02:00
|
|
|
writeDerivation(to, store, drv);
|
|
|
|
|
|
|
|
ServeProto::write(store, *this, options);
|
|
|
|
|
|
|
|
to.flush();
|
|
|
|
}
|
|
|
|
|
2024-05-23 23:40:05 +03:00
|
|
|
BuildResult ServeProto::BasicClientConnection::getBuildDerivationResponse(const StoreDirConfig & store)
|
|
|
|
{
|
|
|
|
return ServeProto::Serialise<BuildResult>::read(store, *this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ServeProto::BasicClientConnection::narFromPath(
|
|
|
|
const StoreDirConfig & store, const StorePath & path, std::function<void(Source &)> fun)
|
|
|
|
{
|
|
|
|
to << ServeProto::Command::DumpStorePath << store.printStorePath(path);
|
|
|
|
to.flush();
|
|
|
|
|
|
|
|
fun(from);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ServeProto::BasicClientConnection::importPaths(const StoreDirConfig & store, std::function<void(Sink &)> fun)
|
|
|
|
{
|
|
|
|
to << ServeProto::Command::ImportPaths;
|
|
|
|
fun(to);
|
|
|
|
to.flush();
|
|
|
|
|
|
|
|
if (readInt(from) != 1)
|
|
|
|
throw Error("remote machine failed to import closure");
|
|
|
|
}
|
|
|
|
|
2022-02-20 21:24:07 +02:00
|
|
|
}
|