1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-24 22:11:15 +02:00

Merge pull request #13188 from NixOS/store-open-reg-header

Split out `store-open.hh` and `store-registration.hh`
This commit is contained in:
Robert Hensing 2025-05-15 00:21:32 +02:00 committed by GitHub
commit 12b7132209
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 275 additions and 223 deletions

View file

@ -16,7 +16,7 @@
#include "nix/store/globals.hh"
#include "nix/util/serialise.hh"
#include "nix/store/build-result.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/util/strings.hh"
#include "nix/store/derivations.hh"
#include "nix/store/local-store.hh"

View file

@ -3,7 +3,7 @@
#include "nix/cmd/command.hh"
#include "nix/cmd/markdown.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/local-fs-store.hh"
#include "nix/store/derivations.hh"
#include "nix/expr/nixexpr.hh"

View file

@ -9,7 +9,7 @@
#include "nix/fetchers/registry.hh"
#include "nix/flake/flakeref.hh"
#include "nix/flake/settings.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/cmd/command.hh"
#include "nix/fetchers/tarball.hh"
#include "nix/fetchers/fetch-to-store.hh"

View file

@ -12,7 +12,7 @@
#include "nix/expr/eval-settings.hh"
#include "nix/expr/attr-path.hh"
#include "nix/util/signals.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/log-store.hh"
#include "nix/cmd/common-eval-args.hh"
#include "nix/expr/get-drvs.hh"

View file

@ -1,5 +1,5 @@
#include "nix/expr/primops.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/realisation.hh"
#include "nix/store/make-content-addressed.hh"
#include "nix/util/url.hh"

View file

@ -5,6 +5,7 @@
#include "nix/store/path.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/build-result.hh"
#include "nix/store/globals.hh"

View file

