Make store implementations pluggable

This for instance allows hydra-queue-runner to add the S3 backend
at runtime.
This commit is contained in:
Eelco Dolstra 2016-02-29 16:11:11 +01:00
parent 012f8d187c
commit 0b907321cc
3 changed files with 50 additions and 19 deletions

View file

@ -41,4 +41,13 @@ std::string LocalBinaryCacheStore::getFile(const std::string & path)
return readFile(binaryCacheDir + "/" + path); return readFile(binaryCacheDir + "/" + path);
} }
static RegisterStoreImplementation regStore([](const std::string & uri) -> std::shared_ptr<Store> {
if (std::string(uri, 0, 7) != "file://") return 0;
auto store = std::make_shared<LocalBinaryCacheStore>(std::shared_ptr<Store>(0),
"", "", // FIXME: allow the signing key to be set
std::string(uri, 7));
store->init();
return store;
});
} }

View file

@ -314,27 +314,38 @@ void Store::exportPaths(const Paths & paths,
#include "local-store.hh" #include "local-store.hh"
#include "remote-store.hh" #include "remote-store.hh"
#include "local-binary-cache-store.hh"
namespace nix { namespace nix {
RegisterStoreImplementation::Implementations * RegisterStoreImplementation::implementations = 0;
ref<Store> openStoreAt(const std::string & uri) ref<Store> openStoreAt(const std::string & uri)
{ {
if (std::string(uri, 0, 7) == "file://") { for (auto fun : *RegisterStoreImplementation::implementations) {
auto store = make_ref<LocalBinaryCacheStore>(std::shared_ptr<Store>(0), auto store = fun(uri);
"", "", // FIXME: allow the signing key to be set if (store) return ref<Store>(store);
std::string(uri, 7));
store->init();
return store;
} }
throw Error(format("don't know how to open Nix store %s") % uri);
}
ref<Store> openStore()
{
return openStoreAt(getEnv("NIX_REMOTE"));
}
static RegisterStoreImplementation regStore([](const std::string & uri) -> std::shared_ptr<Store> {
enum { mDaemon, mLocal, mAuto } mode; enum { mDaemon, mLocal, mAuto } mode;
mode = if (uri == "daemon") mode = mDaemon;
uri == "daemon" ? mDaemon : else if (uri == "local") mode = mLocal;
uri == "local" ? mLocal : mAuto; else if (uri == "") mode = mAuto;
else return 0;
if (mode == mAuto) { if (mode == mAuto) {
if (LocalStore::haveWriteAccess()) if (LocalStore::haveWriteAccess())
@ -346,15 +357,9 @@ ref<Store> openStoreAt(const std::string & uri)
} }
return mode == mDaemon return mode == mDaemon
? (ref<Store>) make_ref<RemoteStore>() ? std::shared_ptr<Store>(std::make_shared<RemoteStore>())
: (ref<Store>) make_ref<LocalStore>(); : std::shared_ptr<Store>(std::make_shared<LocalStore>());
} });
ref<Store> openStore()
{
return openStoreAt(getEnv("NIX_REMOTE"));
}
} }

View file

@ -453,6 +453,23 @@ ref<Store> openStoreAt(const std::string & uri);
ref<Store> openStore(); ref<Store> openStore();
/* Store implementation registration. */
typedef std::function<std::shared_ptr<Store>(const std::string & uri)> OpenStore;
struct RegisterStoreImplementation
{
typedef std::vector<OpenStore> Implementations;
static Implementations * implementations;
RegisterStoreImplementation(OpenStore fun)
{
if (!implementations) implementations = new Implementations;
implementations->push_back(fun);
}
};
/* Display a set of paths in human-readable form (i.e., between quotes /* Display a set of paths in human-readable form (i.e., between quotes
and separated by commas). */ and separated by commas). */
string showPaths(const PathSet & paths); string showPaths(const PathSet & paths);