Skip to content

Commit

Permalink
WIP: Add BuildInterposeStore
Browse files Browse the repository at this point in the history
  • Loading branch information
ryantrinkle committed Dec 23, 2024
1 parent a4f978b commit fe0ff48
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 1 deletion.
121 changes: 121 additions & 0 deletions src/libstore/build-interpose-uds.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#include "uds-remote-store.hh"
#include "pool.hh"
#include "worker-protocol.hh"

namespace nix {

struct BuildInterposeUDSStoreConfig : virtual UDSRemoteStoreConfig
{
BuildInterposeUDSStoreConfig(const Store::Params & params)
: StoreConfig(params)
, LocalFSStoreConfig(params)
, RemoteStoreConfig(params)
, UDSRemoteStoreConfig(params)
{ }

const Setting<int> maxInterposeConnections{(StoreConfig*) this, 1,
"max-interpose-connections", "maximum number of concurrent connections to the build daemon"};

const std::string name() override { return UDSRemoteStoreConfig::name() + " with building interposed"; }

const PathSetting buildInterposeSocket{(StoreConfig*) this, true, "",
"build-interpose-socket", "Socket for logging builds"
};
};

struct BuildInterposeUDSStore : virtual BuildInterposeUDSStoreConfig, virtual UDSRemoteStore
{
static std::set<std::string> uriSchemes() { return {"build-interpose-unix"}; }

struct InterposeConnection;

ref<Pool<InterposeConnection>> interposeConnections;

BuildInterposeUDSStore(
const std::string & uriScheme,
const std::string & ignore,
const Params & params);

void buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMode, std::shared_ptr<Store> evalStore) override;

#if 0
std::vector<BuildResult> buildPathsWithResults(
const std::vector<DerivedPath> & paths,
BuildMode buildMode,
std::shared_ptr<Store> evalStore) override;

BuildResult buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
BuildMode buildMode) override;

void ensurePath(const StorePath & path) override;

void repairPath(const StorePath & path) override;
#endif
};

struct BuildInterposeUDSStore::InterposeConnection
{
AutoCloseFD fd;
FdSink to;
FdSource from;

InterposeConnection(AutoCloseFD && fd0)
: fd(std::move(fd0))
{
to.fd = fd.get();
from.fd = fd.get();
}
};

BuildInterposeUDSStore::BuildInterposeUDSStore(
const std::string & uriScheme,
const std::string & ignore,
const Params & params)
: StoreConfig(params)
, LocalFSStoreConfig(params)
, RemoteStoreConfig(params)
, UDSRemoteStoreConfig(params)
, BuildInterposeUDSStoreConfig(params)
, Store(params)
, LocalFSStore(params)
, RemoteStore(params)
, UDSRemoteStore(params)
, interposeConnections(make_ref<Pool<InterposeConnection>>(
1, //std::max(1, (int) maxInterposeConnections),
[this]() {
AutoCloseFD socket = createUnixDomainSocket();
nix::connect(socket.get(), buildInterposeSocket);
return make_ref<InterposeConnection>(std::move(socket));
},
[](const ref<InterposeConnection> & r) {
return
r->to.good()
&& r->from.good();
}
))
{
if (ignore != "")
throw Error("Invalid URL");
}

void BuildInterposeUDSStore::buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMode, std::shared_ptr<Store> evalStore)
{
auto conn(interposeConnections->get());
conn->to << "Build interposer";
worker_proto::write(*this, conn->to, reqs);
conn->to.flush();
auto res = readNum<bool>(conn->from);
if (!res) {
std::string msg;
for (auto & req : reqs) {
msg += " ";
msg += req.to_string(*this);
}
throw Error("Build interposer Failed to Build%s", msg);
}
UDSRemoteStore::buildPaths(reqs, buildMode, evalStore);
}

