Start factoring out the serve protocol for Hydra to share

Factor out `ServeProto::BasicClientConnection` for Hydra to share

- `queryValidPaths`: Hydra uses the lock argument differently than Nix,
  so we un-hard-code it.

- `buildDerivationRequest`: Just the request half, as Hydra does some
  things between requesting and responding.

Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
This commit is contained in:
John Ericson 2022-02-20 19:24:07 +00:00
parent 50ce3832dc
commit ce2f714e6d
5 changed files with 107 additions and 61 deletions

View file

@ -22,45 +22,10 @@ std::string LegacySSHStoreConfig::doc()
} }
struct LegacySSHStore::Connection struct LegacySSHStore::Connection : public ServeProto::BasicClientConnection
{ {
std::unique_ptr<SSHMaster::Connection> sshConn; std::unique_ptr<SSHMaster::Connection> sshConn;
FdSink to;
FdSource from;
ServeProto::Version remoteVersion;
bool good = true; bool good = true;
/**
* Coercion to `ServeProto::ReadConn`. This makes it easy to use the
* factored out serve protocol searlizers with a
* `LegacySSHStore::Connection`.
*
* The serve protocol connection types are unidirectional, unlike
* this type.
*/
operator ServeProto::ReadConn ()
{
return ServeProto::ReadConn {
.from = from,
.version = remoteVersion,
};
}
/*
* Coercion to `ServeProto::WriteConn`. This makes it easy to use the
* factored out serve protocol searlizers with a
* `LegacySSHStore::Connection`.
*
* The serve protocol connection types are unidirectional, unlike
* this type.
*/
operator ServeProto::WriteConn ()
{
return ServeProto::WriteConn {
.to = to,
.version = remoteVersion,
};
}
}; };
@ -232,16 +197,16 @@ void LegacySSHStore::narFromPath(const StorePath & path, Sink & sink)
} }
void LegacySSHStore::putBuildSettings(Connection & conn) static ServeProto::BuildOptions buildSettings()
{ {
ServeProto::write(*this, conn, ServeProto::BuildOptions { return {
.maxSilentTime = settings.maxSilentTime, .maxSilentTime = settings.maxSilentTime,
.buildTimeout = settings.buildTimeout, .buildTimeout = settings.buildTimeout,
.maxLogSize = settings.maxLogSize, .maxLogSize = settings.maxLogSize,
.nrRepeats = 0, // buildRepeat hasn't worked for ages anyway .nrRepeats = 0, // buildRepeat hasn't worked for ages anyway
.enforceDeterminism = 0, .enforceDeterminism = 0,
.keepFailed = settings.keepFailed, .keepFailed = settings.keepFailed,
}); };
} }
@ -250,14 +215,7 @@ BuildResult LegacySSHStore::buildDerivation(const StorePath & drvPath, const Bas
{ {
auto conn(connections->get()); auto conn(connections->get());
conn->to conn->putBuildDerivationRequest(*this, drvPath, drv, buildSettings());
<< ServeProto::Command::BuildDerivation
<< printStorePath(drvPath);
writeDerivation(conn->to, *this, drv);
putBuildSettings(*conn);
conn->to.flush();
return ServeProto::Serialise<BuildResult>::read(*this, *conn); return ServeProto::Serialise<BuildResult>::read(*this, *conn);
} }
@ -288,7 +246,7 @@ void LegacySSHStore::buildPaths(const std::vector<DerivedPath> & drvPaths, Build
} }
conn->to << ss; conn->to << ss;
putBuildSettings(*conn); ServeProto::write(*this, *conn, buildSettings());
conn->to.flush(); conn->to.flush();
@ -328,15 +286,8 @@ StorePathSet LegacySSHStore::queryValidPaths(const StorePathSet & paths,
SubstituteFlag maybeSubstitute) SubstituteFlag maybeSubstitute)
{ {
auto conn(connections->get()); auto conn(connections->get());
return conn->queryValidPaths(*this,
conn->to false, paths, maybeSubstitute);
<< ServeProto::Command::QueryValidPaths
<< false // lock
<< maybeSubstitute;
ServeProto::write(*this, *conn, paths);
conn->to.flush();
return ServeProto::Serialise<StorePathSet>::read(*this, *conn);
} }

View file

@ -78,10 +78,6 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor
RepairFlag repair = NoRepair) override RepairFlag repair = NoRepair) override
{ unsupported("addToStore"); } { unsupported("addToStore"); }
private:
void putBuildSettings(Connection & conn);
public: public:
BuildResult buildDerivation(const StorePath & drvPath, const BasicDerivation & drv, BuildResult buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,

View file

@ -0,0 +1,38 @@
#include "serve-protocol-impl.hh"
#include "build-result.hh"
#include "derivations.hh"
namespace nix {
StorePathSet ServeProto::BasicClientConnection::queryValidPaths(
const Store & store,
bool lock, const StorePathSet & paths,
SubstituteFlag maybeSubstitute)
{
to
<< ServeProto::Command::QueryValidPaths
<< lock
<< maybeSubstitute;
write(store, *this, paths);
to.flush();
return Serialise<StorePathSet>::read(store, *this);
}
void ServeProto::BasicClientConnection::putBuildDerivationRequest(
const Store & store,
const StorePath & drvPath, const BasicDerivation & drv,
const ServeProto::BuildOptions & options)
{
to
<< ServeProto::Command::BuildDerivation
<< store.printStorePath(drvPath);
writeDerivation(to, store, drv);
ServeProto::write(store, *this, options);
to.flush();
}
}

View file

@ -10,6 +10,7 @@
#include "serve-protocol.hh" #include "serve-protocol.hh"
#include "length-prefixed-protocol-helper.hh" #include "length-prefixed-protocol-helper.hh"
#include "store-api.hh"
namespace nix { namespace nix {
@ -56,4 +57,57 @@ struct ServeProto::Serialise
/* protocol-specific templates */ /* protocol-specific templates */
struct ServeProto::BasicClientConnection
{
FdSink to;
FdSource from;
ServeProto::Version remoteVersion;
/**
* Coercion to `ServeProto::ReadConn`. This makes it easy to use the
* factored out serve protocol serializers with a
* `LegacySSHStore::Connection`.
*
* The serve protocol connection types are unidirectional, unlike
* this type.
*/
operator ServeProto::ReadConn ()
{
return ServeProto::ReadConn {
.from = from,
.version = remoteVersion,
};
}
/**
* Coercion to `ServeProto::WriteConn`. This makes it easy to use the
* factored out serve protocol serializers with a
* `LegacySSHStore::Connection`.
*
* The serve protocol connection types are unidirectional, unlike
* this type.
*/
operator ServeProto::WriteConn ()
{
return ServeProto::WriteConn {
.to = to,
.version = remoteVersion,
};
}
StorePathSet queryValidPaths(
const Store & remoteStore,
bool lock, const StorePathSet & paths,
SubstituteFlag maybeSubstitute);
/**
* Just the request half, because Hydra may do other things between
* issuing the request and reading the `BuildResult` response.
*/
void putBuildDerivationRequest(
const Store & store,
const StorePath & drvPath, const BasicDerivation & drv,
const ServeProto::BuildOptions & options);
};
} }

View file

@ -59,6 +59,13 @@ struct ServeProto
Version version; Version version;
}; };
/**
* Stripped down serialization logic suitable for sharing with Hydra.
*
* @todo remove once Hydra uses Store abstraction consistently.
*/
struct BasicClientConnection;
/** /**
* Data type for canonical pairs of serialisers for the serve protocol. * Data type for canonical pairs of serialisers for the serve protocol.
* *