From 0b907321cca39368c5abcb3f5e6d73d5ab2e3e40 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 29 Feb 2016 16:11:11 +0100 Subject: [PATCH] Make store implementations pluggable This for instance allows hydra-queue-runner to add the S3 backend at runtime. --- src/libstore/local-binary-cache-store.cc | 9 +++++ src/libstore/store-api.cc | 43 +++++++++++++----------- src/libstore/store-api.hh | 17 ++++++++++ 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index 5714688e0..9fae80870 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -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 { + if (std::string(uri, 0, 7) != "file://") return 0; + auto store = std::make_shared(std::shared_ptr(0), + "", "", // FIXME: allow the signing key to be set + std::string(uri, 7)); + store->init(); + return store; +}); + } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 24c05b8b4..378233654 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -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 openStoreAt(const std::string & uri) { - if (std::string(uri, 0, 7) == "file://") { - auto store = make_ref(std::shared_ptr(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); } + throw Error(format("don't know how to open Nix store ā€˜%sā€™") % uri); +} + + +ref openStore() +{ + return openStoreAt(getEnv("NIX_REMOTE")); +} + + +static RegisterStoreImplementation regStore([](const std::string & uri) -> std::shared_ptr { 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 openStoreAt(const std::string & uri) } return mode == mDaemon - ? (ref) make_ref() - : (ref) make_ref(); -} - - -ref openStore() -{ - return openStoreAt(getEnv("NIX_REMOTE")); -} + ? std::shared_ptr(std::make_shared()) + : std::shared_ptr(std::make_shared()); +}); } diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 488f32e16..97e834ed2 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -453,6 +453,23 @@ ref openStoreAt(const std::string & uri); ref openStore(); +/* Store implementation registration. */ +typedef std::function(const std::string & uri)> OpenStore; + +struct RegisterStoreImplementation +{ + typedef std::vector 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);