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);
}
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 "remote-store.hh"
#include "local-binary-cache-store.hh"
namespace nix {
RegisterStoreImplementation::Implementations * RegisterStoreImplementation::implementations = 0;
ref<Store> openStoreAt(const std::string & uri)
{
if (std::string(uri, 0, 7) == "file://") {
auto store = make_ref<LocalBinaryCacheStore>(std::shared_ptr<Store>(0),
"", "", // FIXME: allow the signing key to be set
std::string(uri, 7));
store->init();
return store;
for (auto fun : *RegisterStoreImplementation::implementations) {
auto store = fun(uri);
if (store) return ref<Store>(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;
mode =
uri == "daemon" ? mDaemon :
uri == "local" ? mLocal : mAuto;
if (uri == "daemon") mode = mDaemon;
else if (uri == "local") mode = mLocal;
else if (uri == "") mode = mAuto;
else return 0;
if (mode == mAuto) {
if (LocalStore::haveWriteAccess())
@ -346,15 +357,9 @@ ref<Store> openStoreAt(const std::string & uri)
}
return mode == mDaemon
? (ref<Store>) make_ref<RemoteStore>()
: (ref<Store>) make_ref<LocalStore>();
}
ref<Store> openStore()
{
return openStoreAt(getEnv("NIX_REMOTE"));
}
? std::shared_ptr<Store>(std::make_shared<RemoteStore>())
: std::shared_ptr<Store>(std::make_shared<LocalStore>());
});
}

View file

@ -453,6 +453,23 @@ ref<Store> openStoreAt(const std::string & uri);
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
and separated by commas). */
string showPaths(const PathSet & paths);