2023-03-22 13:23:36 +00:00
# include "ssh-store-config.hh"
2017-02-07 18:28:40 +00:00
# include "archive.hh"
# include "pool.hh"
# include "remote-store.hh"
# include "serve-protocol.hh"
2024-03-04 03:35:39 +00:00
# include "serve-protocol-impl.hh"
2022-03-01 19:43:07 +00:00
# include "build-result.hh"
2017-02-07 18:28:40 +00:00
# include "store-api.hh"
2021-03-02 03:50:41 +00:00
# include "path-with-outputs.hh"
2017-03-03 18:05:50 +00:00
# include "ssh.hh"
2017-05-01 14:08:13 +00:00
# include "derivations.hh"
2020-09-21 16:40:11 +00:00
# include "callback.hh"
2017-02-07 18:28:40 +00:00
namespace nix {
2023-03-22 13:23:36 +00:00
struct LegacySSHStoreConfig : virtual CommonSSHStoreConfig
2017-02-07 18:28:40 +00:00
{
2023-03-22 13:23:36 +00:00
using CommonSSHStoreConfig : : CommonSSHStoreConfig ;
2024-03-04 04:24:33 +00:00
const Setting < Path > remoteProgram { this , " nix-store " , " remote-program " ,
2023-03-23 08:35:35 +00:00
" Path to the `nix-store` executable on the remote machine. " } ;
2024-03-04 04:24:33 +00:00
const Setting < int > maxConnections { this , 1 , " max-connections " ,
2023-03-22 13:23:36 +00:00
" Maximum number of concurrent SSH connections. " } ;
2020-09-14 12:04:02 +00:00
2023-03-21 13:03:05 +00:00
const std : : string name ( ) override { return " SSH Store " ; }
std : : string doc ( ) override
{
return
# include "legacy-ssh-store.md"
;
}
2020-09-10 08:55:51 +00:00
} ;
2017-04-13 13:55:38 +00:00
2020-12-20 15:33:12 +00:00
struct LegacySSHStore : public virtual LegacySSHStoreConfig , public virtual Store
2020-09-10 08:55:51 +00:00
{
2017-05-02 10:01:46 +00:00
// Hack for getting remote build log output.
2020-09-15 07:10:37 +00:00
// Intentionally not in `LegacySSHStoreConfig` so that it doesn't appear in
// the documentation
2024-03-04 04:24:33 +00:00
const Setting < int > logFD { this , - 1 , " log-fd " , " file descriptor to which SSH's stderr is connected " } ;
2017-05-02 10:01:46 +00:00
2017-02-07 18:28:40 +00:00
struct Connection
{
2017-03-03 18:05:50 +00:00
std : : unique_ptr < SSHMaster : : Connection > sshConn ;
2017-02-07 18:28:40 +00:00
FdSink to ;
FdSource from ;
2023-10-20 13:34:26 +00:00
ServeProto : : Version remoteVersion ;
2018-08-03 19:10:03 +00:00
bool good = true ;
2023-04-17 17:40:46 +00:00
/**
2024-03-04 03:35:39 +00:00
* Coercion to ` ServeProto : : ReadConn ` . This makes it easy to use the
* factored out serve protocol searlizers with a
2023-04-17 17:40:46 +00:00
* ` LegacySSHStore : : Connection ` .
*
2024-03-04 03:35:39 +00:00
* The serve protocol connection types are unidirectional , unlike
2023-04-17 17:40:46 +00:00
* this type .
*/
2024-03-04 03:35:39 +00:00
operator ServeProto : : ReadConn ( )
2023-04-17 17:40:46 +00:00
{
2024-03-04 03:35:39 +00:00
return ServeProto : : ReadConn {
2023-04-17 17:40:46 +00:00
. from = from ,
2023-10-20 13:34:26 +00:00
. version = remoteVersion ,
2023-04-17 17:40:46 +00:00
} ;
}
/*
2024-03-04 03:35:39 +00:00
* Coercion to ` ServeProto : : WriteConn ` . This makes it easy to use the
* factored out serve protocol searlizers with a
2023-04-17 17:40:46 +00:00
* ` LegacySSHStore : : Connection ` .
*
2024-03-04 03:35:39 +00:00
* The serve protocol connection types are unidirectional , unlike
2023-04-17 17:40:46 +00:00
* this type .
*/
2024-03-04 03:35:39 +00:00
operator ServeProto : : WriteConn ( )
2023-04-17 17:40:46 +00:00
{
2024-03-04 03:35:39 +00:00
return ServeProto : : WriteConn {
2023-04-17 17:40:46 +00:00
. to = to ,
2023-10-20 13:34:26 +00:00
. version = remoteVersion ,
2023-04-17 17:40:46 +00:00
} ;
}
2017-02-07 18:28:40 +00:00
} ;
2017-03-03 18:05:50 +00:00
std : : string host ;
2017-02-07 18:28:40 +00:00
ref < Pool < Connection > > connections ;
2017-03-03 18:05:50 +00:00
SSHMaster master ;
2017-02-07 18:28:40 +00:00
2020-09-11 09:11:05 +00:00
static std : : set < std : : string > uriSchemes ( ) { return { " ssh " } ; }
2020-09-08 12:50:23 +00:00
2022-02-25 15:00:00 +00:00
LegacySSHStore ( const std : : string & scheme , const std : : string & host , const Params & params )
2020-09-11 09:06:18 +00:00
: StoreConfig ( params )
2023-03-23 08:11:15 +00:00
, CommonSSHStoreConfig ( params )
2020-12-20 15:33:12 +00:00
, LegacySSHStoreConfig ( params )
2020-09-10 08:55:51 +00:00
, Store ( params )
2017-02-07 18:28:40 +00:00
, host ( host )
, connections ( make_ref < Pool < Connection > > (
2017-04-13 13:55:38 +00:00
std : : max ( 1 , ( int ) maxConnections ) ,
2017-02-07 18:28:40 +00:00
[ this ] ( ) { return openConnection ( ) ; } ,
2018-08-03 19:10:03 +00:00
[ ] ( const ref < Connection > & r ) { return r - > good ; }
2017-02-07 18:28:40 +00:00
) )
2017-03-03 18:05:50 +00:00
, master (
host ,
2017-04-13 13:55:38 +00:00
sshKey ,
2021-02-25 01:52:22 +00:00
sshPublicHostKey ,
2017-03-03 18:05:50 +00:00
// Use SSH master only if using more than 1 connection.
connections - > capacity ( ) > 1 ,
2017-05-02 10:01:46 +00:00
compress ,
logFD )
2017-02-07 18:28:40 +00:00
{
}
ref < Connection > openConnection ( )
{
auto conn = make_ref < Connection > ( ) ;
2018-08-03 16:07:46 +00:00
conn - > sshConn = master . startCommand (
2018-08-06 15:27:08 +00:00
fmt ( " %s --serve --write " , remoteProgram )
2018-08-03 16:07:46 +00:00
+ ( remoteStore . get ( ) = = " " ? " " : " --store " + shellEscape ( remoteStore . get ( ) ) ) ) ;
2017-03-03 18:05:50 +00:00
conn - > to = FdSink ( conn - > sshConn - > in . get ( ) ) ;
conn - > from = FdSource ( conn - > sshConn - > out . get ( ) ) ;
2017-02-07 18:28:40 +00:00
try {
conn - > to < < SERVE_MAGIC_1 < < SERVE_PROTOCOL_VERSION ;
conn - > to . flush ( ) ;
2021-09-23 15:48:52 +00: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 16:01:04 +00:00
/* In case the other side is waiting for our input,
close it . */
2021-09-23 15:48:52 +00:00
conn - > sshConn - > in . close ( ) ;
auto msg = conn - > from . drain ( ) ;
throw Error ( " 'nix-store --serve' protocol mismatch from '%s', got '%s' " ,
2022-01-17 21:20:05 +00:00
host , chomp ( saved . s + msg ) ) ;
2021-09-23 15:48:52 +00:00
}
2017-05-01 14:08:13 +00:00
conn - > remoteVersion = readInt ( conn - > from ) ;
if ( GET_PROTOCOL_MAJOR ( conn - > remoteVersion ) ! = 0x200 )
2017-07-30 11:27:57 +00:00
throw Error ( " unsupported 'nix-store --serve' protocol version on '%s' " , host ) ;
2017-02-07 18:28:40 +00:00
} catch ( EndOfFile & e ) {
2017-07-30 11:27:57 +00:00
throw Error ( " cannot connect to '%1%' " , host ) ;
2017-02-07 18:28:40 +00:00
}
return conn ;
} ;
2022-02-25 15:00:00 +00:00
std : : string getUri ( ) override
2017-02-07 18:28:40 +00:00
{
2020-09-11 09:11:05 +00:00
return * uriSchemes ( ) . begin ( ) + " :// " + host ;
2017-02-07 18:28:40 +00:00
}
2019-12-05 18:11:09 +00:00
void queryPathInfoUncached ( const StorePath & path ,
2018-09-25 16:54:16 +00:00
Callback < std : : shared_ptr < const ValidPathInfo > > callback ) noexcept override
2017-02-07 18:28:40 +00:00
{
2018-03-27 20:16:01 +00:00
try {
2017-02-07 18:28:40 +00:00
auto conn ( connections - > get ( ) ) ;
2020-08-06 18:31:48 +00:00
/* No longer support missing NAR hash */
assert ( GET_PROTOCOL_MINOR ( conn - > remoteVersion ) > = 4 ) ;
2019-12-05 18:11:09 +00:00
debug ( " querying remote host '%s' for info on '%s' " , host , printStorePath ( path ) ) ;
2017-02-07 18:28:40 +00:00
2023-05-26 15:22:24 +00:00
conn - > to < < ServeProto : : Command : : QueryPathInfos < < PathSet { printStorePath ( path ) } ;
2017-02-07 18:28:40 +00:00
conn - > to . flush ( ) ;
2019-12-05 18:11:09 +00:00
auto p = readString ( conn - > from ) ;
if ( p . empty ( ) ) return callback ( nullptr ) ;
2020-08-06 18:31:48 +00: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 18:28:40 +00:00
2019-12-05 18:11:09 +00:00
auto deriver = readString ( conn - > from ) ;
if ( deriver ! = " " )
info - > deriver = parseStorePath ( deriver ) ;
2024-03-04 03:35:39 +00:00
info - > references = ServeProto : : Serialise < StorePathSet > : : read ( * this , * conn ) ;
2017-02-07 18:28:40 +00:00
readLongLong ( conn - > from ) ; // download size
info - > narSize = readLongLong ( conn - > from ) ;
2020-08-06 18:31:48 +00:00
{
2017-09-08 14:55:27 +00:00
auto s = readString ( conn - > from ) ;
2020-08-06 18:31:48 +00:00
if ( s = = " " )
throw Error ( " NAR hash is now mandatory " ) ;
info - > narHash = Hash : : parseAnyPrefixed ( s ) ;
2017-09-08 14:55:27 +00:00
}
2023-03-30 21:12:49 +00:00
info - > ca = ContentAddress : : parseOpt ( readString ( conn - > from ) ) ;
2020-08-06 18:31:48 +00:00
info - > sigs = readStrings < StringSet > ( conn - > from ) ;
2017-09-08 14:55:27 +00:00
2017-02-07 18:28:40 +00:00
auto s = readString ( conn - > from ) ;
assert ( s = = " " ) ;
2018-03-27 20:16:01 +00:00
callback ( std : : move ( info ) ) ;
} catch ( . . . ) { callback . rethrow ( ) ; }
2017-02-07 18:28:40 +00:00
}
2018-03-21 22:12:22 +00:00
void addToStore ( const ValidPathInfo & info , Source & source ,
2020-07-13 15:37:44 +00:00
RepairFlag repair , CheckSigsFlag checkSigs ) override
2017-02-07 18:28:40 +00:00
{
2019-12-05 18:11:09 +00:00
debug ( " adding path '%s' to remote host '%s' " , printStorePath ( info . path ) , host ) ;
2017-02-07 18:28:40 +00:00
auto conn ( connections - > get ( ) ) ;
2018-08-30 23:00:01 +00:00
if ( GET_PROTOCOL_MINOR ( conn - > remoteVersion ) > = 5 ) {
2018-08-03 19:10:03 +00:00
conn - > to
2023-05-26 15:22:24 +00:00
< < ServeProto : : Command : : AddToStoreNar
2019-12-05 18:11:09 +00:00
< < printStorePath ( info . path )
< < ( info . deriver ? printStorePath ( * info . deriver ) : " " )
2020-08-05 18:42:48 +00:00
< < info . narHash . to_string ( Base16 , false ) ;
2024-03-04 03:35:39 +00:00
ServeProto : : write ( * this , * conn , info . references ) ;
2019-12-05 18:11:09 +00:00
conn - > to
2018-08-03 19:10:03 +00:00
< < info . registrationTime
< < info . narSize
< < info . ultimate
< < info . sigs
2020-06-02 00:37:43 +00:00
< < renderContentAddress ( info . ca ) ;
2018-08-03 19:10:03 +00:00
try {
copyNAR ( source , conn - > to ) ;
} catch ( . . . ) {
conn - > good = false ;
throw ;
}
conn - > to . flush ( ) ;
} else {
conn - > to
2023-05-26 15:22:24 +00:00
< < ServeProto : : Command : : ImportPaths
2018-08-03 19:10:03 +00:00
< < 1 ;
try {
copyNAR ( source , conn - > to ) ;
} catch ( . . . ) {
conn - > good = false ;
throw ;
}
conn - > to
< < exportMagic
2019-12-05 18:11:09 +00:00
< < printStorePath ( info . path ) ;
2024-03-04 03:35:39 +00:00
ServeProto : : write ( * this , * conn , info . references ) ;
2019-12-05 18:11:09 +00:00
conn - > to
< < ( info . deriver ? printStorePath ( * info . deriver ) : " " )
2018-08-03 19:10:03 +00:00
< < 0
< < 0 ;
conn - > to . flush ( ) ;
}
2017-02-07 18:28:40 +00:00
if ( readInt ( conn - > from ) ! = 1 )
2019-12-05 18:11:09 +00:00
throw Error ( " failed to add path '%s' to remote host '%s' " , printStorePath ( info . path ) , host ) ;
2017-02-07 18:28:40 +00:00
}
2019-12-05 18:11:09 +00:00
void narFromPath ( const StorePath & path , Sink & sink ) override
2017-02-07 18:28:40 +00:00
{
auto conn ( connections - > get ( ) ) ;
2023-05-26 15:22:24 +00:00
conn - > to < < ServeProto : : Command : : DumpStorePath < < printStorePath ( path ) ;
2017-02-07 18:28:40 +00:00
conn - > to . flush ( ) ;
2018-03-21 21:56:02 +00:00
copyNAR ( conn - > from , sink ) ;
2017-02-07 18:28:40 +00:00
}
2019-12-05 18:11:09 +00:00
std : : optional < StorePath > queryPathFromHashPart ( const std : : string & hashPart ) override
2019-01-18 12:34:23 +00:00
{ unsupported ( " queryPathFromHashPart " ) ; }
2017-02-07 18:28:40 +00:00
2022-02-25 15:00:00 +00: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 12:34:23 +00:00
{ unsupported ( " addToStore " ) ; }
2017-02-07 18:28:40 +00:00
2022-02-25 15:00:00 +00:00
StorePath addTextToStore (
std : : string_view name ,
std : : string_view s ,
const StorePathSet & references ,
RepairFlag repair ) override
2019-01-18 12:34:23 +00:00
{ unsupported ( " addTextToStore " ) ; }
2017-02-07 18:28:40 +00:00
2020-08-12 03:13:17 +00: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 18:55:56 +00:00
< < 0 // buildRepeat hasn't worked for ages anyway
< < 0 ;
2021-08-23 21:47:29 +00:00
if ( GET_PROTOCOL_MINOR ( conn . remoteVersion ) > = 7 ) {
conn . to < < ( ( int ) settings . keepFailed ) ;
}
2020-08-12 03:13:17 +00:00
}
public :
2019-12-05 18:11:09 +00:00
BuildResult buildDerivation ( const StorePath & drvPath , const BasicDerivation & drv ,
2017-02-07 18:28:40 +00:00
BuildMode buildMode ) override
2017-05-01 14:08:13 +00:00
{
auto conn ( connections - > get ( ) ) ;
conn - > to
2023-05-26 15:22:24 +00:00
< < ServeProto : : Command : : BuildDerivation
2019-12-05 18:11:09 +00:00
< < printStorePath ( drvPath ) ;
writeDerivation ( conn - > to , * this , drv ) ;
2020-08-12 03:13:17 +00:00
putBuildSettings ( * conn ) ;
2017-05-01 14:08:13 +00:00
conn - > to . flush ( ) ;
2024-03-04 03:59:31 +00:00
return ServeProto : : Serialise < BuildResult > : : read ( * this , * conn ) ;
2017-05-01 14:08:13 +00:00
}
2017-02-07 18:28:40 +00:00
2021-07-19 13:43:08 +00:00
void buildPaths ( const std : : vector < DerivedPath > & drvPaths , BuildMode buildMode , std : : shared_ptr < Store > evalStore ) override
2020-08-12 03:13:17 +00:00
{
2021-07-19 13:43:08 +00:00
if ( evalStore & & evalStore . get ( ) ! = this )
throw Error ( " building on an SSH store is incompatible with '--eval-store' " ) ;
2020-08-12 03:13:17 +00:00
auto conn ( connections - > get ( ) ) ;
2023-05-26 15:22:24 +00:00
conn - > to < < ServeProto : : Command : : BuildPaths ;
2020-08-12 03:13:17 +00:00
Strings ss ;
2021-03-02 03:50:41 +00:00
for ( auto & p : drvPaths ) {
2021-04-05 13:48:18 +00:00
auto sOrDrvPath = StorePathWithOutputs : : tryFromDerivedPath ( p ) ;
2021-03-02 03:50:41 +00:00
std : : visit ( overloaded {
2021-09-30 21:31:21 +00:00
[ & ] ( const StorePathWithOutputs & s ) {
2021-03-02 03:50:41 +00:00
ss . push_back ( s . to_string ( * this ) ) ;
} ,
2021-09-30 21:31:21 +00:00
[ & ] ( const StorePath & drvPath ) {
2021-03-02 03:50:41 +00: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 ) ) ;
} ,
Make the Derived Path family of types inductive for dynamic derivations
We want to be able to write down `foo.drv^bar.drv^baz`:
`foo.drv^bar.drv` is the dynamic derivation (since it is itself a
derivation output, `bar.drv` from `foo.drv`).
To that end, we create `Single{Derivation,BuiltPath}` types, that are
very similar except instead of having multiple outputs (in a set or
map), they have a single one. This is for everything to the left of the
rightmost `^`.
`NixStringContextElem` has an analogous change, and now can reuse
`SingleDerivedPath` at the top level. In fact, if we ever get rid of
`DrvDeep`, `NixStringContextElem` could be replaced with
`SingleDerivedPath` entirely!
Important note: some JSON formats have changed.
We already can *produce* dynamic derivations, but we can't refer to them
directly. Today, we can merely express building or example at the top
imperatively over time by building `foo.drv^bar.drv`, and then with a
second nix invocation doing `<result-from-first>^baz`, but this is not
declarative. The ethos of Nix of being able to write down the full plan
everything you want to do, and then execute than plan with a single
command, and for that we need the new inductive form of these types.
Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
2023-01-15 22:39:04 +00:00
[ & ] ( std : : monostate ) {
throw Error ( " wanted build derivation that is itself a build product, but the legacy ssh protocol doesn't support that. Try using ssh-ng:// " ) ;
} ,
2021-03-02 03:50:41 +00:00
} , sOrDrvPath ) ;
}
2020-08-12 03:13:17 +00: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 01:26:07 +00:00
BuildResult result ;
2020-08-12 03:13:17 +00:00
result . status = ( BuildResult : : Status ) readInt ( conn - > from ) ;
if ( ! result . success ( ) ) {
conn - > from > > result . errorMsg ;
throw Error ( result . status , result . errorMsg ) ;
}
}
2019-12-05 18:11:09 +00:00
void ensurePath ( const StorePath & path ) override
2019-01-18 12:34:23 +00:00
{ unsupported ( " ensurePath " ) ; }
2017-02-07 18:28:40 +00:00
2023-04-13 17:38:12 +00:00
virtual ref < FSAccessor > getFSAccessor ( ) override
{ unsupported ( " getFSAccessor " ) ; }
2023-04-13 14:38:35 +00: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 18:11:09 +00:00
void computeFSClosure ( const StorePathSet & paths ,
StorePathSet & out , bool flipDirection = false ,
2017-03-16 10:44:01 +00: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
2023-05-26 15:22:24 +00:00
< < ServeProto : : Command : : QueryClosure
2019-12-05 18:11:09 +00:00
< < includeOutputs ;
2024-03-04 03:35:39 +00:00
ServeProto : : write ( * this , * conn , paths ) ;
2017-03-16 10:44:01 +00:00
conn - > to . flush ( ) ;
2024-03-04 03:35:39 +00:00
for ( auto & i : ServeProto : : Serialise < StorePathSet > : : read ( * this , * conn ) )
2020-06-16 20:20:18 +00:00
out . insert ( i ) ;
2017-03-16 10:44:01 +00:00
}
2019-12-05 18:11:09 +00:00
StorePathSet queryValidPaths ( const StorePathSet & paths ,
2017-06-28 16:11:01 +00:00
SubstituteFlag maybeSubstitute = NoSubstitute ) override
2017-03-16 12:50:01 +00:00
{
auto conn ( connections - > get ( ) ) ;
conn - > to
2023-05-26 15:22:24 +00:00
< < ServeProto : : Command : : QueryValidPaths
2017-03-16 12:50:01 +00:00
< < false // lock
2019-12-05 18:11:09 +00:00
< < maybeSubstitute ;
2024-03-04 03:35:39 +00:00
ServeProto : : write ( * this , * conn , paths ) ;
2017-03-16 12:50:01 +00:00
conn - > to . flush ( ) ;
2024-03-04 03:35:39 +00:00
return ServeProto : : Serialise < StorePathSet > : : read ( * this , * conn ) ;
2017-03-16 12:50:01 +00:00
}
2017-05-02 12:18:46 +00:00
void connect ( ) override
{
auto conn ( connections - > get ( ) ) ;
}
2018-08-30 21:28:47 +00:00
unsigned int getProtocol ( ) override
{
auto conn ( connections - > get ( ) ) ;
return conn - > remoteVersion ;
}
2020-10-08 15:36:51 +00:00
2022-12-26 20:21:08 +00: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 09:36:51 +00:00
void queryRealisationUncached ( const DrvOutput & ,
Callback < std : : shared_ptr < const Realisation > > callback ) noexcept override
2020-10-08 15:36:51 +00:00
// TODO: Implement
{ unsupported ( " queryRealisation " ) ; }
2017-02-07 18:28:40 +00:00
} ;
2020-10-06 11:36:55 +00:00
static RegisterStoreImplementation < LegacySSHStore , LegacySSHStoreConfig > regLegacySSHStore ;
2017-02-07 18:28:40 +00:00
}