@ -5,6 +5,7 @@
#include <gmock/gmock.h>
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
namespace nix {

View file

@ -3,6 +3,7 @@
#include "nix/store/build/worker.hh"
#include "nix/store/build/substitution-goal.hh"
#include "nix/util/callback.hh"
#include "nix/store/store-open.hh"
namespace nix {

View file

@ -1,4 +1,5 @@
#include "nix/store/build/worker.hh"
#include "nix/store/store-open.hh"
#include "nix/store/build/substitution-goal.hh"
#include "nix/store/nar-info.hh"
#include "nix/util/finally.hh"

View file

@ -1,4 +1,4 @@
#include "nix/store/store-api.hh"
#include "nix/store/store-registration.hh"
#include "nix/util/callback.hh"
namespace nix {

View file

@ -3,6 +3,7 @@
#include "nix/store/globals.hh"
#include "nix/store/nar-info-disk-cache.hh"
#include "nix/util/callback.hh"
#include "nix/store/store-registration.hh"
namespace nix {

View file

@ -66,16 +66,18 @@ headers = [config_pub_h] + files(
'restricted-store.hh',
's3-binary-cache-store.hh',
's3.hh',
'ssh-store.hh',
'serve-protocol-connection.hh',
'serve-protocol-impl.hh',
'serve-protocol.hh',
'sqlite.hh',
'ssh-store.hh',
'ssh.hh',
'store-api.hh',
'store-cast.hh',
'store-dir-config.hh',
'store-open.hh',
'store-reference.hh',
'store-registration.hh',
'uds-remote-store.hh',
'worker-protocol-connection.hh',
'worker-protocol-impl.hh',

View file

@ -888,99 +888,6 @@ StorePath resolveDerivedPath(Store &, const SingleDerivedPath &, Store * evalSto
OutputPathMap resolveDerivedPath(Store &, const DerivedPath::Built &, Store * evalStore = nullptr);
/**
* @return a Store object to access the Nix store denoted by
* uri (slight misnomer...).
*/
ref<Store> openStore(StoreReference && storeURI);
/**
* Opens the store at `uri`, where `uri` is in the format expected by `StoreReference::parse`
*/
ref<Store> openStore(const std::string & uri = settings.storeUri.get(),
const Store::Config::Params & extraParams = Store::Config::Params());
/**
* @return the default substituter stores, defined by the
* substituters option and various legacy options.
*/
std::list<ref<Store>> getDefaultSubstituters();
struct StoreFactory
{
/**
* Documentation for this type of store.
*/
std::string doc;
/**
* URIs with these schemes should be handled by this factory
*/
StringSet uriSchemes;
/**
* An experimental feature this type store is gated, if it is to be
* experimental.
*/
std::optional<ExperimentalFeature> experimentalFeature;
/**
* The `authorityPath` parameter is `<authority>/<path>`, or really
* whatever comes after `<scheme>://` and before `?<query-params>`.
*/
std::function<ref<StoreConfig>(
std::string_view scheme, std::string_view authorityPath, const Store::Config::Params & params)>
parseConfig;
/**
* Just for dumping the defaults. Kind of awkward this exists,
* because it means we cannot require fields to be manually
* specified so easily.
*/
std::function<ref<StoreConfig>()> getConfig;
};
struct Implementations
{
using Map = std::map<std::string, StoreFactory>;
static Map & registered();
template<typename TConfig>
static void add()
{
StoreFactory factory{
.doc = TConfig::doc(),
.uriSchemes = TConfig::uriSchemes(),
.experimentalFeature = TConfig::experimentalFeature(),
.parseConfig =
([](auto scheme, auto uri, auto & params)
-> ref<StoreConfig>
{ return make_ref<TConfig>(scheme, uri, params); }),
.getConfig =
([]() -> ref<StoreConfig>
{ return make_ref<TConfig>(Store::Config::Params{}); }),
};
auto [it, didInsert] = registered().insert({TConfig::name(), std::move(factory)});
if (!didInsert) {
throw Error("Already registred store with name '%s'", it->first);
}
}
};
template<typename TConfig>
struct RegisterStoreImplementation
{
RegisterStoreImplementation()
{
Implementations::add<TConfig>();
}
};
/**
* Display a set of paths in human-readable form (i.e., between quotes
* and separated by commas).

View file

@ -0,0 +1,38 @@
#pragma once
/**
* @file
*
* For opening a store described by an `StoreReference`, which is an "untyped"
* notion which needs to be decoded against a collection of specific
* implementations.
*
* For consumers of the store registration machinery defined in
* `store-registration.hh`. Not needed by store implementation definitions, or
* usages of a given `Store` which will be passed in.
*/
#include "nix/store/store-api.hh"
namespace nix {
/**
* @return a Store object to access the Nix store denoted by
* uri (slight misnomer...).
*/
ref<Store> openStore(StoreReference && storeURI);
/**
* Opens the store at `uri`, where `uri` is in the format expected by
* `StoreReference::parse`
*/
ref<Store> openStore(
const std::string & uri = settings.storeUri.get(),
const StoreReference::Params & extraParams = StoreReference::Params());
/**
* @return the default substituter stores, defined by the
* substituters option and various legacy options.
*/
std::list<ref<Store>> getDefaultSubstituters();
}

View file

@ -0,0 +1,88 @@
#pragma once
/**
* @file
*
* Infrastructure for "registering" store implementations. Used by the
* store implementation definitions themselves but not by consumers of
* those implementations.
*
* Consumers of an arbitrary store from a URL/JSON configuration instead
* just need the defintions `nix/store/store-open.hh`; those do use this
* but only as an implementation. Consumers of a specific extra type of
* store can skip both these, and just use the definition of the store
* in question directly.
*/
#include "nix/store/store-api.hh"
namespace nix {
struct StoreFactory
{
/**
* Documentation for this type of store.
*/
std::string doc;
/**
* URIs with these schemes should be handled by this factory
*/
StringSet uriSchemes;
/**
* An experimental feature this type store is gated, if it is to be
* experimental.
*/
std::optional<ExperimentalFeature> experimentalFeature;
/**
* The `authorityPath` parameter is `<authority>/<path>`, or really
* whatever comes after `<scheme>://` and before `?<query-params>`.
*/
std::function<ref<StoreConfig>(
std::string_view scheme, std::string_view authorityPath, const Store::Config::Params & params)>
parseConfig;
/**
* Just for dumping the defaults. Kind of awkward this exists,
* because it means we cannot require fields to be manually
* specified so easily.
*/
std::function<ref<StoreConfig>()> getConfig;
};
struct Implementations
{
using Map = std::map<std::string, StoreFactory>;
static Map & registered();
template<typename TConfig>
static void add()
{
StoreFactory factory{
.doc = TConfig::doc(),
.uriSchemes = TConfig::uriSchemes(),
.experimentalFeature = TConfig::experimentalFeature(),
.parseConfig = ([](auto scheme, auto uri, auto & params) -> ref<StoreConfig> {
return make_ref<TConfig>(scheme, uri, params);
}),
.getConfig = ([]() -> ref<StoreConfig> { return make_ref<TConfig>(Store::Config::Params{}); }),
};
auto [it, didInsert] = registered().insert({TConfig::name(), std::move(factory)});
if (!didInsert) {
throw Error("Already registred store with name '%s'", it->first);
}
}
};
template<typename TConfig>
struct RegisterStoreImplementation
{
RegisterStoreImplementation()
{
Implementations::add<TConfig>();
}
};
}

View file

@ -12,6 +12,7 @@
#include "nix/store/ssh.hh"
#include "nix/store/derivations.hh"
#include "nix/util/callback.hh"
#include "nix/store/store-registration.hh"
namespace nix {

View file

@ -2,6 +2,7 @@
#include "nix/store/globals.hh"
#include "nix/store/nar-info-disk-cache.hh"
#include "nix/util/signals.hh"
#include "nix/store/store-registration.hh"
#include <atomic>

View file

@ -1,9 +1,12 @@
#include <regex>
#include "nix/store/local-overlay-store.hh"
#include "nix/util/callback.hh"
#include "nix/store/realisation.hh"
#include "nix/util/processes.hh"
#include "nix/util/url.hh"
#include <regex>
#include "nix/store/store-open.hh"
#include "nix/store/store-registration.hh"
namespace nix {

View file

@ -17,6 +17,8 @@
#include "nix/util/posix-source-accessor.hh"
#include "nix/store/keys.hh"
#include "nix/util/users.hh"
#include "nix/store/store-open.hh"
#include "nix/store/store-registration.hh"
#include <iostream>
#include <algorithm>

View file

@ -1,6 +1,6 @@
#include "nix/store/machines.hh"
#include "nix/store/globals.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include <algorithm>

View file

@ -314,6 +314,7 @@ sources = files(
'ssh.cc',
'store-api.cc',
'store-dir-config.cc',
'store-registration.cc',
'store-reference.cc',
'uds-remote-store.cc',
'worker-protocol-connection.cc',

View file

@ -4,7 +4,7 @@
#include "nix/store/parsed-derivations.hh"
#include "nix/store/derivation-options.hh"
#include "nix/store/globals.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/util/thread-pool.hh"
#include "nix/store/realisation.hh"
#include "nix/util/topo-sort.hh"

View file

@ -11,6 +11,7 @@
#include "nix/util/compression.hh"
#include "nix/store/filetransfer.hh"
#include "nix/util/signals.hh"
#include "nix/store/store-registration.hh"
#include <aws/core/Aws.h>
#include <aws/core/VersionConfig.h>

View file

@ -7,6 +7,7 @@
#include "nix/store/worker-protocol-impl.hh"
#include "nix/util/pool.hh"
#include "nix/store/ssh.hh"
#include "nix/store/store-registration.hh"
namespace nix {

View file

@ -5,6 +5,7 @@
#include "nix/store/realisation.hh"
#include "nix/store/derivations.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/util/util.hh"
#include "nix/store/nar-info-disk-cache.hh"
#include "nix/util/thread-pool.hh"
@ -1304,108 +1305,3 @@ void Store::signRealisation(Realisation & realisation)
}
}
#include "nix/store/local-store.hh"
#include "nix/store/uds-remote-store.hh"
namespace nix {
ref<Store> openStore(const std::string & uri,
const Store::Config::Params & extraParams)
{
return openStore(StoreReference::parse(uri, extraParams));
}
ref<Store> openStore(StoreReference && storeURI)
{
auto & params = storeURI.params;
auto storeConfig = std::visit(overloaded {
[&](const StoreReference::Auto &) -> ref<StoreConfig> {
auto stateDir = getOr(params, "state", settings.nixStateDir);
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
return make_ref<LocalStore::Config>(params);
else if (pathExists(settings.nixDaemonSocketFile))
return make_ref<UDSRemoteStore::Config>(params);
#ifdef __linux__
else if (!pathExists(stateDir)
&& params.empty()
&& !isRootUser()
&& !getEnv("NIX_STORE_DIR").has_value()
&& !getEnv("NIX_STATE_DIR").has_value())
{
/* If /nix doesn't exist, there is no daemon socket, and
we're not root, then automatically set up a chroot
store in ~/.local/share/nix/root. */
auto chrootStore = getDataDir() + "/root";
if (!pathExists(chrootStore)) {
try {
createDirs(chrootStore);
} catch (SystemError & e) {
return make_ref<LocalStore::Config>(params);
}
warn("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
} else
debug("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
return make_ref<LocalStore::Config>("local", chrootStore, params);
}
#endif
else
return make_ref<LocalStore::Config>(params);
},
[&](const StoreReference::Specified & g) {
for (const auto & [storeName, implem] : Implementations::registered())
if (implem.uriSchemes.count(g.scheme))
return implem.parseConfig(g.scheme, g.authority, params);
throw Error("don't know how to open Nix store with scheme '%s'", g.scheme);
},
}, storeURI.variant);
experimentalFeatureSettings.require(storeConfig->experimentalFeature());
storeConfig->warnUnknownSettings();
auto store = storeConfig->openStore();
store->init();
return store;
}
std::list<ref<Store>> getDefaultSubstituters()
{
static auto stores([]() {
std::list<ref<Store>> stores;
StringSet done;
auto addStore = [&](const std::string & uri) {
if (!done.insert(uri).second) return;
try {
stores.push_back(openStore(uri));
} catch (Error & e) {
logWarning(e.info());
}
};
for (const auto & uri : settings.substituters.get())
addStore(uri);
stores.sort([](ref<Store> & a, ref<Store> & b) {
return a->config.priority < b->config.priority;
});
return stores;
} ());
return stores;
}
Implementations::Map & Implementations::registered()
{
static Map registered;
return registered;
}
}

View file

@ -0,0 +1,101 @@
#include "nix/store/store-registration.hh"
#include "nix/store/store-open.hh"
#include "nix/store/local-store.hh"
#include "nix/store/uds-remote-store.hh"
namespace nix {
ref<Store> openStore(const std::string & uri, const Store::Config::Params & extraParams)
{
return openStore(StoreReference::parse(uri, extraParams));
}
ref<Store> openStore(StoreReference && storeURI)
{
auto & params = storeURI.params;
auto storeConfig = std::visit(
overloaded{
[&](const StoreReference::Auto &) -> ref<StoreConfig> {
auto stateDir = getOr(params, "state", settings.nixStateDir);
if (access(stateDir.c_str(), R_OK | W_OK) == 0)
return make_ref<LocalStore::Config>(params);
else if (pathExists(settings.nixDaemonSocketFile))
return make_ref<UDSRemoteStore::Config>(params);
#ifdef __linux__
else if (
!pathExists(stateDir) && params.empty() && !isRootUser() && !getEnv("NIX_STORE_DIR").has_value()
&& !getEnv("NIX_STATE_DIR").has_value()) {
/* If /nix doesn't exist, there is no daemon socket, and
we're not root, then automatically set up a chroot
store in ~/.local/share/nix/root. */
auto chrootStore = getDataDir() + "/root";
if (!pathExists(chrootStore)) {
try {
createDirs(chrootStore);
} catch (SystemError & e) {
return make_ref<LocalStore::Config>(params);
}
warn("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
} else
debug("'%s' does not exist, so Nix will use '%s' as a chroot store", stateDir, chrootStore);
return make_ref<LocalStore::Config>("local", chrootStore, params);
}
#endif
else
return make_ref<LocalStore::Config>(params);
},
[&](const StoreReference::Specified & g) {
for (const auto & [storeName, implem] : Implementations::registered())
if (implem.uriSchemes.count(g.scheme))
return implem.parseConfig(g.scheme, g.authority, params);
throw Error("don't know how to open Nix store with scheme '%s'", g.scheme);
},
},
storeURI.variant);
experimentalFeatureSettings.require(storeConfig->experimentalFeature());
storeConfig->warnUnknownSettings();
auto store = storeConfig->openStore();
store->init();
return store;
}
std::list<ref<Store>> getDefaultSubstituters()
{
static auto stores([]() {
std::list<ref<Store>> stores;
StringSet done;
auto addStore = [&](const std::string & uri) {
if (!done.insert(uri).second)
return;
try {
stores.push_back(openStore(uri));
} catch (Error & e) {
logWarning(e.info());
}
};
for (const auto & uri : settings.substituters.get())
addStore(uri);
stores.sort([](ref<Store> & a, ref<Store> & b) { return a->config.priority < b->config.priority; });
return stores;
}());
return stores;
}
Implementations::Map & Implementations::registered()
{
static Map registered;
return registered;
}
}

View file

@ -1,6 +1,7 @@
#include "nix/store/uds-remote-store.hh"
#include "nix/util/unix-domain-socket.hh"
#include "nix/store/worker-protocol.hh"
#include "nix/store/store-registration.hh"
#include <sys/types.h>
#include <sys/stat.h>

View file

@ -12,7 +12,7 @@
#include "nix/util/current-process.hh"
#include "nix/store/parsed-derivations.hh"
#include "nix/store/derivation-options.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/local-fs-store.hh"
#include "nix/store/globals.hh"
#include "nix/store/realisation.hh"

View file

@ -2,7 +2,7 @@
#include "nix/main/shared.hh"
#include "nix/store/globals.hh"
#include "nix/store/filetransfer.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/cmd/legacy.hh"
#include "nix/expr/eval-settings.hh" // for defexpr
#include "nix/util/users.hh"

View file

@ -1,6 +1,6 @@
#include "nix/util/file-system.hh"
#include "nix/util/signals.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/store-cast.hh"
#include "nix/store/gc-store.hh"
#include "nix/store/profiles.hh"

View file

@ -1,6 +1,6 @@
#include "nix/main/shared.hh"
#include "nix/store/realisation.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/cmd/legacy.hh"
#include "man-pages.hh"

View file

@ -9,7 +9,7 @@
#include "nix/store/profiles.hh"
#include "nix/store/path-with-outputs.hh"
#include "nix/main/shared.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/local-fs-store.hh"
#include "user-env.hh"
#include "nix/expr/value-to-json.hh"

View file

@ -8,7 +8,7 @@
#include "nix/util/signals.hh"
#include "nix/expr/value-to-xml.hh"
#include "nix/expr/value-to-json.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/local-fs-store.hh"
#include "nix/cmd/common-eval-args.hh"
#include "nix/cmd/legacy.hh"

View file

@ -2,6 +2,7 @@
#include "nix/store/derivations.hh"
#include "dotgraph.hh"
#include "nix/store/globals.hh"
#include "nix/store/store-open.hh"
#include "nix/store/store-cast.hh"
#include "nix/store/local-fs-store.hh"
#include "nix/store/log-store.hh"

View file

@ -8,7 +8,7 @@
#include "nix/flake/flake.hh"
#include "nix/expr/get-drvs.hh"
#include "nix/util/signals.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/derivations.hh"
#include "nix/store/outputs-spec.hh"
#include "nix/expr/attr-path.hh"

View file

@ -1,7 +1,7 @@
#include "nix/cmd/command.hh"
#include "nix/main/common-args.hh"
#include "nix/main/shared.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/log-store.hh"
using namespace nix;

View file

@ -7,7 +7,8 @@
#include "nix/store/globals.hh"
#include "nix/cmd/legacy.hh"
#include "nix/main/shared.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/store-registration.hh"
#include "nix/store/filetransfer.hh"
#include "nix/util/finally.hh"
#include "nix/main/loggers.hh"

View file

@ -1,5 +1,5 @@
#include "nix/cmd/command.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/make-content-addressed.hh"
#include "nix/main/common-args.hh"

View file

@ -1,7 +1,7 @@
#include "nix/cmd/command.hh"
#include "nix/main/common-args.hh"
#include "nix/main/shared.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/filetransfer.hh"
#include "nix/util/finally.hh"
#include "nix/main/loggers.hh"

View file

@ -2,6 +2,7 @@
#include "nix/expr/eval-settings.hh"
#include "nix/util/config-global.hh"
#include "nix/store/globals.hh"
#include "nix/store/store-open.hh"
#include "nix/cmd/command.hh"
#include "nix/cmd/installable-value.hh"
#include "nix/cmd/repl.hh"

View file

@ -1,7 +1,7 @@
#include "nix/util/signals.hh"
#include "nix/cmd/command.hh"
#include "nix/main/shared.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/util/thread-pool.hh"
#include <atomic>

View file

@ -7,6 +7,7 @@
#include "nix/store/local-store.hh"
#include "nix/store/remote-store.hh"
#include "nix/store/remote-store-connection.hh"
#include "nix/store/store-open.hh"
#include "nix/util/serialise.hh"
#include "nix/util/archive.hh"
#include "nix/store/globals.hh"

View file

@ -1,6 +1,6 @@
#include "nix/cmd/command.hh"
#include "nix/main/shared.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/util/thread-pool.hh"
#include "nix/util/signals.hh"
#include "nix/store/keys.hh"

View file

@ -9,7 +9,7 @@
#include "nix/store/derivations.hh"
#include "nix/store/realisation.hh"
#include "nix/store/globals.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/util/posix-source-accessor.hh"
#include <sodium.h>

View file

@ -1,5 +1,5 @@
#include "nix/store/globals.hh"
#include "nix/store/store-api.hh"
#include "nix/store/store-open.hh"
#include "nix/store/build-result.hh"
#include <iostream>