diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 79841ca49a1..ba4a6e6e5eb 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -5,6 +5,7 @@ #include "path.hh" #include "store-api.hh" +#include "store-open.hh" #include "build-result.hh" #include "globals.hh" diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index 695bc925277..234c39caf3a 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -96,7 +96,11 @@ public: public: - virtual void init() override; + /** + * Perform any necessary effectful operation to make the store up and + * running + */ + virtual void init(); private: diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index f7509bcdeaf..c6dd71ba669 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -36,7 +36,7 @@ struct DummyStoreConfig : virtual StoreConfig { return {"dummy"}; } - std::shared_ptr open() override; + std::shared_ptr openStore() override; }; @@ -50,7 +50,7 @@ struct DummyStore : public virtual DummyStoreConfig, public virtual Store DummyStore(const Config & config) : StoreConfig(config) , DummyStoreConfig(config) - , Store(config) + , Store{static_cast(*this)} { } std::string getUri() override @@ -100,7 +100,7 @@ struct DummyStore : public virtual DummyStoreConfig, public virtual Store { unsupported("getFSAccessor"); } }; -std::shared_ptr DummyStore::Config::open() +std::shared_ptr DummyStore::Config::openStore() { return std::make_shared(*this); } diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc index fbaf6c3cb1c..a8b23996159 100644 --- a/src/libstore/local-fs-store.cc +++ b/src/libstore/local-fs-store.cc @@ -85,7 +85,8 @@ LocalFSStore::Config::LocalFSStoreConfig(PathView rootDir, const StoreReference: } LocalFSStore::LocalFSStore(const Config & config) - : Store(config) + : LocalFSStore::Config{config} + , Store{static_cast(*this)} { } diff --git a/src/libstore/local-fs-store.hh b/src/libstore/local-fs-store.hh index a400faec05a..654dd210f40 100644 --- a/src/libstore/local-fs-store.hh +++ b/src/libstore/local-fs-store.hh @@ -23,17 +23,6 @@ struct LocalFSStoreConfig : virtual Store::Config, LocalFSStoreConfigT { - LocalFSStoreConfig(const StoreReference::Params &); - - /** - * Used to override the `root` settings. Can't be done via modifying - * `params` reliably because this parameter is unused except for - * passing to base class constructors. - * - * @todo Make this less error-prone with new store settings system. - */ - LocalFSStoreConfig(PathView path, const StoreReference::Params & params); - struct Descriptions : virtual Store::Config::Descriptions, LocalFSStoreConfigT @@ -49,6 +38,17 @@ struct LocalFSStoreConfig : static LocalFSStoreConfigT defaults( const Store::Config &, const std::optional rootDir); + + LocalFSStoreConfig(const StoreReference::Params &); + + /** + * Used to override the `root` settings. Can't be done via modifying + * `params` reliably because this parameter is unused except for + * passing to base class constructors. + * + * @todo Make this less error-prone with new store settings system. + */ + LocalFSStoreConfig(PathView path, const StoreReference::Params & params); }; struct LocalFSStore : diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 819cee34532..2dfc78ebda3 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -17,6 +17,9 @@ #include "posix-source-accessor.hh" #include "keys.hh" #include "users.hh" +#include "config-parse-impl.hh" +#include "store-open.hh" +#include "store-registration.hh" #include #include @@ -56,12 +59,50 @@ namespace nix { -LocalStoreConfig::LocalStoreConfig( +LocalStore::Config::Descriptions::Descriptions() + : Store::Config::Descriptions{Store::Config::descriptions} + , LocalFSStore::Config::Descriptions{LocalFSStore::Config::descriptions} + , LocalStoreConfigT{ + .requireSigs = { + .name = "require-sigs", + .description = "Whether store paths copied into this store should have a trusted signature.", + }, + .readOnly = { + .name = "read-only", + .description = R"( + Allow this store to be opened when its [database](@docroot@/glossary.md#gloss-nix-database) is on a read-only filesystem. + + Normally Nix will attempt to open the store database in read-write mode, even for querying (when write access is not needed), causing it to fail if the database is on a read-only filesystem. + + Enable read-only mode to disable locking and open the SQLite database with the [`immutable` parameter](https://www.sqlite.org/c3ref/open.html) set. + + > **Warning** + > Do not use this unless the filesystem is read-only. + > + > Using it when the filesystem is writable can cause incorrect query results or corruption errors if the database is changed by another process. + > While the filesystem the database resides on might appear to be read-only, consider whether another user or system might have write access to it. + )", + }, + } +{} + +const LocalStore::Config::Descriptions LocalStore::Config::descriptions{}; + +decltype(LocalStore::Config::defaults) LocalStore::Config::defaults = { + .requireSigs = {.value = settings.requireSigs }, + .readOnly = {.value = false }, +}; + +LocalStore::Config::LocalStoreConfig( std::string_view scheme, std::string_view authority, - const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(authority, params) + const StoreReference::Params & params) + : Store::Config(params) + , LocalFSStore::Config(authority, params) + , LocalStoreConfigT{ + CONFIG_ROW(requireSigs), + CONFIG_ROW(readOnly), + } { } @@ -72,6 +113,11 @@ std::string LocalStoreConfig::doc() ; } +std::shared_ptr LocalStore::Config::openStore() +{ + return std::make_shared(*this); +} + struct LocalStore::State::Stmts { /* Some precompiled SQLite statements. */ SQLiteStmt RegisterValidPath; @@ -192,15 +238,12 @@ void migrateCASchema(SQLite& db, Path schemaPath, AutoCloseFD& lockFd) } } -LocalStore::LocalStore( - std::string_view scheme, - PathView path, - const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(path, params) - , LocalStoreConfig(scheme, path, params) - , Store(params) - , LocalFSStore(params) +LocalStore::LocalStore(const Config & config) + : Store::Config{config} + , LocalFSStore::Config{config} + , LocalStore::Config{config} + , Store{static_cast(*this)} + , LocalFSStore{static_cast(*this)} , dbDir(stateDir + "/db") , linksDir(realStoreDir + "/.links") , reservedPath(dbDir + "/reserved") @@ -477,12 +520,6 @@ LocalStore::LocalStore( } -LocalStore::LocalStore(const Params & params) - : LocalStore("local", "", params) -{ -} - - AutoCloseFD LocalStore::openGCLock() { Path fnGCLock = stateDir + "/gc.lock"; @@ -1512,7 +1549,7 @@ LocalStore::VerificationResult LocalStore::verifyAllValidPaths(RepairFlag repair database and the filesystem) in the loop below, in order to catch invalid states. */ - for (auto & i : std::filesystem::directory_iterator{realStoreDir.to_string()}) { + for (auto & i : std::filesystem::directory_iterator{realStoreDir.get()}) { checkInterrupt(); try { storePathsInStoreDir.insert({i.path().filename().string()}); @@ -1802,6 +1839,6 @@ std::optional LocalStore::getVersion() return nixVersion; } -static RegisterStoreImplementation regLocalStore; +static RegisterStoreImplementation regLocalStore; } // namespace nix diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index a03cfc03b30..13e26922c0a 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -34,36 +34,40 @@ struct OptimiseStats uint64_t bytesFreed = 0; }; -struct LocalStoreConfig : virtual LocalFSStoreConfig +template class F> +struct LocalStoreConfigT { - using LocalFSStoreConfig::LocalFSStoreConfig; + const F requireSigs; - LocalStoreConfig( - std::string_view scheme, - std::string_view authority, - const Params & params); + const F readOnly; +}; - Setting requireSigs{this, - settings.requireSigs, - "require-sigs", - "Whether store paths copied into this store should have a trusted signature."}; +struct LocalStoreConfig : + virtual Store::Config, + virtual LocalFSStore::Config, + LocalStoreConfigT +{ + struct Descriptions : + virtual Store::Config::Descriptions, + virtual LocalFSStore::Config::Descriptions, + LocalStoreConfigT + { + Descriptions(); + }; - Setting readOnly{this, - false, - "read-only", - R"( - Allow this store to be opened when its [database](@docroot@/glossary.md#gloss-nix-database) is on a read-only filesystem. + static const Descriptions descriptions; - Normally Nix will attempt to open the store database in read-write mode, even for querying (when write access is not needed), causing it to fail if the database is on a read-only filesystem. + /** + * The other defaults depend on the choice of `storeDir` and `rootDir` + */ + static LocalStoreConfigT defaults; - Enable read-only mode to disable locking and open the SQLite database with the [`immutable` parameter](https://www.sqlite.org/c3ref/open.html) set. + LocalStoreConfig(const StoreReference::Params &); - > **Warning** - > Do not use this unless the filesystem is read-only. - > - > Using it when the filesystem is writable can cause incorrect query results or corruption errors if the database is changed by another process. - > While the filesystem the database resides on might appear to be read-only, consider whether another user or system might have write access to it. - )"}; + LocalStoreConfig( + std::string_view scheme, + std::string_view authority, + const StoreReference::Params & params); const std::string name() override { return "Local Store"; } @@ -71,12 +75,19 @@ struct LocalStoreConfig : virtual LocalFSStoreConfig { return {"local"}; } std::string doc() override; + + std::shared_ptr openStore() override; }; -class LocalStore : public virtual LocalStoreConfig - , public virtual IndirectRootStore - , public virtual GcStore +class LocalStore : + public virtual LocalStoreConfig, + public virtual IndirectRootStore, + public virtual GcStore { +public: + + using Config = LocalStoreConfig; + private: /** @@ -144,11 +155,7 @@ public: * Initialise the local store, upgrading the schema if * necessary. */ - LocalStore(const Params & params); - LocalStore( - std::string_view scheme, - PathView path, - const Params & params); + LocalStore(const Config & params); ~LocalStore(); diff --git a/src/libstore/machines.hh b/src/libstore/machines.hh index 983652d5f8b..671de208468 100644 --- a/src/libstore/machines.hh +++ b/src/libstore/machines.hh @@ -1,6 +1,8 @@ #pragma once ///@file +#include + #include "ref.hh" #include "store-reference.hh" diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 95aa103e46e..c4bb9d594b0 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -189,7 +189,7 @@ std::pair StoreDirConfig::computeStorePath( } -StoreConfig::Descriptions::Descriptions() +Store::Config::Descriptions::Descriptions() : StoreDirConfig::Descriptions{StoreDirConfig::descriptions} , StoreConfigT{ .pathInfoCacheSize = { @@ -235,19 +235,19 @@ StoreConfig::Descriptions::Descriptions() } -const StoreConfig::Descriptions StoreConfig::descriptions{}; +const Store::Config::Descriptions Store::Config::descriptions{}; -decltype(StoreConfig::defaults) StoreConfig::defaults = { +decltype(Store::Config::defaults) Store::Config::defaults = { .pathInfoCacheSize = { .value = 65536 }, .isTrusted = { .value = false }, .priority = { .value = 0 }, .wantMassQuery = { .value = false }, - .systemFeatures = { .value = StoreConfig::getDefaultSystemFeatures() }, + .systemFeatures = { .value = Store::Config::getDefaultSystemFeatures() }, }; -StoreConfig::StoreConfig(const StoreReference::Params & params) +Store::Config::StoreConfig(const StoreReference::Params & params) : StoreDirConfig{params} , StoreConfigT{ CONFIG_ROW(pathInfoCacheSize), @@ -491,7 +491,7 @@ ValidPathInfo Store::addToStoreSlow( return info; } -StringSet StoreConfig::getDefaultSystemFeatures() +StringSet Store::Config::getDefaultSystemFeatures() { auto res = settings.systemFeatures.get(); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 9d114ff40c7..09352e601ba 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -115,8 +115,6 @@ struct StoreConfig : StoreDirConfig, StoreConfigT { - StoreConfig(const StoreReference::Params &); - struct Descriptions : StoreDirConfig::Descriptions, StoreConfigT @@ -128,10 +126,12 @@ struct StoreConfig : static const Descriptions descriptions; - static StringSet getDefaultSystemFeatures(); + StoreConfig(const StoreReference::Params &); virtual ~StoreConfig() { } + static StringSet getDefaultSystemFeatures(); + /** * The name of this type of store. */ @@ -158,7 +158,7 @@ struct StoreConfig : * Open a store of the type corresponding to this configuration * type. */ - virtual std::shared_ptr open() = 0; + virtual std::shared_ptr openStore() = 0; }; class Store : public std::enable_shared_from_this, public virtual StoreConfig @@ -208,11 +208,6 @@ protected: Store(const Store::Config & config); public: - /** - * Perform any necessary effectful operation to make the store up and - * running - */ - virtual void init() {}; virtual ~Store() { } diff --git a/src/libstore/store-dir-config.hh b/src/libstore/store-dir-config.hh index 4f90c5b5fc5..19391322907 100644 --- a/src/libstore/store-dir-config.hh +++ b/src/libstore/store-dir-config.hh @@ -27,14 +27,14 @@ struct StoreDirConfigT struct StoreDirConfig : StoreDirConfigT { - StoreDirConfig(const StoreReference::Params & params); - static const StoreDirConfigT defaults; using Descriptions = StoreDirConfigT; static const Descriptions descriptions; + StoreDirConfig(const StoreReference::Params & params); + virtual ~StoreDirConfig() = default; const Path & storeDir = _storeDir.value; diff --git a/src/libutil/config-abstract.hh b/src/libutil/config-abstract.hh index 4737a29cc7c..7d546b33332 100644 --- a/src/libutil/config-abstract.hh +++ b/src/libutil/config-abstract.hh @@ -23,7 +23,7 @@ struct JustValue }; template -auto operator <<(auto str, const JustValue & opt) +auto && operator <<(auto && str, const JustValue & opt) { return str << opt.get(); } diff --git a/src/nix-channel/nix-channel.cc b/src/nix-channel/nix-channel.cc index 9f7f557b59d..d8d0d518b78 100644 --- a/src/nix-channel/nix-channel.cc +++ b/src/nix-channel/nix-channel.cc @@ -3,6 +3,7 @@ #include "globals.hh" #include "filetransfer.hh" #include "store-api.hh" +#include "store-open.hh" #include "legacy.hh" #include "eval-settings.hh" // for defexpr #include "users.hh" diff --git a/tests/unit/libstore-support/tests/libstore.hh b/tests/unit/libstore-support/tests/libstore.hh index 84be52c230b..5710a12d9b6 100644 --- a/tests/unit/libstore-support/tests/libstore.hh +++ b/tests/unit/libstore-support/tests/libstore.hh @@ -5,6 +5,7 @@ #include #include "store-api.hh" +#include "store-open.hh" namespace nix {