2022-03-08 22:21:41 +00:00
# include "serialise.hh"
# include "util.hh"
# include "path-with-outputs.hh"
# include "store-api.hh"
# include "build-result.hh"
# include "worker-protocol.hh"
2022-03-08 21:53:26 +00:00
# include "worker-protocol-impl.hh"
2022-03-08 22:21:41 +00:00
# include "archive.hh"
2024-03-04 03:59:31 +00:00
# include "path-info.hh"
2022-03-08 22:21:41 +00:00
# include <nlohmann/json.hpp>
2023-05-18 02:04:59 +00:00
namespace nix {
2022-03-08 22:21:41 +00:00
2024-03-04 03:24:23 +00:00
/* protocol-specific definitions */
2022-03-08 22:21:41 +00:00
2023-04-17 17:40:46 +00:00
std : : optional < TrustedFlag > WorkerProto : : Serialise < std : : optional < TrustedFlag > > : : read ( const Store & store , WorkerProto : : ReadConn conn )
2022-03-08 22:21:41 +00:00
{
2023-04-17 17:40:46 +00:00
auto temp = readNum < uint8_t > ( conn . from ) ;
2022-03-08 22:21:41 +00:00
switch ( temp ) {
case 0 :
return std : : nullopt ;
case 1 :
return { Trusted } ;
case 2 :
return { NotTrusted } ;
default :
throw Error ( " Invalid trusted status from remote " ) ;
}
}
2023-04-17 17:40:46 +00:00
void WorkerProto : : Serialise < std : : optional < TrustedFlag > > : : write ( const Store & store , WorkerProto : : WriteConn conn , const std : : optional < TrustedFlag > & optTrusted )
2022-03-08 22:21:41 +00:00
{
if ( ! optTrusted )
2023-04-17 17:40:46 +00:00
conn . to < < ( uint8_t ) 0 ;
2022-03-08 22:21:41 +00:00
else {
switch ( * optTrusted ) {
case Trusted :
2023-04-17 17:40:46 +00:00
conn . to < < ( uint8_t ) 1 ;
2022-03-08 22:21:41 +00:00
break ;
case NotTrusted :
2023-04-17 17:40:46 +00:00
conn . to < < ( uint8_t ) 2 ;
2022-03-08 22:21:41 +00:00
break ;
default :
assert ( false ) ;
} ;
}
}
2023-04-17 17:40:46 +00:00
DerivedPath WorkerProto : : Serialise < DerivedPath > : : read ( const Store & store , WorkerProto : : ReadConn conn )
2022-03-08 22:21:41 +00:00
{
2023-04-17 17:40:46 +00:00
auto s = readString ( conn . from ) ;
2024-03-04 03:59:31 +00:00
if ( GET_PROTOCOL_MINOR ( conn . version ) > = 30 ) {
return DerivedPath : : parseLegacy ( store , s ) ;
} else {
return parsePathWithOutputs ( store , s ) . toDerivedPath ( ) ;
}
2022-03-08 22:21:41 +00:00
}
2023-04-17 17:40:46 +00:00
void WorkerProto : : Serialise < DerivedPath > : : write ( const Store & store , WorkerProto : : WriteConn conn , const DerivedPath & req )
2022-03-08 22:21:41 +00:00
{
2024-03-04 03:59:31 +00:00
if ( GET_PROTOCOL_MINOR ( conn . version ) > = 30 ) {
conn . to < < req . to_string_legacy ( store ) ;
} else {
auto sOrDrvPath = StorePathWithOutputs : : tryFromDerivedPath ( req ) ;
std : : visit ( overloaded {
[ & ] ( const StorePathWithOutputs & s ) {
conn . to < < s . to_string ( store ) ;
} ,
[ & ] ( const StorePath & drvPath ) {
throw Error ( " trying to request '%s', but daemon protocol %d.%d is too old (< 1.29) to request a derivation file " ,
store . printStorePath ( drvPath ) ,
GET_PROTOCOL_MAJOR ( conn . version ) ,
GET_PROTOCOL_MINOR ( conn . version ) ) ;
} ,
[ & ] ( std : : monostate ) {
throw Error ( " wanted to build a derivation that is itself a build product, but protocols do not support that. Try upgrading the Nix on the other end of this connection " ) ;
} ,
} , sOrDrvPath ) ;
}
2022-03-08 22:21:41 +00:00
}
2023-04-17 17:40:46 +00:00
KeyedBuildResult WorkerProto : : Serialise < KeyedBuildResult > : : read ( const Store & store , WorkerProto : : ReadConn conn )
2022-03-08 22:21:41 +00:00
{
2023-04-17 17:40:46 +00:00
auto path = WorkerProto : : Serialise < DerivedPath > : : read ( store , conn ) ;
auto br = WorkerProto : : Serialise < BuildResult > : : read ( store , conn ) ;
2022-03-08 22:21:41 +00:00
return KeyedBuildResult {
std : : move ( br ) ,
/* .path = */ std : : move ( path ) ,
} ;
}
2023-04-17 17:40:46 +00:00
void WorkerProto : : Serialise < KeyedBuildResult > : : write ( const Store & store , WorkerProto : : WriteConn conn , const KeyedBuildResult & res )
2022-03-08 22:21:41 +00:00
{
2023-04-17 17:40:46 +00:00
WorkerProto : : write ( store , conn , res . path ) ;
WorkerProto : : write ( store , conn , static_cast < const BuildResult & > ( res ) ) ;
2022-03-08 22:21:41 +00:00
}
2023-04-17 17:40:46 +00:00
BuildResult WorkerProto : : Serialise < BuildResult > : : read ( const Store & store , WorkerProto : : ReadConn conn )
2022-03-08 22:21:41 +00:00
{
BuildResult res ;
2023-04-17 17:40:46 +00:00
res . status = ( BuildResult : : Status ) readInt ( conn . from ) ;
2024-03-04 03:59:31 +00:00
conn . from > > res . errorMsg ;
if ( GET_PROTOCOL_MINOR ( conn . version ) > = 29 ) {
conn . from
> > res . timesBuilt
> > res . isNonDeterministic
> > res . startTime
> > res . stopTime ;
}
if ( GET_PROTOCOL_MINOR ( conn . version ) > = 28 ) {
auto builtOutputs = WorkerProto : : Serialise < DrvOutputs > : : read ( store , conn ) ;
for ( auto & & [ output , realisation ] : builtOutputs )
res . builtOutputs . insert_or_assign (
std : : move ( output . outputName ) ,
std : : move ( realisation ) ) ;
}
2022-03-08 22:21:41 +00:00
return res ;
}
2023-04-17 17:40:46 +00:00
void WorkerProto : : Serialise < BuildResult > : : write ( const Store & store , WorkerProto : : WriteConn conn , const BuildResult & res )
2022-03-08 22:21:41 +00:00
{
2023-04-17 17:40:46 +00:00
conn . to
2022-03-08 22:21:41 +00:00
< < res . status
2024-03-04 03:59:31 +00:00
< < res . errorMsg ;
if ( GET_PROTOCOL_MINOR ( conn . version ) > = 29 ) {
conn . to
< < res . timesBuilt
< < res . isNonDeterministic
< < res . startTime
< < res . stopTime ;
}
if ( GET_PROTOCOL_MINOR ( conn . version ) > = 28 ) {
DrvOutputs builtOutputs ;
for ( auto & [ output , realisation ] : res . builtOutputs )
builtOutputs . insert_or_assign ( realisation . id , realisation ) ;
WorkerProto : : write ( store , conn , builtOutputs ) ;
}
2022-03-08 22:21:41 +00:00
}
2024-03-04 03:59:31 +00:00
ValidPathInfo WorkerProto : : Serialise < ValidPathInfo > : : read ( const Store & store , ReadConn conn )
{
auto path = WorkerProto : : Serialise < StorePath > : : read ( store , conn ) ;
return ValidPathInfo {
std : : move ( path ) ,
WorkerProto : : Serialise < UnkeyedValidPathInfo > : : read ( store , conn ) ,
} ;
}
void WorkerProto : : Serialise < ValidPathInfo > : : write ( const Store & store , WriteConn conn , const ValidPathInfo & pathInfo )
{
WorkerProto : : write ( store , conn , pathInfo . path ) ;
WorkerProto : : write ( store , conn , static_cast < const UnkeyedValidPathInfo & > ( pathInfo ) ) ;
}
UnkeyedValidPathInfo WorkerProto : : Serialise < UnkeyedValidPathInfo > : : read ( const Store & store , ReadConn conn )
{
auto deriver = readString ( conn . from ) ;
auto narHash = Hash : : parseAny ( readString ( conn . from ) , htSHA256 ) ;
UnkeyedValidPathInfo info ( narHash ) ;
if ( deriver ! = " " ) info . deriver = store . parseStorePath ( deriver ) ;
info . references = WorkerProto : : Serialise < StorePathSet > : : read ( store , conn ) ;
conn . from > > info . registrationTime > > info . narSize ;
if ( GET_PROTOCOL_MINOR ( conn . version ) > = 16 ) {
conn . from > > info . ultimate ;
info . sigs = readStrings < StringSet > ( conn . from ) ;
info . ca = ContentAddress : : parseOpt ( readString ( conn . from ) ) ;
}
return info ;
}
void WorkerProto : : Serialise < UnkeyedValidPathInfo > : : write ( const Store & store , WriteConn conn , const UnkeyedValidPathInfo & pathInfo )
{
conn . to
< < ( pathInfo . deriver ? store . printStorePath ( * pathInfo . deriver ) : " " )
< < pathInfo . narHash . to_string ( Base16 , false ) ;
WorkerProto : : write ( store , conn , pathInfo . references ) ;
conn . to < < pathInfo . registrationTime < < pathInfo . narSize ;
if ( GET_PROTOCOL_MINOR ( conn . version ) > = 16 ) {
conn . to
< < pathInfo . ultimate
< < pathInfo . sigs
< < renderContentAddress ( pathInfo . ca ) ;
}
}
2022-03-08 22:21:41 +00:00
}