2023-03-22 15:23:36 +02:00
# include "ssh-store-config.hh"
2017-02-07 20:28:40 +02:00
# include "archive.hh"
# include "pool.hh"
# include "remote-store.hh"
# include "serve-protocol.hh"
2022-03-01 21:43:07 +02:00
# include "build-result.hh"
2017-02-07 20:28:40 +02:00
# include "store-api.hh"
2021-03-02 05:50:41 +02:00
# include "path-with-outputs.hh"
2017-02-07 20:28:40 +02:00
# include "worker-protocol.hh"
2017-03-03 20:05:50 +02:00
# include "ssh.hh"
2017-05-01 17:08:13 +03:00
# include "derivations.hh"
2020-09-21 19:40:11 +03:00
# include "callback.hh"
2017-02-07 20:28:40 +02:00
namespace nix {
2023-03-22 15:23:36 +02:00
struct LegacySSHStoreConfig : virtual CommonSSHStoreConfig
2017-02-07 20:28:40 +02:00
{
2023-03-22 15:23:36 +02:00
using CommonSSHStoreConfig : : CommonSSHStoreConfig ;
2023-03-23 10:35:35 +02:00
const Setting < Path > remoteProgram { ( StoreConfig * ) this , " nix-store " , " remote-program " ,
" Path to the `nix-store` executable on the remote machine. " } ;
2023-03-22 15:23:36 +02:00
const Setting < int > maxConnections { ( StoreConfig * ) this , 1 , " max-connections " ,
" Maximum number of concurrent SSH connections. " } ;
2020-09-14 15:04:02 +03:00
2023-03-21 15:03:05 +02:00
const std : : string name ( ) override { return " SSH Store " ; }
std : : string doc ( ) override
{
return
# include "legacy-ssh-store.md"
;
}
2020-09-10 11:55:51 +03:00
} ;
2017-04-13 16:55:38 +03:00
2020-12-20 17:33:12 +02:00
struct LegacySSHStore : public virtual LegacySSHStoreConfig , public virtual Store
2020-09-10 11:55:51 +03:00
{
2017-05-02 13:01:46 +03:00
// Hack for getting remote build log output.
2020-09-15 10:10:37 +03:00
// Intentionally not in `LegacySSHStoreConfig` so that it doesn't appear in
// the documentation
const Setting < int > logFD { ( StoreConfig * ) this , - 1 , " log-fd " , " file descriptor to which SSH's stderr is connected " } ;
2017-05-02 13:01:46 +03:00
2017-02-07 20:28:40 +02:00
struct Connection
{
2017-03-03 20:05:50 +02:00
std : : unique_ptr < SSHMaster : : Connection > sshConn ;
2017-02-07 20:28:40 +02:00
FdSink to ;
FdSource from ;
2017-05-01 17:08:13 +03:00
int remoteVersion ;
2018-08-03 22:10:03 +03:00
bool good = true ;
2017-02-07 20:28:40 +02:00
} ;
2017-03-03 20:05:50 +02:00
std : : string host ;
2017-02-07 20:28:40 +02:00
ref < Pool < Connection > > connections ;
2017-03-03 20:05:50 +02:00
SSHMaster master ;
2017-02-07 20:28:40 +02:00
2020-09-11 12:11:05 +03:00
static std : : set < std : : string > uriSchemes ( ) { return { " ssh " } ; }
2020-09-08 15:50:23 +03:00
2022-02-25 17:00:00 +02:00
LegacySSHStore ( const std : : string & scheme , const std : : string & host , const Params & params )
2020-09-11 12:06:18 +03:00
: StoreConfig ( params )
2023-03-23 10:11:15 +02:00
, CommonSSHStoreConfig ( params )
2020-12-20 17:33:12 +02:00
, LegacySSHStoreConfig ( params )
2020-09-10 11:55:51 +03:00
, Store ( params )
2017-02-07 20:28:40 +02:00
, host ( host )
, connections ( make_ref < Pool < Connection > > (
2017-04-13 16:55:38 +03:00
std : : max ( 1 , ( int ) maxConnections ) ,
2017-02-07 20:28:40 +02:00
[ this ] ( ) { return openConnection ( ) ; } ,
2018-08-03 22:10:03 +03:00
[ ] ( const ref < Connection > & r ) { return r - > good ; }
2017-02-07 20:28:40 +02:00
) )
2017-03-03 20:05:50 +02:00
, master (
host ,
2017-04-13 16:55:38 +03:00
sshKey ,
2021-02-25 03:52:22 +02:00
sshPublicHostKey ,
2017-03-03 20:05:50 +02:00
// Use SSH master only if using more than 1 connection.
connections - > capacity ( ) > 1 ,
2017-05-02 13:01:46 +03:00
compress ,
logFD )
2017-02-07 20:28:40 +02:00
{
}
ref < Connection > openConnection ( )
{
auto conn = make_ref < Connection > ( ) ;
2018-08-03 19:07:46 +03:00
conn - > sshConn = master . startCommand (
2018-08-06 18:27:08 +03:00
fmt ( " %s --serve --write " , remoteProgram )
2018-08-03 19:07:46 +03:00
+ ( remoteStore . get ( ) = = " " ? " " : " --store " + shellEscape ( remoteStore . get ( ) ) ) ) ;
2017-03-03 20:05:50 +02:00
conn - > to = FdSink ( conn - > sshConn - > in . get ( ) ) ;
conn - > from = FdSource ( conn - > sshConn - > out . get ( ) ) ;
2017-02-07 20:28:40 +02:00
try {
conn - > to < < SERVE_MAGIC_1 < < SERVE_PROTOCOL_VERSION ;
conn - > to . flush ( ) ;
2021-09-23 18:48:52 +03:00
StringSink saved ;
try {
TeeSource tee ( conn - > from , saved ) ;
unsigned int magic = readInt ( tee ) ;
if ( magic ! = SERVE_MAGIC_2 )
throw Error ( " 'nix-store --serve' protocol mismatch from '%s' " , host ) ;
} catch ( SerialisationError & e ) {
2021-09-23 19:01:04 +03:00
/* In case the other side is waiting for our input,
close it . */
2021-09-23 18:48:52 +03:00
conn - > sshConn - > in . close ( ) ;
auto msg = conn - > from . drain ( ) ;
throw Error ( " 'nix-store --serve' protocol mismatch from '%s', got '%s' " ,
2022-01-17 23:20:05 +02:00
host , chomp ( saved . s + msg ) ) ;
2021-09-23 18:48:52 +03:00
}
2017-05-01 17:08:13 +03:00
conn - > remoteVersion = readInt ( conn - > from ) ;
if ( GET_PROTOCOL_MAJOR ( conn - > remoteVersion ) ! = 0x200 )
2017-07-30 14:27:57 +03:00
throw Error ( " unsupported 'nix-store --serve' protocol version on '%s' " , host ) ;
2017-02-07 20:28:40 +02:00
} catch ( EndOfFile & e ) {
2017-07-30 14:27:57 +03:00
throw Error ( " cannot connect to '%1%' " , host ) ;
2017-02-07 20:28:40 +02:00
}
return conn ;
} ;
2022-02-25 17:00:00 +02:00
std : : string getUri ( ) override
2017-02-07 20:28:40 +02:00
{
2020-09-11 12:11:05 +03:00
return * uriSchemes ( ) . begin ( ) + " :// " + host ;
2017-02-07 20:28:40 +02:00
}
2019-12-05 20:11:09 +02:00
void queryPathInfoUncached ( const StorePath & path ,
2018-09-25 19:54:16 +03:00
Callback < std : : shared_ptr < const ValidPathInfo > > callback ) noexcept override
2017-02-07 20:28:40 +02:00
{
2018-03-27 23:16:01 +03:00
try {
2017-02-07 20:28:40 +02:00
auto conn ( connections - > get ( ) ) ;
2020-08-06 21:31:48 +03:00
/* No longer support missing NAR hash */
assert ( GET_PROTOCOL_MINOR ( conn - > remoteVersion ) > = 4 ) ;
2019-12-05 20:11:09 +02:00
debug ( " querying remote host '%s' for info on '%s' " , host , printStorePath ( path ) ) ;
2017-02-07 20:28:40 +02:00
2019-12-05 20:11:09 +02:00
conn - > to < < cmdQueryPathInfos < < PathSet { printStorePath ( path ) } ;
2017-02-07 20:28:40 +02:00
conn - > to . flush ( ) ;
2019-12-05 20:11:09 +02:00
auto p = readString ( conn - > from ) ;
if ( p . empty ( ) ) return callback ( nullptr ) ;
2020-08-06 21:31:48 +03:00
auto path2 = parseStorePath ( p ) ;
assert ( path = = path2 ) ;
/* Hash will be set below. FIXME construct ValidPathInfo at end. */
auto info = std : : make_shared < ValidPathInfo > ( path , Hash : : dummy ) ;
2017-02-07 20:28:40 +02:00
2019-12-05 20:11:09 +02:00
auto deriver = readString ( conn - > from ) ;
if ( deriver ! = " " )
info - > deriver = parseStorePath ( deriver ) ;
2023-05-18 05:04:59 +03:00
info - > references = WorkerProto < StorePathSet > : : read ( * this , conn - > from ) ;
2017-02-07 20:28:40 +02:00
readLongLong ( conn - > from ) ; // download size
info - > narSize = readLongLong ( conn - > from ) ;
2020-08-06 21:31:48 +03:00
{
2017-09-08 17:55:27 +03:00
auto s = readString ( conn - > from ) ;
2020-08-06 21:31:48 +03:00
if ( s = = " " )
throw Error ( " NAR hash is now mandatory " ) ;
info - > narHash = Hash : : parseAnyPrefixed ( s ) ;
2017-09-08 17:55:27 +03:00
}
2023-03-31 00:12:49 +03:00
info - > ca = ContentAddress : : parseOpt ( readString ( conn - > from ) ) ;
2020-08-06 21:31:48 +03:00
info - > sigs = readStrings < StringSet > ( conn - > from ) ;
2017-09-08 17:55:27 +03:00
2017-02-07 20:28:40 +02:00
auto s = readString ( conn - > from ) ;
assert ( s = = " " ) ;
2018-03-27 23:16:01 +03:00
callback ( std : : move ( info ) ) ;
} catch ( . . . ) { callback . rethrow ( ) ; }
2017-02-07 20:28:40 +02:00
}
2018-03-22 00:12:22 +02:00
void addToStore ( const ValidPathInfo & info , Source & source ,
2020-07-13 18:37:44 +03:00
RepairFlag repair , CheckSigsFlag checkSigs ) override
2017-02-07 20:28:40 +02:00
{
2019-12-05 20:11:09 +02:00
debug ( " adding path '%s' to remote host '%s' " , printStorePath ( info . path ) , host ) ;
2017-02-07 20:28:40 +02:00
auto conn ( connections - > get ( ) ) ;
2018-08-31 02:00:01 +03:00
if ( GET_PROTOCOL_MINOR ( conn - > remoteVersion ) > = 5 ) {
2018-08-03 22:10:03 +03:00
conn - > to
< < cmdAddToStoreNar
2019-12-05 20:11:09 +02:00
< < printStorePath ( info . path )
< < ( info . deriver ? printStorePath ( * info . deriver ) : " " )
2020-08-05 21:42:48 +03:00
< < info . narHash . to_string ( Base16 , false ) ;
2023-05-18 05:04:59 +03:00
workerProtoWrite ( * this , conn - > to , info . references ) ;
2019-12-05 20:11:09 +02:00
conn - > to
2018-08-03 22:10:03 +03:00
< < info . registrationTime
< < info . narSize
< < info . ultimate
< < info . sigs
2020-06-02 03:37:43 +03:00
< < renderContentAddress ( info . ca ) ;
2018-08-03 22:10:03 +03:00
try {
copyNAR ( source , conn - > to ) ;
} catch ( . . . ) {
conn - > good = false ;
throw ;
}
conn - > to . flush ( ) ;
} else {
conn - > to
< < cmdImportPaths
< < 1 ;
try {
copyNAR ( source , conn - > to ) ;
} catch ( . . . ) {
conn - > good = false ;
throw ;
}
conn - > to
< < exportMagic
2019-12-05 20:11:09 +02:00
< < printStorePath ( info . path ) ;
2023-05-18 05:04:59 +03:00
workerProtoWrite ( * this , conn - > to , info . references ) ;
2019-12-05 20:11:09 +02:00
conn - > to
< < ( info . deriver ? printStorePath ( * info . deriver ) : " " )
2018-08-03 22:10:03 +03:00
< < 0
< < 0 ;
conn - > to . flush ( ) ;
}
2017-02-07 20:28:40 +02:00
if ( readInt ( conn - > from ) ! = 1 )
2019-12-05 20:11:09 +02:00
throw Error ( " failed to add path '%s' to remote host '%s' " , printStorePath ( info . path ) , host ) ;
2017-02-07 20:28:40 +02:00
}
2019-12-05 20:11:09 +02:00
void narFromPath ( const StorePath & path , Sink & sink ) override
2017-02-07 20:28:40 +02:00
{
auto conn ( connections - > get ( ) ) ;
2019-12-05 20:11:09 +02:00
conn - > to < < cmdDumpStorePath < < printStorePath ( path ) ;
2017-02-07 20:28:40 +02:00
conn - > to . flush ( ) ;
2018-03-21 23:56:02 +02:00
copyNAR ( conn - > from , sink ) ;
2017-02-07 20:28:40 +02:00
}
2019-12-05 20:11:09 +02:00
std : : optional < StorePath > queryPathFromHashPart ( const std : : string & hashPart ) override
2019-01-18 14:34:23 +02:00
{ unsupported ( " queryPathFromHashPart " ) ; }
2017-02-07 20:28:40 +02:00
2022-02-25 17:00:00 +02:00
StorePath addToStore (
std : : string_view name ,
const Path & srcPath ,
FileIngestionMethod method ,
HashType hashAlgo ,
PathFilter & filter ,
RepairFlag repair ,
const StorePathSet & references ) override
2019-01-18 14:34:23 +02:00
{ unsupported ( " addToStore " ) ; }
2017-02-07 20:28:40 +02:00
2022-02-25 17:00:00 +02:00
StorePath addTextToStore (
std : : string_view name ,
std : : string_view s ,
const StorePathSet & references ,
RepairFlag repair ) override
2019-01-18 14:34:23 +02:00
{ unsupported ( " addTextToStore " ) ; }
2017-02-07 20:28:40 +02:00
2020-08-12 06:13:17 +03:00
private :
void putBuildSettings ( Connection & conn )
{
conn . to
< < settings . maxSilentTime
< < settings . buildTimeout ;
if ( GET_PROTOCOL_MINOR ( conn . remoteVersion ) > = 2 )
conn . to
< < settings . maxLogSize ;
if ( GET_PROTOCOL_MINOR ( conn . remoteVersion ) > = 3 )
conn . to
2022-09-26 21:55:56 +03:00
< < 0 // buildRepeat hasn't worked for ages anyway
< < 0 ;
2021-08-24 00:47:29 +03:00
if ( GET_PROTOCOL_MINOR ( conn . remoteVersion ) > = 7 ) {
conn . to < < ( ( int ) settings . keepFailed ) ;
}
2020-08-12 06:13:17 +03:00
}
public :
2019-12-05 20:11:09 +02:00
BuildResult buildDerivation ( const StorePath & drvPath , const BasicDerivation & drv ,
2017-02-07 20:28:40 +02:00
BuildMode buildMode ) override
2017-05-01 17:08:13 +03:00
{
auto conn ( connections - > get ( ) ) ;
conn - > to
< < cmdBuildDerivation
2019-12-05 20:11:09 +02:00
< < printStorePath ( drvPath ) ;
writeDerivation ( conn - > to , * this , drv ) ;
2020-08-12 06:13:17 +03:00
putBuildSettings ( * conn ) ;
2017-05-01 17:08:13 +03:00
conn - > to . flush ( ) ;
Make `KeyedBuildResult`, `BuildResult` like before, and fix bug another way
In https://github.com/NixOS/nix/pull/6311#discussion_r834863823, I
realized since derivation goals' wanted outputs can "grow" due to
overlapping dependencies (See `DerivationGoal::addWantedOutputs`, called
by `Worker::makeDerivationGoalCommon`), the previous bug fix had an
unfortunate side effect of causing more pointless rebuilds.
In paticular, we have this situation:
1. Goal made from `DerivedPath::Built { foo, {a} }`.
2. Goal gives on on substituting, starts building.
3. Goal made from `DerivedPath::Built { foo, {b} }`, in fact is just
modified original goal.
4. Though the goal had gotten as far as building, so all outputs were
going to be produced, `addWantedOutputs` no longer knows that and so
the goal is flagged to be restarted.
This might sound far-fetched with input-addressed drvs, where we usually
basically have all our goals "planned out" before we start doing
anything, but with CA derivation goals and especially RFC 92, where *drv
resolution* means goals are created after some building is completed, it
is more likely to happen.
So the first thing to do was restore the clearing of `wantedOutputs` we
used to do, and then filter the outputs in `buildPathsWithResults` to
only get the ones we care about.
But fix also has its own side effect in that the `DerivedPath` in the
`BuildResult` in `DerivationGoal` cannot be trusted; it is merely the
*first* `DerivedPath` for which this goal was originally created.
To remedy this, I made `BuildResult` be like it was before, and instead
made `KeyedBuildResult` be a subclass wit the path. Only
`buildPathsWithResults` returns `KeyedBuildResult`s, everything else
just becomes like it was before, where the "key" is unambiguous from
context.
I think separating the "primary key" field(s) from the other fields is
good practical in general anyways. (I would like to do the same thing
for `ValidPathInfo`.) Among other things, it allows constructions like
`std::map<Key, ThingWithKey>` where doesn't contain duplicate keys and
just precludes the possibility of those duplicate keys being out of
sync.
We might leverage the above someday to overload `buildPathsWithResults`
to take a *set* of return a *map* per the above.
-----
Unfortunately, we need to avoid C++20 strictness on designated
initializers.
(BTW
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2287r1.html
this offers some new syntax for this use-case. Hopefully this will be
adopted and we can eventually use it.)
No having that yet, maybe it would be better to not make
`KeyedBuildResult` a subclass to just avoid this.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
2022-03-25 03:26:07 +02:00
BuildResult status ;
2017-05-01 17:08:13 +03:00
status . status = ( BuildResult : : Status ) readInt ( conn - > from ) ;
conn - > from > > status . errorMsg ;
if ( GET_PROTOCOL_MINOR ( conn - > remoteVersion ) > = 3 )
conn - > from > > status . timesBuilt > > status . isNonDeterministic > > status . startTime > > status . stopTime ;
2021-01-26 11:50:44 +02:00
if ( GET_PROTOCOL_MINOR ( conn - > remoteVersion ) > = 6 ) {
2023-05-18 05:04:59 +03:00
auto builtOutputs = WorkerProto < DrvOutputs > : : read ( * this , conn - > from ) ;
2023-04-15 01:18:32 +03:00
for ( auto & & [ output , realisation ] : builtOutputs )
status . builtOutputs . insert_or_assign (
std : : move ( output . outputName ) ,
std : : move ( realisation ) ) ;
2021-01-26 11:50:44 +02:00
}
2017-05-01 17:08:13 +03:00
return status ;
}
2017-02-07 20:28:40 +02:00
2021-07-19 16:43:08 +03:00
void buildPaths ( const std : : vector < DerivedPath > & drvPaths , BuildMode buildMode , std : : shared_ptr < Store > evalStore ) override
2020-08-12 06:13:17 +03:00
{
2021-07-19 16:43:08 +03:00
if ( evalStore & & evalStore . get ( ) ! = this )
throw Error ( " building on an SSH store is incompatible with '--eval-store' " ) ;
2020-08-12 06:13:17 +03:00
auto conn ( connections - > get ( ) ) ;
conn - > to < < cmdBuildPaths ;
Strings ss ;
2021-03-02 05:50:41 +02:00
for ( auto & p : drvPaths ) {
2021-04-05 16:48:18 +03:00
auto sOrDrvPath = StorePathWithOutputs : : tryFromDerivedPath ( p ) ;
2021-03-02 05:50:41 +02:00
std : : visit ( overloaded {
2021-10-01 00:31:21 +03:00
[ & ] ( const StorePathWithOutputs & s ) {
2021-03-02 05:50:41 +02:00
ss . push_back ( s . to_string ( * this ) ) ;
} ,
2021-10-01 00:31:21 +03:00
[ & ] ( const StorePath & drvPath ) {
2021-03-02 05:50:41 +02:00
throw Error ( " wanted to fetch '%s' but the legacy ssh protocol doesn't support merely substituting drv files via the build paths command. It would build them instead. Try using ssh-ng:// " , printStorePath ( drvPath ) ) ;
} ,
} , sOrDrvPath ) ;
}
2020-08-12 06:13:17 +03:00
conn - > to < < ss ;
putBuildSettings ( * conn ) ;
conn - > to . flush ( ) ;
Make `KeyedBuildResult`, `BuildResult` like before, and fix bug another way
In https://github.com/NixOS/nix/pull/6311#discussion_r834863823, I
realized since derivation goals' wanted outputs can "grow" due to
overlapping dependencies (See `DerivationGoal::addWantedOutputs`, called
by `Worker::makeDerivationGoalCommon`), the previous bug fix had an
unfortunate side effect of causing more pointless rebuilds.
In paticular, we have this situation:
1. Goal made from `DerivedPath::Built { foo, {a} }`.
2. Goal gives on on substituting, starts building.
3. Goal made from `DerivedPath::Built { foo, {b} }`, in fact is just
modified original goal.
4. Though the goal had gotten as far as building, so all outputs were
going to be produced, `addWantedOutputs` no longer knows that and so
the goal is flagged to be restarted.
This might sound far-fetched with input-addressed drvs, where we usually
basically have all our goals "planned out" before we start doing
anything, but with CA derivation goals and especially RFC 92, where *drv
resolution* means goals are created after some building is completed, it
is more likely to happen.
So the first thing to do was restore the clearing of `wantedOutputs` we
used to do, and then filter the outputs in `buildPathsWithResults` to
only get the ones we care about.
But fix also has its own side effect in that the `DerivedPath` in the
`BuildResult` in `DerivationGoal` cannot be trusted; it is merely the
*first* `DerivedPath` for which this goal was originally created.
To remedy this, I made `BuildResult` be like it was before, and instead
made `KeyedBuildResult` be a subclass wit the path. Only
`buildPathsWithResults` returns `KeyedBuildResult`s, everything else
just becomes like it was before, where the "key" is unambiguous from
context.
I think separating the "primary key" field(s) from the other fields is
good practical in general anyways. (I would like to do the same thing
for `ValidPathInfo`.) Among other things, it allows constructions like
`std::map<Key, ThingWithKey>` where doesn't contain duplicate keys and
just precludes the possibility of those duplicate keys being out of
sync.
We might leverage the above someday to overload `buildPathsWithResults`
to take a *set* of return a *map* per the above.
-----
Unfortunately, we need to avoid C++20 strictness on designated
initializers.
(BTW
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2287r1.html
this offers some new syntax for this use-case. Hopefully this will be
adopted and we can eventually use it.)
No having that yet, maybe it would be better to not make
`KeyedBuildResult` a subclass to just avoid this.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
2022-03-25 03:26:07 +02:00
BuildResult result ;
2020-08-12 06:13:17 +03:00
result . status = ( BuildResult : : Status ) readInt ( conn - > from ) ;
if ( ! result . success ( ) ) {
conn - > from > > result . errorMsg ;
throw Error ( result . status , result . errorMsg ) ;
}
}
2019-12-05 20:11:09 +02:00
void ensurePath ( const StorePath & path ) override
2019-01-18 14:34:23 +02:00
{ unsupported ( " ensurePath " ) ; }
2017-02-07 20:28:40 +02:00
2023-04-13 20:38:12 +03:00
virtual ref < FSAccessor > getFSAccessor ( ) override
{ unsupported ( " getFSAccessor " ) ; }
2023-04-13 17:38:35 +03:00
/**
* The default instance would schedule the work on the client side , but
* for consistency with ` buildPaths ` and ` buildDerivation ` it should happen
* on the remote side .
*
* We make this fail for now so we can add implement this properly later
* without it being a breaking change .
*/
void repairPath ( const StorePath & path ) override
{ unsupported ( " repairPath " ) ; }
2019-12-05 20:11:09 +02:00
void computeFSClosure ( const StorePathSet & paths ,
StorePathSet & out , bool flipDirection = false ,
2017-03-16 12:44:01 +02:00
bool includeOutputs = false , bool includeDerivers = false ) override
{
if ( flipDirection | | includeDerivers ) {
Store : : computeFSClosure ( paths , out , flipDirection , includeOutputs , includeDerivers ) ;
return ;
}
auto conn ( connections - > get ( ) ) ;
conn - > to
< < cmdQueryClosure
2019-12-05 20:11:09 +02:00
< < includeOutputs ;
2023-05-18 05:04:59 +03:00
workerProtoWrite ( * this , conn - > to , paths ) ;
2017-03-16 12:44:01 +02:00
conn - > to . flush ( ) ;
2023-05-18 05:04:59 +03:00
for ( auto & i : WorkerProto < StorePathSet > : : read ( * this , conn - > from ) )
2020-06-16 23:20:18 +03:00
out . insert ( i ) ;
2017-03-16 12:44:01 +02:00
}
2019-12-05 20:11:09 +02:00
StorePathSet queryValidPaths ( const StorePathSet & paths ,
2017-06-28 19:11:01 +03:00
SubstituteFlag maybeSubstitute = NoSubstitute ) override
2017-03-16 14:50:01 +02:00
{
auto conn ( connections - > get ( ) ) ;
conn - > to
< < cmdQueryValidPaths
< < false // lock
2019-12-05 20:11:09 +02:00
< < maybeSubstitute ;
2023-05-18 05:04:59 +03:00
workerProtoWrite ( * this , conn - > to , paths ) ;
2017-03-16 14:50:01 +02:00
conn - > to . flush ( ) ;
2023-05-18 05:04:59 +03:00
return WorkerProto < StorePathSet > : : read ( * this , conn - > from ) ;
2017-03-16 14:50:01 +02:00
}
2017-05-02 15:18:46 +03:00
void connect ( ) override
{
auto conn ( connections - > get ( ) ) ;
}
2018-08-31 00:28:47 +03:00
unsigned int getProtocol ( ) override
{
auto conn ( connections - > get ( ) ) ;
return conn - > remoteVersion ;
}
2020-10-08 18:36:51 +03:00
2022-12-26 22:21:08 +02:00
/**
* The legacy ssh protocol doesn ' t support checking for trusted - user .
* Try using ssh - ng : // instead if you want to know.
*/
std : : optional < TrustedFlag > isTrustedClient ( ) override
{
return std : : nullopt ;
}
2021-10-27 12:36:51 +03:00
void queryRealisationUncached ( const DrvOutput & ,
Callback < std : : shared_ptr < const Realisation > > callback ) noexcept override
2020-10-08 18:36:51 +03:00
// TODO: Implement
{ unsupported ( " queryRealisation " ) ; }
2017-02-07 20:28:40 +02:00
} ;
2020-10-06 14:36:55 +03:00
static RegisterStoreImplementation < LegacySSHStore , LegacySSHStoreConfig > regLegacySSHStore ;
2017-02-07 20:28:40 +02:00
}