static RegisterStoreImplementation<BuildInterposeUDSStore, BuildInterposeUDSStoreConfig> regBuildInterposeUDSStore;

}
120 changes: 120 additions & 0 deletions src/libstore/build-interpose.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#include "local-store.hh"
#include "pool.hh"
#include "worker-protocol.hh"

namespace nix {

struct BuildInterposeStoreConfig : virtual LocalStoreConfig
{
BuildInterposeStoreConfig(const Store::Params & params)
: StoreConfig(params)
, LocalFSStoreConfig(params)
, LocalStoreConfig(params)
{ }

const Setting<int> maxConnections{(StoreConfig*) this, 1,
"max-connections", "maximum number of concurrent connections to the build daemon"};

const std::string name() override { return LocalStoreConfig::name() + " with building interposed"; }

const PathSetting buildInterposeSocket{(StoreConfig*) this, true, "",
"build-interpose-socket", "Socket for logging builds"
};
};

struct BuildInterposeStore : virtual BuildInterposeStoreConfig, virtual LocalStore
{
static std::set<std::string> uriSchemes() { return {"build-interpose"}; }

using LocalStore::LocalStore;

struct Connection;

ref<Pool<Connection>> connections;

BuildInterposeStore(
const std::string & uriScheme,
const std::string & ignore,
const Params & params);

void buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMode, std::shared_ptr<Store> evalStore) override;

#if 0
std::vector<BuildResult> buildPathsWithResults(
const std::vector<DerivedPath> & paths,
BuildMode buildMode,
std::shared_ptr<Store> evalStore) override;

BuildResult buildDerivation(const StorePath & drvPath, const BasicDerivation & drv,
BuildMode buildMode) override;

void ensurePath(const StorePath & path) override;

void repairPath(const StorePath & path) override;
#endif
};

struct BuildInterposeStore::Connection
{
AutoCloseFD fd;
FdSink to;
FdSource from;

Connection(AutoCloseFD && fd0)
: fd(std::move(fd0))
{
to.fd = fd.get();
from.fd = fd.get();
}
};

BuildInterposeStore::BuildInterposeStore(
const std::string & uriScheme,
const std::string & ignore,
const Params & params)
: StoreConfig(params)
, LocalFSStoreConfig(params)
, LocalStoreConfig(params)
, BuildInterposeStoreConfig(params)
, Store(params)
, LocalFSStore(params)
, LocalStore(params)
, connections(make_ref<Pool<Connection>>(
1, //std::max(1, (int) maxConnections),
[this]() {
AutoCloseFD socket = createUnixDomainSocket();
nix::connect(socket.get(), buildInterposeSocket);
return make_ref<Connection>(std::move(socket));
},
[](const ref<Connection> & r) {
return
r->to.good()
&& r->from.good();
}
))
{
if (ignore != "")
throw Error("Invalid URL");
}

void BuildInterposeStore::buildPaths(const std::vector<DerivedPath> & reqs, BuildMode buildMode, std::shared_ptr<Store> evalStore)
{
auto conn(connections->get());
conn->to << "Build interposer";
worker_proto::write(*this, conn->to, reqs);
conn->to.flush();
auto res = readNum<bool>(conn->from);
if (!res) {
std::string msg;
for (auto & req : reqs) {
msg += " ";
msg += req.to_string(*this);
}
throw Error("Build interposer Failed to Build%s", msg);
}
LocalStore::buildPaths(reqs, buildMode, evalStore);
}

static RegisterStoreImplementation<BuildInterposeStore, BuildInterposeStoreConfig> regBuildInterposeStore;

}
2 changes: 1 addition & 1 deletion src/libstore/parsed-derivations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ bool ParsedDerivation::canBuildLocally(Store & localStore) const

bool ParsedDerivation::willBuildLocally(Store & localStore) const
{
return getBoolAttr("preferLocalBuild") && canBuildLocally(localStore);
return false;
}

bool ParsedDerivation::substitutesAllowed() const
Expand Down

0 comments on commit fe0ff48

Please sign in to comment.