Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions src/libstore/remote-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,16 @@ RemoteStore::RemoteStore(const Params & params)
, RemoteStoreConfig(params)
, connections(make_ref<Pool<Connection>>(
std::max(1, (int) maxConnections),
[this]() { return openConnectionWrapper(); },
[this]() {
auto conn = openConnectionWrapper();
try {
initConnection(*conn);
} catch (...) {
failed = true;
throw;
}
return conn;
},
[this](const ref<Connection> & r) {
return
r->to.good()
Expand Down Expand Up @@ -182,8 +191,6 @@ ref<RemoteStore::Connection> UDSRemoteStore::openConnection()

conn->startTime = std::chrono::steady_clock::now();

initConnection(*conn);

return conn;
}

Expand Down
4 changes: 2 additions & 2 deletions src/libstore/remote-store.hh
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ public:

void flushBadConnections();

protected:

struct Connection
{
AutoCloseFD fd;
Expand All @@ -123,6 +121,8 @@ protected:

ref<Connection> openConnectionWrapper();

protected:

virtual ref<Connection> openConnection() = 0;

void initConnection(Connection & conn);
Expand Down
1 change: 0 additions & 1 deletion src/libstore/ssh-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ ref<RemoteStore::Connection> SSHStore::openConnection()
+ (remoteStore.get() == "" ? "" : " --store " + shellEscape(remoteStore.get())));
conn->to = FdSink(conn->sshConn->in.get());
conn->from = FdSource(conn->sshConn->out.get());
initConnection(*conn);
return conn;
}

Expand Down
42 changes: 15 additions & 27 deletions src/libstore/store-api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1040,38 +1040,26 @@ static bool isNonUriPath(const std::string & spec) {
&& spec.find("/") != std::string::npos;
}

StoreType getStoreType(const std::string & uri, const std::string & stateDir)
std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Params & params)
{
if (uri == "daemon") {
return tDaemon;
} else if (uri == "local" || isNonUriPath(uri)) {
return tLocal;
} else if (uri == "" || uri == "auto") {
if (uri == "" || uri == "auto") {
auto stateDir = get(params, "state").value_or(settings.nixStateDir);
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
return tLocal;
return std::make_shared<LocalStore>(params);
else if (pathExists(settings.nixDaemonSocketFile))
return tDaemon;
return std::make_shared<UDSRemoteStore>(params);
else
return tLocal;
return std::make_shared<LocalStore>(params);
} else if (uri == "daemon") {
return std::make_shared<UDSRemoteStore>(params);
} else if (uri == "local") {
return std::make_shared<LocalStore>(params);
} else if (isNonUriPath(uri)) {
Store::Params params2 = params;
params2["root"] = absPath(uri);
return std::make_shared<LocalStore>(params2);
} else {
return tOther;
}
}

std::shared_ptr<Store> openFromNonUri(const std::string & uri, const Store::Params & params)
{
switch (getStoreType(uri, get(params, "state").value_or(settings.nixStateDir))) {
case tDaemon:
return std::shared_ptr<Store>(std::make_shared<UDSRemoteStore>(params));
case tLocal: {
Store::Params params2 = params;
if (isNonUriPath(uri)) {
params2["root"] = absPath(uri);
}
return std::shared_ptr<Store>(std::make_shared<LocalStore>(params2));
}
default:
return nullptr;
return nullptr;
}
}

Expand Down
10 changes: 0 additions & 10 deletions src/libstore/store-api.hh
Original file line number Diff line number Diff line change
Expand Up @@ -791,16 +791,6 @@ ref<Store> openStore(const std::string & uri = settings.storeUri.get(),
const Store::Params & extraParams = Store::Params());


enum StoreType {
tDaemon,
tLocal,
tOther
};


StoreType getStoreType(const std::string & uri = settings.storeUri.get(),
const std::string & stateDir = settings.nixStateDir);

/* Return the default substituter stores, defined by the
‘substituters’ option and various legacy options. */
std::list<ref<Store>> getDefaultSubstituters();
Expand Down
37 changes: 11 additions & 26 deletions src/nix-daemon/nix-daemon.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "shared.hh"
#include "local-store.hh"
#include "remote-store.hh"
#include "util.hh"
#include "serialise.hh"
#include "archive.hh"
Expand Down Expand Up @@ -285,44 +286,28 @@ static int _main(int argc, char * * argv)
initPlugins();

if (stdio) {
if (getStoreType() == tDaemon) {
// Forward on this connection to the real daemon
auto socketPath = settings.nixDaemonSocketFile;
auto s = socket(PF_UNIX, SOCK_STREAM, 0);
if (s == -1)
throw SysError("creating Unix domain socket");

auto socketDir = dirOf(socketPath);
if (chdir(socketDir.c_str()) == -1)
throw SysError("changing to socket directory '%1%'", socketDir);

auto socketName = std::string(baseNameOf(socketPath));
auto addr = sockaddr_un{};
addr.sun_family = AF_UNIX;
if (socketName.size() + 1 >= sizeof(addr.sun_path))
throw Error("socket name %1% is too long", socketName);
strcpy(addr.sun_path, socketName.c_str());

if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) == -1)
throw SysError("cannot connect to daemon at %1%", socketPath);

auto nfds = (s > STDIN_FILENO ? s : STDIN_FILENO) + 1;
if (auto store = openUncachedStore().dynamic_pointer_cast<RemoteStore>()) {
auto conn = store->openConnectionWrapper();
int from = conn->from.fd;
int to = conn->to.fd;

auto nfds = std::max(from, STDIN_FILENO) + 1;
while (true) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(s, &fds);
FD_SET(from, &fds);
FD_SET(STDIN_FILENO, &fds);
if (select(nfds, &fds, nullptr, nullptr, nullptr) == -1)
throw SysError("waiting for data from client or server");
if (FD_ISSET(s, &fds)) {
auto res = splice(s, nullptr, STDOUT_FILENO, nullptr, SSIZE_MAX, SPLICE_F_MOVE);
if (FD_ISSET(from, &fds)) {
auto res = splice(from, nullptr, STDOUT_FILENO, nullptr, SSIZE_MAX, SPLICE_F_MOVE);
if (res == -1)
throw SysError("splicing data from daemon socket to stdout");
else if (res == 0)
throw EndOfFile("unexpected EOF from daemon socket");
}
if (FD_ISSET(STDIN_FILENO, &fds)) {
auto res = splice(STDIN_FILENO, nullptr, s, nullptr, SSIZE_MAX, SPLICE_F_MOVE);
auto res = splice(STDIN_FILENO, nullptr, to, nullptr, SSIZE_MAX, SPLICE_F_MOVE);
if (res == -1)
throw SysError("splicing data from stdin to daemon socket");
else if (res == 0)
Expand Down
4 changes: 1 addition & 3 deletions src/nix/doctor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ struct CmdDoctor : StoreCommand
{
logger->log("Running checks against store uri: " + store->getUri());

auto type = getStoreType();

if (type < tOther) {
if (store.dynamic_pointer_cast<LocalFSStore>()) {
success &= checkNixInPath();
success &= checkProfileRoots(store);
}
Expand Down
1 change: 1 addition & 0 deletions tests/local.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ nix_tests = \
linux-sandbox.sh \
build-dry.sh \
build-remote-input-addressed.sh \
ssh-relay.sh \
nar-access.sh \
structured-attrs.sh \
fetchGit.sh \
Expand Down
16 changes: 16 additions & 0 deletions tests/ssh-relay.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
source common.sh

echo foo > $TEST_ROOT/hello.sh

ssh_localhost=ssh://localhost
remote_store=?remote-store=$ssh_localhost

store=$ssh_localhost

store+=$remote_store
store+=$remote_store
store+=$remote_store

out=$(nix add-to-store --store "$store" $TEST_ROOT/hello.sh)

[ foo = $(< $out) ]