1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#include <absl/strings/str_cat.h>
#include "libstore/remote-fs-accessor.hh"
#include "libstore/remote-store.hh"
#include "libstore/ssh.hh"
#include "libstore/store-api.hh"
#include "libstore/worker-protocol.hh"
#include "libutil/archive.hh"
#include "libutil/pool.hh"
namespace nix {
constexpr std::string_view kUriScheme = "ssh-ng://";
class SSHStore : public RemoteStore {
public:
const Setting<Path> sshKey{(Store*)this, "", "ssh-key",
"path to an SSH private key"};
const Setting<bool> compress{(Store*)this, false, "compress",
"whether to compress the connection"};
SSHStore(const std::string& host, const Params& params)
: Store(params),
RemoteStore(params),
host(host),
master(host, sshKey,
// Use SSH master only if using more than 1 connection.
connections->capacity() > 1, compress) {}
std::string getUri() override { return absl::StrCat(kUriScheme, host); }
bool sameMachine() override { return false; }
void narFromPath(const Path& path, Sink& sink) override;
ref<FSAccessor> getFSAccessor() override;
private:
struct Connection : RemoteStore::Connection {
std::unique_ptr<SSHMaster::Connection> sshConn;
};
ref<RemoteStore::Connection> openConnection() override;
std::string host;
SSHMaster master;
void setOptions(RemoteStore::Connection& conn) override{
/* TODO Add a way to explicitly ask for some options to be
forwarded. One option: A way to query the daemon for its
settings, and then a series of params to SSHStore like
forward-cores or forward-overridden-cores that only
override the requested settings.
*/
};
};
void SSHStore::narFromPath(const Path& path, Sink& sink) {
auto conn(connections->get());
conn->to << wopNarFromPath << path;
conn->processStderr();
copyNAR(conn->from, sink);
}
ref<FSAccessor> SSHStore::getFSAccessor() {
return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()));
}
ref<RemoteStore::Connection> SSHStore::openConnection() {
auto conn = make_ref<Connection>();
conn->sshConn = master.startCommand("nix-daemon --pipe");
conn->to = FdSink(conn->sshConn->in.get());
conn->from = FdSource(conn->sshConn->out.get());
initConnection(*conn);
return conn;
}
static RegisterStoreImplementation regStore(
[](const std::string& uri,
const Store::Params& params) -> std::shared_ptr<Store> {
if (std::string(uri, 0, kUriScheme.size()) != kUriScheme) {
return nullptr;
}
return std::make_shared<SSHStore>(std::string(uri, kUriScheme.size()),
params);
});
} // namespace nix
|