From 1c53a04401097d3c0dcb4f1dce1c8bb4b6b92487 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 21 Nov 2025 01:17:12 -0500 Subject: [PATCH] WIP get rid of global `Settings` in libstore This is analogous to 52bfccf8d8112ba738e6fc9e4891f85b6b864566 for `EvalSettings`, and 3fc77f281ef3def1f997c959687cba04660dd27d for `FlakeSettings` and `fetchers::Settings`. --- src/libcmd/command.cc | 11 +- src/libcmd/common-eval-args.cc | 6 +- .../include/nix/cmd/installable-attr-path.hh | 1 - src/libcmd/repl.cc | 4 +- src/libexpr-c/nix_api_expr.cc | 8 +- src/libexpr-c/nix_api_expr_internal.h | 2 - .../include/nix/expr/tests/libexpr.hh | 18 +-- src/libexpr-tests/eval.cc | 15 ++- src/libexpr/eval-cache.cc | 14 ++- src/libexpr/eval-settings.cc | 14 +-- src/libexpr/eval.cc | 5 +- src/libexpr/include/nix/expr/eval-settings.hh | 14 ++- src/libexpr/primops.cc | 38 +++---- src/libexpr/primops/context.cc | 2 +- src/libexpr/primops/fetchClosure.cc | 2 +- src/libfetchers-c/nix_api_fetchers.cc | 3 +- src/libfetchers-tests/access-tokens.cc | 23 ++-- src/libfetchers-tests/git.cc | 12 +- src/libfetchers-tests/input.cc | 7 +- src/libfetchers/cache.cc | 9 +- src/libfetchers/fetch-settings.cc | 5 +- src/libfetchers/fetch-to-store.cc | 8 +- src/libfetchers/git.cc | 16 +-- .../include/nix/fetchers/fetch-settings.hh | 10 +- src/libfetchers/registry.cc | 2 +- src/libflake-tests/flakeref.cc | 13 ++- src/libmain/common-args.cc | 1 + src/libmain/include/nix/main/shared.hh | 5 + src/libmain/shared.cc | 9 +- src/libstore-c/nix_api_store.cc | 9 +- src/libstore-c/nix_api_store_internal.h | 2 + .../include/nix/store/tests/libstore.hh | 9 +- .../include/nix/store/tests/test-main.hh | 7 ++ src/libstore-test-support/test-main.cc | 19 +++- .../derivation-advanced-attrs.cc | 8 +- src/libstore-tests/derivation/invariants.cc | 6 +- src/libstore-tests/dummy-store.cc | 15 ++- src/libstore-tests/http-binary-cache-store.cc | 14 ++- src/libstore-tests/legacy-ssh-store.cc | 4 + .../local-binary-cache-store.cc | 4 +- src/libstore-tests/local-overlay-store.cc | 7 +- src/libstore-tests/local-store.cc | 16 +-- src/libstore-tests/nar-info-disk-cache.cc | 15 ++- src/libstore-tests/nix_api_store.cc | 24 ++-- src/libstore-tests/s3-binary-cache-store.cc | 26 +++-- src/libstore-tests/ssh-store.cc | 8 +- src/libstore-tests/uds-remote-store.cc | 20 +++- src/libstore-tests/write-derivation.cc | 13 ++- .../build/derivation-building-goal.cc | 56 ++++++---- src/libstore/build/derivation-goal.cc | 5 +- .../build/drv-output-substitution-goal.cc | 3 +- src/libstore/build/goal.cc | 2 +- src/libstore/build/substitution-goal.cc | 7 +- src/libstore/build/worker.cc | 45 ++++---- src/libstore/builtins/fetchurl.cc | 10 +- src/libstore/common-ssh-store-config.cc | 9 +- src/libstore/daemon.cc | 4 +- src/libstore/derivation-options.cc | 8 +- src/libstore/derivations.cc | 2 +- src/libstore/dummy-store.cc | 8 +- src/libstore/filetransfer.cc | 27 ++++- src/libstore/gc.cc | 5 +- src/libstore/globals.cc | 57 ++++------ src/libstore/http-binary-cache-store.cc | 10 +- .../nix/store/build/derivation-builder.hh | 4 + src/libstore/include/nix/store/builtins.hh | 3 + .../nix/store/common-ssh-store-config.hh | 9 +- .../include/nix/store/derivation-options.hh | 3 +- src/libstore/include/nix/store/dummy-store.hh | 19 +++- .../include/nix/store/filetransfer.hh | 65 +++++++++++ src/libstore/include/nix/store/globals.hh | 103 +++++------------- .../nix/store/http-binary-cache-store.hh | 5 +- src/libstore/include/nix/store/keys.hh | 10 +- .../include/nix/store/legacy-ssh-store.hh | 3 +- .../nix/store/local-binary-cache-store.hh | 3 +- .../include/nix/store/local-fs-store.hh | 10 +- .../include/nix/store/local-overlay-store.hh | 12 +- src/libstore/include/nix/store/local-store.hh | 3 +- src/libstore/include/nix/store/machines.hh | 5 +- .../include/nix/store/nar-info-disk-cache.hh | 9 +- .../nix/store/posix-fs-canonicalise.hh | 4 + src/libstore/include/nix/store/profiles.hh | 13 ++- .../nix/store/s3-binary-cache-store.hh | 3 +- src/libstore/include/nix/store/sqlite.hh | 8 +- src/libstore/include/nix/store/ssh-store.hh | 7 +- src/libstore/include/nix/store/store-api.hh | 27 ++++- .../include/nix/store/store-dir-config.hh | 2 + src/libstore/include/nix/store/store-open.hh | 19 ++-- .../include/nix/store/store-registration.hh | 15 ++- .../include/nix/store/uds-remote-store.hh | 5 +- src/libstore/keys.cc | 2 +- src/libstore/legacy-ssh-store.cc | 13 ++- .../linux/include/nix/store/personality.hh | 8 +- src/libstore/linux/personality.cc | 2 +- src/libstore/local-binary-cache-store.cc | 6 +- src/libstore/local-fs-store.cc | 8 +- src/libstore/local-overlay-store.cc | 3 +- src/libstore/local-store.cc | 57 +++++----- src/libstore/machines.cc | 6 +- src/libstore/misc.cc | 8 +- src/libstore/nar-info-disk-cache.cc | 15 ++- src/libstore/optimise-store.cc | 2 +- src/libstore/posix-fs-canonicalise.cc | 6 + src/libstore/profiles.cc | 18 +-- src/libstore/remote-store.cc | 2 + src/libstore/s3-binary-cache-store.cc | 6 +- src/libstore/sqlite.cc | 8 +- src/libstore/ssh-store.cc | 34 +++--- src/libstore/store-api.cc | 28 ++--- src/libstore/store-dir-config.cc | 1 + src/libstore/store-registration.cc | 32 +++--- src/libstore/uds-remote-store.cc | 17 +-- src/libstore/unix/build/derivation-builder.cc | 27 +++-- src/libstore/unix/build/hook-instance.cc | 10 +- .../unix/build/linux-derivation-builder.cc | 14 +-- .../include/nix/store/build/hook-instance.hh | 2 +- .../unix/include/nix/store/user-lock.hh | 13 ++- src/libstore/unix/user-lock.cc | 26 +++-- src/nix/add-to-store.cc | 6 +- src/nix/build-remote/build-remote.cc | 6 +- src/nix/flake-prefetch-inputs.cc | 9 +- src/nix/flake.cc | 2 +- src/nix/log.cc | 2 +- src/nix/main.cc | 4 +- src/nix/make-content-addressed.cc | 2 +- src/nix/nix-build/nix-build.cc | 4 +- src/nix/nix-channel/nix-channel.cc | 6 +- .../nix-collect-garbage.cc | 6 +- src/nix/nix-copy-closure/nix-copy-closure.cc | 4 +- src/nix/nix-env/nix-env.cc | 10 +- src/nix/nix-instantiate/nix-instantiate.cc | 4 +- src/nix/nix-store/nix-store.cc | 4 +- src/nix/prefetch.cc | 2 +- src/nix/repl.cc | 2 +- src/nix/run.cc | 4 +- src/nix/sigs.cc | 2 +- src/nix/unix/daemon.cc | 2 +- src/nix/verify.cc | 4 +- src/perl/lib/Nix/Store.xs | 7 +- src/perl/meson.build | 5 + src/perl/package.nix | 2 + .../functional/test-libstoreconsumer/main.cc | 4 +- 142 files changed, 967 insertions(+), 640 deletions(-) diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index 798ef072eb1..3ccbe768539 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -4,6 +4,7 @@ #include "nix/cmd/command.hh" #include "nix/cmd/legacy.hh" #include "nix/cmd/markdown.hh" +#include "nix/main/shared.hh" #include "nix/store/store-open.hh" #include "nix/store/local-fs-store.hh" #include "nix/store/derivations.hh" @@ -74,7 +75,7 @@ ref StoreCommand::getStore() ref StoreCommand::createStore() { - return openStore(); + return openStore(settings); } void StoreCommand::run() @@ -101,7 +102,7 @@ CopyCommand::CopyCommand() ref CopyCommand::createStore() { - return srcUri.empty() ? StoreCommand::createStore() : openStore(srcUri); + return srcUri.empty() ? StoreCommand::createStore() : openStore(settings, srcUri); } ref CopyCommand::getDstStore() @@ -109,7 +110,7 @@ ref CopyCommand::getDstStore() if (srcUri.empty() && dstUri.empty()) throw UsageError("you must pass '--from' and/or '--to'"); - return dstUri.empty() ? openStore() : openStore(dstUri); + return dstUri.empty() ? openStore(settings) : openStore(settings, dstUri); } EvalCommand::EvalCommand() @@ -131,7 +132,7 @@ EvalCommand::~EvalCommand() ref EvalCommand::getEvalStore() { if (!evalStore) - evalStore = evalStoreUrl ? openStore(*evalStoreUrl) : getStore(); + evalStore = evalStoreUrl ? openStore(settings, *evalStoreUrl) : getStore(); return ref(evalStore); } @@ -297,7 +298,7 @@ void MixProfile::updateProfile(const BuiltPaths & buildables) MixDefaultProfile::MixDefaultProfile() { - profile = getDefaultProfile().string(); + profile = getDefaultProfile(settings).string(); } MixEnvironment::MixEnvironment() diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc index 30e76b2455d..e5f8925d450 100644 --- a/src/libcmd/common-eval-args.cc +++ b/src/libcmd/common-eval-args.cc @@ -19,12 +19,12 @@ namespace nix { -fetchers::Settings fetchSettings; +fetchers::Settings fetchSettings{settings}; static GlobalConfig::Register rFetchSettings(&fetchSettings); EvalSettings evalSettings{ - settings.readOnlyMode, + settings, { { "flake", @@ -135,7 +135,7 @@ MixEvalArgs::MixEvalArgs() fetchers::overrideRegistry(from.input, to.input, extraAttrs); }}, .completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) { - completeFlakeRef(completions, openStore(), prefix); + completeFlakeRef(completions, openStore(settings), prefix); }}, }); diff --git a/src/libcmd/include/nix/cmd/installable-attr-path.hh b/src/libcmd/include/nix/cmd/installable-attr-path.hh index 474bb358ec9..8deee4a37e0 100644 --- a/src/libcmd/include/nix/cmd/installable-attr-path.hh +++ b/src/libcmd/include/nix/cmd/installable-attr-path.hh @@ -1,7 +1,6 @@ #pragma once ///@file -#include "nix/store/globals.hh" #include "nix/cmd/installable-value.hh" #include "nix/store/outputs-spec.hh" #include "nix/cmd/command.hh" diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc index 38a0da0f818..490fb7c9568 100644 --- a/src/libcmd/repl.cc +++ b/src/libcmd/repl.cc @@ -566,7 +566,7 @@ ProcessLineResult NixRepl::processLine(std::string line) } else if (command == ":log") { settings.readOnlyMode = true; Finally roModeReset([&]() { settings.readOnlyMode = false; }); - auto subs = getDefaultSubstituters(); + auto subs = getDefaultSubstituters(settings); subs.push_front(state->store); @@ -919,7 +919,7 @@ ReplExitStatus AbstractNixRepl::runSimple(ref evalState, const ValMap // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDelete) auto repl = std::make_unique( lookupPath, - openStore(), + openStore(settings), evalState, getValues, /*runNix=*/nullptr); diff --git a/src/libexpr-c/nix_api_expr.cc b/src/libexpr-c/nix_api_expr.cc index 0dd9fa0a51d..52648bb8b61 100644 --- a/src/libexpr-c/nix_api_expr.cc +++ b/src/libexpr-c/nix_api_expr.cc @@ -132,9 +132,8 @@ nix_eval_state_builder * nix_eval_state_builder_new(nix_c_context * context, Sto return unsafe_new_with_self([&](auto * self) { return nix_eval_state_builder{ .store = nix::ref(store->ptr), - .settings = nix::EvalSettings{/* &bool */ self->readOnlyMode}, - .fetchSettings = nix::fetchers::Settings{}, - .readOnlyMode = true, + .settings = nix::EvalSettings{cStoreSettings}, + .fetchSettings = nix::fetchers::Settings{cStoreSettings}, }; }); } @@ -153,8 +152,7 @@ nix_err nix_eval_state_builder_load(nix_c_context * context, nix_eval_state_buil if (context) context->last_err_code = NIX_OK; try { - // TODO: load in one go? - builder->settings.readOnlyMode = nix::settings.readOnlyMode; + loadConfFile(cStoreSettings); loadConfFile(builder->settings); loadConfFile(builder->fetchSettings); } diff --git a/src/libexpr-c/nix_api_expr_internal.h b/src/libexpr-c/nix_api_expr_internal.h index 07c7a2194df..0e5389e3783 100644 --- a/src/libexpr-c/nix_api_expr_internal.h +++ b/src/libexpr-c/nix_api_expr_internal.h @@ -16,8 +16,6 @@ struct nix_eval_state_builder nix::EvalSettings settings; nix::fetchers::Settings fetchSettings; nix::LookupPath lookupPath; - // TODO: make an EvalSettings setting own this instead? - bool readOnlyMode; }; struct EvalState diff --git a/src/libexpr-test-support/include/nix/expr/tests/libexpr.hh b/src/libexpr-test-support/include/nix/expr/tests/libexpr.hh index 658a6ffe0a3..7150096e679 100644 --- a/src/libexpr-test-support/include/nix/expr/tests/libexpr.hh +++ b/src/libexpr-test-support/include/nix/expr/tests/libexpr.hh @@ -26,18 +26,18 @@ public: } protected: - LibExprTest(ref store, auto && makeEvalSettings) - : LibStoreTest() - , evalSettings(makeEvalSettings(readOnlyMode)) + LibExprTest(auto && makeEvalSettings, auto &&... args) + : LibStoreTest(args...) + , evalSettings(makeEvalSettings(settings)) , state({}, store, fetchSettings, evalSettings, nullptr) { } LibExprTest() - : LibExprTest(openStore("dummy://"), [](bool & readOnlyMode) { - EvalSettings settings{readOnlyMode}; - settings.nixPath = {}; - return settings; + : LibExprTest([](Settings & settings) { + EvalSettings evalSettings{settings}; + evalSettings.nixPath = {}; + return evalSettings; }) { } @@ -66,8 +66,8 @@ protected: } bool readOnlyMode = true; - fetchers::Settings fetchSettings{}; - EvalSettings evalSettings{readOnlyMode}; + fetchers::Settings fetchSettings{settings}; + EvalSettings evalSettings{settings}; EvalState state; }; diff --git a/src/libexpr-tests/eval.cc b/src/libexpr-tests/eval.cc index 7562a9da21a..3bcef1e820c 100644 --- a/src/libexpr-tests/eval.cc +++ b/src/libexpr-tests/eval.cc @@ -179,12 +179,15 @@ class PureEvalTest : public LibExprTest { public: PureEvalTest() - : LibExprTest(openStore("dummy://", {{"read-only", "false"}}), [](bool & readOnlyMode) { - EvalSettings settings{readOnlyMode}; - settings.pureEval = true; - settings.restrictEval = true; - return settings; - }) + : LibExprTest{ + [](auto & settings) { + EvalSettings evalSettings{settings}; + evalSettings.pureEval = true; + evalSettings.restrictEval = true; + return evalSettings; + }, + [](auto & settings) { return openStore(settings, "dummy://", {{"read-only", "false"}}); }, + } { } }; diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc index 4cfa3dabbac..8be7337872e 100644 --- a/src/libexpr/eval-cache.cc +++ b/src/libexpr/eval-cache.cc @@ -63,7 +63,7 @@ struct AttrDb SymbolTable & symbols; - AttrDb(const StoreDirConfig & cfg, const Hash & fingerprint, SymbolTable & symbols) + AttrDb(bool useSQLiteWAL, const StoreDirConfig & cfg, const Hash & fingerprint, SymbolTable & symbols) : cfg(cfg) , _state(std::make_unique>()) , symbols(symbols) @@ -75,7 +75,7 @@ struct AttrDb auto dbPath = cacheDir / (fingerprint.to_string(HashFormat::Base16, false) + ".sqlite"); - state->db = SQLite(dbPath); + state->db = SQLite(dbPath, {.useWAL = useSQLiteWAL}); state->db.isCache(); state->db.exec(schema); @@ -287,10 +287,11 @@ struct AttrDb } }; -static std::shared_ptr makeAttrDb(const StoreDirConfig & cfg, const Hash & fingerprint, SymbolTable & symbols) +static std::shared_ptr +makeAttrDb(bool useSQLiteWAL, const StoreDirConfig & cfg, const Hash & fingerprint, SymbolTable & symbols) { try { - return std::make_shared(cfg, fingerprint, symbols); + return std::make_shared(useSQLiteWAL, cfg, fingerprint, symbols); } catch (SQLiteError &) { ignoreExceptionExceptInterrupt(); return nullptr; @@ -299,7 +300,8 @@ static std::shared_ptr makeAttrDb(const StoreDirConfig & cfg, const Hash EvalCache::EvalCache( std::optional> useCache, EvalState & state, RootLoader rootLoader) - : db(useCache ? makeAttrDb(*state.store, *useCache, state.symbols) : nullptr) + : db(useCache ? makeAttrDb(state.store->config.settings.useSQLiteWAL, *state.store, *useCache, state.symbols) + : nullptr) , state(state) , rootLoader(rootLoader) { @@ -707,7 +709,7 @@ StorePath AttrCursor::forceDerivation() auto aDrvPath = getAttr(root->state.s.drvPath); auto drvPath = root->state.store->parseStorePath(aDrvPath->getString()); drvPath.requireDerivation(); - if (!root->state.store->isValidPath(drvPath) && !settings.readOnlyMode) { + if (!root->state.store->isValidPath(drvPath) && !root->state.store->config.settings.readOnlyMode) { /* The eval cache contains 'drvPath', but the actual path has been garbage-collected. So force it to be regenerated. */ aDrvPath->forceValue(); diff --git a/src/libexpr/eval-settings.cc b/src/libexpr/eval-settings.cc index 8e8b6bcd976..9c4fde11cf8 100644 --- a/src/libexpr/eval-settings.cc +++ b/src/libexpr/eval-settings.cc @@ -48,8 +48,8 @@ Strings EvalSettings::parseNixPath(const std::string & s) return res; } -EvalSettings::EvalSettings(bool & readOnlyMode, EvalSettings::LookupPathHooks lookupPathHooks) - : readOnlyMode{readOnlyMode} +EvalSettings::EvalSettings(nix::Settings & settings, EvalSettings::LookupPathHooks lookupPathHooks) + : settings{settings} , lookupPathHooks{lookupPathHooks} { auto var = getEnv("NIX_ABORT_ON_WARN"); @@ -57,7 +57,7 @@ EvalSettings::EvalSettings(bool & readOnlyMode, EvalSettings::LookupPathHooks lo builtinsAbortOnWarn = true; } -Strings EvalSettings::getDefaultNixPath() +Strings EvalSettings::getDefaultNixPath(nix::Settings & settings) { Strings res; auto add = [&](const std::filesystem::path & p, const std::string & s = std::string()) { @@ -70,9 +70,9 @@ Strings EvalSettings::getDefaultNixPath() } }; - add(std::filesystem::path{getNixDefExpr()} / "channels"); - add(rootChannelsDir() / "nixpkgs", "nixpkgs"); - add(rootChannelsDir()); + add(std::filesystem::path{getNixDefExpr(settings)} / "channels"); + add(rootChannelsDir(settings) / "nixpkgs", "nixpkgs"); + add(rootChannelsDir(settings)); return res; } @@ -103,7 +103,7 @@ const std::string & EvalSettings::getCurrentSystem() const return evalSystem != "" ? evalSystem : settings.thisSystem.get(); } -Path getNixDefExpr() +Path getNixDefExpr(const Settings & settings) { return settings.useXDGBaseDirectories ? getStateDir() + "/defexpr" : getHome() + "/.nix-defexpr"; } diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 71834f10f89..fd009fb3b81 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -15,6 +15,7 @@ #include "nix/store/filetransfer.hh" #include "nix/expr/function-trace.hh" #include "nix/store/profiles.hh" +#include "nix/store/globals.hh" #include "nix/expr/print.hh" #include "nix/fetchers/filtering-source-accessor.hh" #include "nix/util/memory-source-accessor.hh" @@ -331,7 +332,7 @@ EvalState::EvalState( lookupPath.elements.emplace_back(LookupPath::Elem::parse(i)); } if (!settings.restrictEval) { - for (auto & i : EvalSettings::getDefaultNixPath()) { + for (auto & i : EvalSettings::getDefaultNixPath(store->config.settings)) { lookupPath.elements.emplace_back(LookupPath::Elem::parse(i)); } } @@ -2502,7 +2503,7 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat fetchSettings, *store, path.resolveSymlinks(SymlinkResolution::Ancestors), - settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy, + settings.settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy, path.baseName(), ContentAddressMethod::Raw::NixArchive, nullptr, diff --git a/src/libexpr/include/nix/expr/eval-settings.hh b/src/libexpr/include/nix/expr/eval-settings.hh index 250c2cddf37..9b4c1b2005b 100644 --- a/src/libexpr/include/nix/expr/eval-settings.hh +++ b/src/libexpr/include/nix/expr/eval-settings.hh @@ -9,9 +9,15 @@ namespace nix { class EvalState; struct PrimOp; +class Settings; struct EvalSettings : Config { + /** + * Reference to the "parent" store-layer settings. + */ + nix::Settings & settings; + /** * Function used to interpret look path entries of a given scheme. * @@ -38,11 +44,9 @@ struct EvalSettings : Config */ using LookupPathHooks = std::map>; - EvalSettings(bool & readOnlyMode, LookupPathHooks lookupPathHooks = {}); - - bool & readOnlyMode; + EvalSettings(nix::Settings & settings, LookupPathHooks lookupPathHooks = {}); - static Strings getDefaultNixPath(); + static Strings getDefaultNixPath(nix::Settings & settings); static bool isPseudoUrl(std::string_view s); @@ -366,6 +370,6 @@ struct EvalSettings : Config /** * Conventionally part of the default nix path in impure mode. */ -Path getNixDefExpr(); +Path getNixDefExpr(const Settings & settings); } // namespace nix diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 83d3f667f2e..06f0723c584 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1893,7 +1893,7 @@ static void prim_storePath(EvalState & state, const PosIdx pos, Value ** args, V if (!state.store->isInStore(path.abs())) state.error("path '%1%' is not in the Nix store", path).atPos(pos).debugThrow(); auto path2 = state.store->toStorePath(path.abs()).first; - if (!settings.readOnlyMode) + if (!state.settings.settings.readOnlyMode) state.store->ensurePath(path2); context.insert(NixStringContextElem::Opaque{.path = path2}); v.mkString(path.abs(), context, state.mem); @@ -2634,23 +2634,23 @@ static void prim_toFile(EvalState & state, const PosIdx pos, Value ** args, Valu .debugThrow(); } - auto storePath = settings.readOnlyMode ? state.store->makeFixedOutputPathFromCA( - name, - TextInfo{ - .hash = hashString(HashAlgorithm::SHA256, contents), - .references = std::move(refs), - }) - : ({ - StringSource s{contents}; - state.store->addToStoreFromDump( - s, - name, - FileSerialisationMethod::Flat, - ContentAddressMethod::Raw::Text, - HashAlgorithm::SHA256, - refs, - state.repair); - }); + auto storePath = state.settings.settings.readOnlyMode ? state.store->makeFixedOutputPathFromCA( + name, + TextInfo{ + .hash = hashString(HashAlgorithm::SHA256, contents), + .references = std::move(refs), + }) + : ({ + StringSource s{contents}; + state.store->addToStoreFromDump( + s, + name, + FileSerialisationMethod::Flat, + ContentAddressMethod::Raw::Text, + HashAlgorithm::SHA256, + refs, + state.repair); + }); /* Note: we don't need to add `context' to the context of the result, since `storePath' itself has references to the paths @@ -2790,7 +2790,7 @@ static void addPath( state.fetchSettings, *state.store, path.resolveSymlinks(), - settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy, + state.settings.settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy, name, method, filter.get(), diff --git a/src/libexpr/primops/context.cc b/src/libexpr/primops/context.cc index 70c13e2985b..cafdbb751c8 100644 --- a/src/libexpr/primops/context.cc +++ b/src/libexpr/primops/context.cc @@ -271,7 +271,7 @@ static void prim_appendContext(EvalState & state, const PosIdx pos, Value ** arg if (!state.store->isStorePath(name)) state.error("context key '%s' is not a store path", name).atPos(i.pos).debugThrow(); auto namePath = state.store->parseStorePath(name); - if (!settings.readOnlyMode) + if (!state.settings.settings.readOnlyMode) state.store->ensurePath(namePath); state.forceAttrs(*i.value, i.pos, "while evaluating the value of a string context"); diff --git a/src/libexpr/primops/fetchClosure.cc b/src/libexpr/primops/fetchClosure.cc index 6e1389814fc..cfc911bc79d 100644 --- a/src/libexpr/primops/fetchClosure.cc +++ b/src/libexpr/primops/fetchClosure.cc @@ -203,7 +203,7 @@ static void prim_fetchClosure(EvalState & state, const PosIdx pos, Value ** args {.msg = HintFmt("'fetchClosure' does not support URL query parameters (in '%s')", *fromStoreUrl), .pos = state.positions[pos]}); - auto fromStore = openStore(parsedURL.to_string()); + auto fromStore = openStore(state.settings.settings, parsedURL.to_string()); if (toPath) runFetchClosureWithRewrite(state, pos, *fromStore, *fromPath, *toPath, v); diff --git a/src/libfetchers-c/nix_api_fetchers.cc b/src/libfetchers-c/nix_api_fetchers.cc index 7fefedb0c70..be54fc912cf 100644 --- a/src/libfetchers-c/nix_api_fetchers.cc +++ b/src/libfetchers-c/nix_api_fetchers.cc @@ -1,13 +1,14 @@ #include "nix_api_fetchers.h" #include "nix_api_fetchers_internal.hh" #include "nix_api_util_internal.h" +#include "nix_api_store_internal.h" extern "C" { nix_fetchers_settings * nix_fetchers_settings_new(nix_c_context * context) { try { - auto fetchersSettings = nix::make_ref(nix::fetchers::Settings{}); + auto fetchersSettings = nix::make_ref(nix::fetchers::Settings{cStoreSettings}); return new nix_fetchers_settings{ .settings = fetchersSettings, }; diff --git a/src/libfetchers-tests/access-tokens.cc b/src/libfetchers-tests/access-tokens.cc index 7127434db9d..57d638147f8 100644 --- a/src/libfetchers-tests/access-tokens.cc +++ b/src/libfetchers-tests/access-tokens.cc @@ -1,9 +1,12 @@ #include #include +#include "nix/util/json-utils.hh" +#include "nix/store/globals.hh" #include "nix/fetchers/fetchers.hh" #include "nix/fetchers/fetch-settings.hh" -#include "nix/util/json-utils.hh" + +#include "nix/store/tests/test-main.hh" #include "nix/util/tests/characterization.hh" namespace nix::fetchers { @@ -25,7 +28,8 @@ class AccessKeysTest : public ::testing::Test TEST_F(AccessKeysTest, singleOrgGitHub) { - fetchers::Settings fetchSettings = fetchers::Settings{}; + auto settings = getTestSettings(); + fetchers::Settings fetchSettings = fetchers::Settings{settings}; fetchSettings.accessTokens.get().insert({"github.com/a", "token"}); auto i = Input::fromURL(fetchSettings, "github:a/b"); @@ -35,7 +39,8 @@ TEST_F(AccessKeysTest, singleOrgGitHub) TEST_F(AccessKeysTest, nonMatches) { - fetchers::Settings fetchSettings = fetchers::Settings{}; + auto settings = getTestSettings(); + fetchers::Settings fetchSettings = fetchers::Settings{settings}; fetchSettings.accessTokens.get().insert({"github.com", "token"}); auto i = Input::fromURL(fetchSettings, "gitlab:github.com/evil"); @@ -45,7 +50,8 @@ TEST_F(AccessKeysTest, nonMatches) TEST_F(AccessKeysTest, noPartialMatches) { - fetchers::Settings fetchSettings = fetchers::Settings{}; + auto settings = getTestSettings(); + fetchers::Settings fetchSettings = fetchers::Settings{settings}; fetchSettings.accessTokens.get().insert({"github.com/partial", "token"}); auto i = Input::fromURL(fetchSettings, "github:partial-match/repo"); @@ -55,7 +61,8 @@ TEST_F(AccessKeysTest, noPartialMatches) TEST_F(AccessKeysTest, repoGitHub) { - fetchers::Settings fetchSettings = fetchers::Settings{}; + auto settings = getTestSettings(); + fetchers::Settings fetchSettings = fetchers::Settings{settings}; fetchSettings.accessTokens.get().insert({"github.com", "token"}); fetchSettings.accessTokens.get().insert({"github.com/a/b", "another_token"}); fetchSettings.accessTokens.get().insert({"github.com/a/c", "yet_another_token"}); @@ -73,7 +80,8 @@ TEST_F(AccessKeysTest, repoGitHub) TEST_F(AccessKeysTest, multipleGitLab) { - fetchers::Settings fetchSettings = fetchers::Settings{}; + auto settings = getTestSettings(); + fetchers::Settings fetchSettings = fetchers::Settings{settings}; fetchSettings.accessTokens.get().insert({"gitlab.com", "token"}); fetchSettings.accessTokens.get().insert({"gitlab.com/a/b", "another_token"}); auto i = Input::fromURL(fetchSettings, "gitlab:a/b"); @@ -87,7 +95,8 @@ TEST_F(AccessKeysTest, multipleGitLab) TEST_F(AccessKeysTest, multipleSourceHut) { - fetchers::Settings fetchSettings = fetchers::Settings{}; + auto settings = getTestSettings(); + fetchers::Settings fetchSettings = fetchers::Settings{settings}; fetchSettings.accessTokens.get().insert({"git.sr.ht", "token"}); fetchSettings.accessTokens.get().insert({"git.sr.ht/~a/b", "another_token"}); auto i = Input::fromURL(fetchSettings, "sourcehut:a/b"); diff --git a/src/libfetchers-tests/git.cc b/src/libfetchers-tests/git.cc index abc3dd74c5c..8ddc1ca3639 100644 --- a/src/libfetchers-tests/git.cc +++ b/src/libfetchers-tests/git.cc @@ -5,6 +5,8 @@ #include "nix/fetchers/fetchers.hh" #include "nix/fetchers/git-utils.hh" +#include "nix/store/tests/test-main.hh" + #include #include @@ -180,13 +182,15 @@ TEST_F(GitTest, submodulePeriodSupport) // 6) Commit the addition in super commitAll(super.get(), "Add submodule with branch='.'"); - auto store = [] { - auto cfg = make_ref(StoreReference::Params{}); + auto settings = getTestSettings(); + + auto store = [&] { + auto cfg = make_ref(settings, StoreReference::Params{}); cfg->readOnly = false; return cfg->openStore(); }(); - auto settings = fetchers::Settings{}; + auto fetchSettings = fetchers::Settings{settings}; auto input = fetchers::Input::fromAttrs( settings, { @@ -196,7 +200,7 @@ TEST_F(GitTest, submodulePeriodSupport) {"ref", "main"}, }); - auto [accessor, i] = input.getAccessor(settings, *store); + auto [accessor, i] = input.getAccessor(fetchSettings, *store); ASSERT_EQ(accessor->readFile(CanonPath("deps/sub/lib.txt")), "hello from submodule\n"); } diff --git a/src/libfetchers-tests/input.cc b/src/libfetchers-tests/input.cc index faff55f2c2d..aa45580409a 100644 --- a/src/libfetchers-tests/input.cc +++ b/src/libfetchers-tests/input.cc @@ -1,7 +1,11 @@ +#include "nix/store/globals.hh" + #include "nix/fetchers/fetch-settings.hh" #include "nix/fetchers/attrs.hh" #include "nix/fetchers/fetchers.hh" +#include "nix/store/tests/test-main.hh" + #include #include @@ -23,7 +27,8 @@ class InputFromAttrsTest : public ::testing::WithParamInterface _state; - CacheImpl() + CacheImpl(const nix::Settings & settings) + : settings(settings) { auto state(_state.lock()); auto dbPath = getCacheDir() + "/fetcher-cache-v4.sqlite"; createDirs(dirOf(dbPath)); - state->db = SQLite(dbPath); + state->db = SQLite(dbPath, {.useWAL = settings.useSQLiteWAL}); state->db.isCache(); state->db.exec(schema); @@ -154,7 +157,7 @@ ref Settings::getCache() const { auto cache(_cache.lock()); if (!*cache) - *cache = std::make_shared(); + *cache = std::make_shared(settings); return ref(*cache); } diff --git a/src/libfetchers/fetch-settings.cc b/src/libfetchers/fetch-settings.cc index f92b94a0b3b..a08e95a6d33 100644 --- a/src/libfetchers/fetch-settings.cc +++ b/src/libfetchers/fetch-settings.cc @@ -2,6 +2,9 @@ namespace nix::fetchers { -Settings::Settings() {} +Settings::Settings(const nix::Settings & settings) + : settings(settings) +{ +} } // namespace nix::fetchers diff --git a/src/libfetchers/fetch-to-store.cc b/src/libfetchers/fetch-to-store.cc index b1e8b9d72bb..8d11a5b834a 100644 --- a/src/libfetchers/fetch-to-store.cc +++ b/src/libfetchers/fetch-to-store.cc @@ -53,9 +53,11 @@ StorePath fetchToStore( auto filter2 = filter ? *filter : defaultPathFilter; - auto storePath = mode == FetchMode::DryRun - ? store.computeStorePath(name, path, method, HashAlgorithm::SHA256, {}, filter2).first - : store.addToStore(name, path, method, HashAlgorithm::SHA256, {}, filter2, repair); + auto storePath = + mode == FetchMode::DryRun + ? store.computeStorePath(store.config.settings, name, path, method, HashAlgorithm::SHA256, {}, filter2) + .first + : store.addToStore(name, path, method, HashAlgorithm::SHA256, {}, filter2, repair); debug(mode == FetchMode::DryRun ? "hashed '%s'" : "copied '%s' to '%s'", path, store.printStorePath(storePath)); diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc index 75e3f121481..b9584fefe0e 100644 --- a/src/libfetchers/git.cc +++ b/src/libfetchers/git.cc @@ -37,9 +37,9 @@ namespace { // old version of git, which will ignore unrecognized `-c` options. const std::string gitInitialBranch = "__nix_dummy_branch"; -bool isCacheFileWithinTtl(time_t now, const struct stat & st) +static bool isCacheFileWithinTtl(const Settings & settings, time_t now, const struct stat & st) { - return st.st_mtime + static_cast(settings.tarballTtl) > now; + return st.st_mtime + static_cast(settings.settings.tarballTtl) > now; } Path getCachePath(std::string_view key, bool shallow) @@ -105,7 +105,7 @@ bool storeCachedHead(const std::string & actualUrl, bool shallow, const std::str return true; } -std::optional readHeadCached(const std::string & actualUrl, bool shallow) +static std::optional readHeadCached(const Settings & settings, const std::string & actualUrl, bool shallow) { // Create a cache path to store the branch of the HEAD ref. Append something // in front of the URL to prevent collision with the repository itself. @@ -117,7 +117,7 @@ std::optional readHeadCached(const std::string & actualUrl, bool sh std::optional cachedRef; if (stat(headRefFile.c_str(), &st) == 0) { cachedRef = readHead(cacheDir); - if (cachedRef != std::nullopt && *cachedRef != gitInitialBranch && isCacheFileWithinTtl(now, st)) { + if (cachedRef != std::nullopt && *cachedRef != gitInitialBranch && isCacheFileWithinTtl(settings, now, st)) { debug("using cached HEAD ref '%s' for repo '%s'", *cachedRef, actualUrl); return cachedRef; } @@ -733,12 +733,12 @@ struct GitInputScheme : InputScheme return revCount; } - std::string getDefaultRef(const RepoInfo & repoInfo, bool shallow) const + std::string getDefaultRef(const Settings & settings, const RepoInfo & repoInfo, bool shallow) const { auto head = std::visit( overloaded{ [&](const std::filesystem::path & path) { return GitRepo::openRepo(path)->getWorkdirRef(); }, - [&](const ParsedURL & url) { return readHeadCached(url.to_string(), shallow); }}, + [&](const ParsedURL & url) { return readHeadCached(settings, url.to_string(), shallow); }}, repoInfo.location); if (!head) { warn("could not read HEAD ref from repo at '%s', using 'master'", repoInfo.locationToArg()); @@ -787,7 +787,7 @@ struct GitInputScheme : InputScheme auto originalRef = input.getRef(); bool shallow = getShallowAttr(input); - auto ref = originalRef ? *originalRef : getDefaultRef(repoInfo, shallow); + auto ref = originalRef ? *originalRef : getDefaultRef(settings, repoInfo, shallow); input.attrs.insert_or_assign("ref", ref); std::filesystem::path repoDir; @@ -826,7 +826,7 @@ struct GitInputScheme : InputScheme /* If the local ref is older than ‘tarball-ttl’ seconds, do a git fetch to update the local ref to the remote ref. */ struct stat st; - doFetch = stat(localRefFile.string().c_str(), &st) != 0 || !isCacheFileWithinTtl(now, st); + doFetch = stat(localRefFile.string().c_str(), &st) != 0 || !isCacheFileWithinTtl(settings, now, st); } } diff --git a/src/libfetchers/include/nix/fetchers/fetch-settings.hh b/src/libfetchers/include/nix/fetchers/fetch-settings.hh index 8cfa7f6091e..47c8054db69 100644 --- a/src/libfetchers/include/nix/fetchers/fetch-settings.hh +++ b/src/libfetchers/include/nix/fetchers/fetch-settings.hh @@ -13,9 +13,10 @@ namespace nix { +class Settings; struct GitRepo; -} +} // namespace nix namespace nix::fetchers { @@ -23,7 +24,12 @@ struct Cache; struct Settings : public Config { - Settings(); + /** + * Reference to the "parent" store-layer settings. + */ + const nix::Settings & settings; + + Settings(const nix::Settings & settings); Setting accessTokens{ this, diff --git a/src/libfetchers/registry.cc b/src/libfetchers/registry.cc index cb360f03c9e..5f874bfe024 100644 --- a/src/libfetchers/registry.cc +++ b/src/libfetchers/registry.cc @@ -92,7 +92,7 @@ void Registry::remove(const Input & input) static Path getSystemRegistryPath() { - return settings.nixConfDir + "/registry.json"; + return bootstrapSettings.nixConfDir + "/registry.json"; } static std::shared_ptr getSystemRegistry(const Settings & settings) diff --git a/src/libflake-tests/flakeref.cc b/src/libflake-tests/flakeref.cc index eb8b56ea29d..2fc12c16f8b 100644 --- a/src/libflake-tests/flakeref.cc +++ b/src/libflake-tests/flakeref.cc @@ -3,6 +3,7 @@ #include #include +#include "nix/store/globals.hh" #include "nix/fetchers/fetch-settings.hh" #include "nix/flake/flakeref.hh" #include "nix/fetchers/attrs.hh" @@ -19,7 +20,8 @@ TEST(parseFlakeRef, path) { experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::Flakes); - fetchers::Settings fetchSettings; + Settings settings; + fetchers::Settings fetchSettings{settings}; { auto s = "/foo/bar"; @@ -69,7 +71,8 @@ TEST(parseFlakeRef, GitArchiveInput) { experimentalFeatureSettings.experimentalFeatures.get().insert(Xp::Flakes); - fetchers::Settings fetchSettings; + Settings settings; + fetchers::Settings fetchSettings{settings}; { auto s = "github:foo/bar/branch%23"; // branch name with `#` @@ -112,7 +115,8 @@ class InputFromURLTest : public ::testing::WithParamInterface fun); /** diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 19733fb3ec3..49952a3ce64 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -25,12 +25,17 @@ #include "nix/util/exit.hh" #include "nix/util/strings.hh" +#include "nix/util/config-global.hh" #include "main-config-private.hh" #include "nix/expr/config.hh" namespace nix { +Settings settings; + +static GlobalConfig::Register rSettings(&settings); + char ** savedArgv; static bool gcWarning = true; @@ -304,8 +309,8 @@ void printVersion(const std::string & programName) std::cout << "System type: " << settings.thisSystem << "\n"; std::cout << "Additional system types: " << concatStringsSep(", ", settings.extraPlatforms.get()) << "\n"; std::cout << "Features: " << concatStringsSep(", ", cfg) << "\n"; - std::cout << "System configuration file: " << settings.nixConfDir + "/nix.conf" << "\n"; - std::cout << "User configuration files: " << concatStringsSep(":", settings.nixUserConfFiles) << "\n"; + std::cout << "System configuration file: " << bootstrapSettings.nixConfDir + "/nix.conf" << "\n"; + std::cout << "User configuration files: " << concatStringsSep(":", bootstrapSettings.nixUserConfFiles) << "\n"; std::cout << "Store directory: " << settings.nixStore << "\n"; std::cout << "State directory: " << settings.nixStateDir << "\n"; std::cout << "Data directory: " << settings.nixDataDir << "\n"; diff --git a/src/libstore-c/nix_api_store.cc b/src/libstore-c/nix_api_store.cc index 4f71d0a3cae..dfba89c6281 100644 --- a/src/libstore-c/nix_api_store.cc +++ b/src/libstore-c/nix_api_store.cc @@ -17,6 +17,9 @@ extern "C" { +// FIXME: This is going to conflict with the one in libmain. +nix::Settings cStoreSettings; + nix_err nix_libstore_init(nix_c_context * context) { if (context) @@ -45,16 +48,16 @@ Store * nix_store_open(nix_c_context * context, const char * uri, const char *** std::string uri_str = uri ? uri : ""; if (uri_str.empty()) - return new Store{nix::openStore()}; + return new Store{nix::openStore(cStoreSettings)}; if (!params) - return new Store{nix::openStore(uri_str)}; + return new Store{nix::openStore(cStoreSettings, uri_str)}; nix::Store::Config::Params params_map; for (size_t i = 0; params[i] != nullptr; i++) { params_map[params[i][0]] = params[i][1]; } - return new Store{nix::openStore(uri_str, params_map)}; + return new Store{nix::openStore(cStoreSettings, uri_str, params_map)}; } NIXC_CATCH_ERRS_NULL } diff --git a/src/libstore-c/nix_api_store_internal.h b/src/libstore-c/nix_api_store_internal.h index 712d96488a5..d211b983994 100644 --- a/src/libstore-c/nix_api_store_internal.h +++ b/src/libstore-c/nix_api_store_internal.h @@ -5,6 +5,8 @@ extern "C" { +extern nix::Settings cStoreSettings; + struct Store { nix::ref ptr; diff --git a/src/libstore-test-support/include/nix/store/tests/libstore.hh b/src/libstore-test-support/include/nix/store/tests/libstore.hh index d79b5531232..65260f6cab0 100644 --- a/src/libstore-test-support/include/nix/store/tests/libstore.hh +++ b/src/libstore-test-support/include/nix/store/tests/libstore.hh @@ -7,6 +7,7 @@ #include "nix/store/store-api.hh" #include "nix/store/store-open.hh" #include "nix/store/globals.hh" +#include "nix/store/tests/test-main.hh" namespace nix { @@ -18,14 +19,16 @@ public: initLibStore(false); } + Settings settings = getTestSettings(); + protected: - LibStoreTest(ref store) - : store(std::move(store)) + LibStoreTest(auto && makeStore) + : store(makeStore(settings)) { } LibStoreTest() - : LibStoreTest(openStore("dummy://")) + : LibStoreTest([](auto & settings) { return openStore(settings, "dummy://"); }) { } diff --git a/src/libstore-test-support/include/nix/store/tests/test-main.hh b/src/libstore-test-support/include/nix/store/tests/test-main.hh index 3a1897469de..3f6eb9fcfe6 100644 --- a/src/libstore-test-support/include/nix/store/tests/test-main.hh +++ b/src/libstore-test-support/include/nix/store/tests/test-main.hh @@ -4,6 +4,13 @@ namespace nix { +class Settings; + +/** + * Get a Settings object configured appropriately for unit testing. + */ +Settings getTestSettings(); + /** * Call this for a GTest test suite that will including performing Nix * builds, before running tests. diff --git a/src/libstore-test-support/test-main.cc b/src/libstore-test-support/test-main.cc index 0b9072dc08f..59784640dd6 100644 --- a/src/libstore-test-support/test-main.cc +++ b/src/libstore-test-support/test-main.cc @@ -7,14 +7,11 @@ namespace nix { -int testMainForBuidingPre(int argc, char ** argv) +Settings getTestSettings() { - if (argc > 1 && std::string_view(argv[1]) == "__build-remote") { - printError("test-build-remote: not supported in libexpr unit tests"); - return EXIT_FAILURE; - } + Settings settings; - // Disable build hook. We won't be testing remote builds in these unit tests. If we do, fix the above build hook. + // Disable build hook. We won't be testing remote builds in these unit tests. settings.buildHook = {}; // No substituters, unless a test specifically requests. @@ -41,6 +38,16 @@ int testMainForBuidingPre(int argc, char ** argv) setEnv("_NIX_TEST_NO_SANDBOX", "1"); #endif + return settings; +} + +int testMainForBuidingPre(int argc, char ** argv) +{ + if (argc > 1 && std::string_view(argv[1]) == "__build-remote") { + printError("test-build-remote: not supported in libexpr unit tests"); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; } diff --git a/src/libstore-tests/derivation-advanced-attrs.cc b/src/libstore-tests/derivation-advanced-attrs.cc index 764f16014f5..8ce555e0fb8 100644 --- a/src/libstore-tests/derivation-advanced-attrs.cc +++ b/src/libstore-tests/derivation-advanced-attrs.cc @@ -196,7 +196,7 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_defaults) EXPECT_EQ(options.canBuildLocally(*this->store, got), false); EXPECT_EQ(options.willBuildLocally(*this->store, got), false); - EXPECT_EQ(options.substitutesAllowed(), true); + EXPECT_EQ(options.substitutesAllowed(this->settings), true); EXPECT_EQ(options.useUidRange(got), false); }); }; @@ -244,7 +244,7 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes) EXPECT_EQ(options, expected); - EXPECT_EQ(options.substitutesAllowed(), false); + EXPECT_EQ(options.substitutesAllowed(this->settings), false); EXPECT_EQ(options.useUidRange(got), true); }); }; @@ -338,7 +338,7 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs_d EXPECT_EQ(options.canBuildLocally(*this->store, got), false); EXPECT_EQ(options.willBuildLocally(*this->store, got), false); - EXPECT_EQ(options.substitutesAllowed(), true); + EXPECT_EQ(options.substitutesAllowed(this->settings), true); EXPECT_EQ(options.useUidRange(got), false); }); }; @@ -405,7 +405,7 @@ TYPED_TEST(DerivationAdvancedAttrsBothTest, advancedAttributes_structuredAttrs) EXPECT_EQ(options.canBuildLocally(*this->store, got), false); EXPECT_EQ(options.willBuildLocally(*this->store, got), false); - EXPECT_EQ(options.substitutesAllowed(), false); + EXPECT_EQ(options.substitutesAllowed(this->settings), false); EXPECT_EQ(options.useUidRange(got), true); }); }; diff --git a/src/libstore-tests/derivation/invariants.cc b/src/libstore-tests/derivation/invariants.cc index 6d7cee968d1..2891deacb47 100644 --- a/src/libstore-tests/derivation/invariants.cc +++ b/src/libstore-tests/derivation/invariants.cc @@ -16,11 +16,11 @@ class FillInOutputPathsTest : public LibStoreTest, public JsonCharacterizationTe protected: FillInOutputPathsTest() - : LibStoreTest([]() { - auto config = make_ref(DummyStoreConfig::Params{}); + : LibStoreTest([](auto & settings) { + auto config = make_ref(settings, DummyStoreConfig::Params{}); config->readOnly = false; return config->openDummyStore(); - }()) + }) { } diff --git a/src/libstore-tests/dummy-store.cc b/src/libstore-tests/dummy-store.cc index 4a12dcf78c0..773f5a62387 100644 --- a/src/libstore-tests/dummy-store.cc +++ b/src/libstore-tests/dummy-store.cc @@ -7,6 +7,7 @@ #include "nix/store/realisation.hh" #include "nix/util/tests/json-characterization.hh" +#include "nix/store/tests/test-main.hh" namespace nix { @@ -31,8 +32,10 @@ TEST(DummyStore, realisation_read) { initLibStore(/*loadConfig=*/false); - auto store = [] { - auto cfg = make_ref(StoreReference::Params{}); + auto settings = getTestSettings(); + + auto store = [&] { + auto cfg = make_ref(settings, StoreReference::Params{}); cfg->readOnly = false; return cfg->openDummyStore(); }(); @@ -73,9 +76,10 @@ TEST_P(DummyStoreJsonTest, from_json) using namespace nlohmann; /* Cannot use `readJsonTest` because need to dereference the stores for equality. */ + auto settings = getTestSettings(); readTest(Path{name} + ".json", [&](const auto & encodedRaw) { auto encoded = json::parse(encodedRaw); - ref decoded = adl_serializer>::from_json(encoded); + ref decoded = adl_serializer>::from_json(settings, encoded); ASSERT_EQ(*decoded, *expected); }); } @@ -88,12 +92,13 @@ TEST_P(DummyStoreJsonTest, to_json) INSTANTIATE_TEST_SUITE_P(DummyStoreJSON, DummyStoreJsonTest, [] { initLibStore(false); - auto writeCfg = make_ref(DummyStore::Config::Params{}); + auto settings = getTestSettings(); + auto writeCfg = make_ref(settings, DummyStore::Config::Params{}); writeCfg->readOnly = false; return ::testing::Values( std::pair{ "empty", - make_ref(DummyStore::Config::Params{})->openDummyStore(), + make_ref(settings, DummyStore::Config::Params{})->openDummyStore(), }, std::pair{ "one-flat-file", diff --git a/src/libstore-tests/http-binary-cache-store.cc b/src/libstore-tests/http-binary-cache-store.cc index 4b3754a1fe4..66798cf6aef 100644 --- a/src/libstore-tests/http-binary-cache-store.cc +++ b/src/libstore-tests/http-binary-cache-store.cc @@ -1,35 +1,41 @@ #include +#include "nix/store/globals.hh" #include "nix/store/http-binary-cache-store.hh" +#include "nix/store/tests/test-main.hh" namespace nix { TEST(HttpBinaryCacheStore, constructConfig) { - HttpBinaryCacheStoreConfig config{"http", "foo.bar.baz", {}}; + auto settings = getTestSettings(); + HttpBinaryCacheStoreConfig config{settings, "http", "foo.bar.baz", {}}; EXPECT_EQ(config.cacheUri.to_string(), "http://foo.bar.baz"); } TEST(HttpBinaryCacheStore, constructConfigNoTrailingSlash) { - HttpBinaryCacheStoreConfig config{"https", "foo.bar.baz/a/b/", {}}; + auto settings = getTestSettings(); + HttpBinaryCacheStoreConfig config{settings, "https", "foo.bar.baz/a/b/", {}}; EXPECT_EQ(config.cacheUri.to_string(), "https://foo.bar.baz/a/b"); } TEST(HttpBinaryCacheStore, constructConfigWithParams) { + auto settings = getTestSettings(); StoreConfig::Params params{{"compression", "xz"}}; - HttpBinaryCacheStoreConfig config{"https", "foo.bar.baz/a/b/", params}; + HttpBinaryCacheStoreConfig config{settings, "https", "foo.bar.baz/a/b/", params}; EXPECT_EQ(config.cacheUri.to_string(), "https://foo.bar.baz/a/b"); EXPECT_EQ(config.getReference().params, params); } TEST(HttpBinaryCacheStore, constructConfigWithParamsAndUrlWithParams) { + auto settings = getTestSettings(); StoreConfig::Params params{{"compression", "xz"}}; - HttpBinaryCacheStoreConfig config{"https", "foo.bar.baz/a/b?some-param=some-value", params}; + HttpBinaryCacheStoreConfig config{settings, "https", "foo.bar.baz/a/b?some-param=some-value", params}; EXPECT_EQ(config.cacheUri.to_string(), "https://foo.bar.baz/a/b?some-param=some-value"); EXPECT_EQ(config.getReference().params, params); } diff --git a/src/libstore-tests/legacy-ssh-store.cc b/src/libstore-tests/legacy-ssh-store.cc index d60ecc424c5..b92e99df129 100644 --- a/src/libstore-tests/legacy-ssh-store.cc +++ b/src/libstore-tests/legacy-ssh-store.cc @@ -1,12 +1,16 @@ #include +#include "nix/store/globals.hh" #include "nix/store/legacy-ssh-store.hh" +#include "nix/store/tests/test-main.hh" namespace nix { TEST(LegacySSHStore, constructConfig) { + auto settings = getTestSettings(); LegacySSHStoreConfig config( + settings, "ssh", "me@localhost:2222", StoreConfig::Params{ diff --git a/src/libstore-tests/local-binary-cache-store.cc b/src/libstore-tests/local-binary-cache-store.cc index 01f514e89aa..d771cd70ac8 100644 --- a/src/libstore-tests/local-binary-cache-store.cc +++ b/src/libstore-tests/local-binary-cache-store.cc @@ -1,12 +1,14 @@ #include +#include "nix/store/globals.hh" #include "nix/store/local-binary-cache-store.hh" namespace nix { TEST(LocalBinaryCacheStore, constructConfig) { - LocalBinaryCacheStoreConfig config{"local", "/foo/bar/baz", {}}; + Settings settings; + LocalBinaryCacheStoreConfig config{settings, "local", "/foo/bar/baz", {}}; EXPECT_EQ(config.binaryCacheDir, "/foo/bar/baz"); } diff --git a/src/libstore-tests/local-overlay-store.cc b/src/libstore-tests/local-overlay-store.cc index 175e5d0f44e..9bdbbe72360 100644 --- a/src/libstore-tests/local-overlay-store.cc +++ b/src/libstore-tests/local-overlay-store.cc @@ -1,12 +1,16 @@ #include +#include "nix/store/globals.hh" #include "nix/store/local-overlay-store.hh" +#include "nix/store/tests/test-main.hh" namespace nix { TEST(LocalOverlayStore, constructConfig_rootQueryParam) { + auto settings = getTestSettings(); LocalOverlayStoreConfig config{ + settings, "local-overlay", "", { @@ -22,7 +26,8 @@ TEST(LocalOverlayStore, constructConfig_rootQueryParam) TEST(LocalOverlayStore, constructConfig_rootPath) { - LocalOverlayStoreConfig config{"local-overlay", "/foo/bar", {}}; + auto settings = getTestSettings(); + LocalOverlayStoreConfig config{settings, "local-overlay", "/foo/bar", {}}; EXPECT_EQ(config.rootDir.get(), std::optional{"/foo/bar"}); } diff --git a/src/libstore-tests/local-store.cc b/src/libstore-tests/local-store.cc index d008888974b..40d76223168 100644 --- a/src/libstore-tests/local-store.cc +++ b/src/libstore-tests/local-store.cc @@ -1,18 +1,16 @@ #include +#include "nix/store/globals.hh" #include "nix/store/local-store.hh" - -// Needed for template specialisations. This is not good! When we -// overhaul how store configs work, this should be fixed. -#include "nix/util/args.hh" -#include "nix/util/config-impl.hh" -#include "nix/util/abstract-setting-to-json.hh" +#include "nix/store/tests/test-main.hh" namespace nix { TEST(LocalStore, constructConfig_rootQueryParam) { + auto settings = getTestSettings(); LocalStoreConfig config{ + settings, "local", "", { @@ -28,14 +26,16 @@ TEST(LocalStore, constructConfig_rootQueryParam) TEST(LocalStore, constructConfig_rootPath) { - LocalStoreConfig config{"local", "/foo/bar", {}}; + auto settings = getTestSettings(); + LocalStoreConfig config{settings, "local", "/foo/bar", {}}; EXPECT_EQ(config.rootDir.get(), std::optional{"/foo/bar"}); } TEST(LocalStore, constructConfig_to_string) { - LocalStoreConfig config{"local", "", {}}; + auto settings = getTestSettings(); + LocalStoreConfig config{settings, "local", "", {}}; EXPECT_EQ(config.getReference().to_string(), "local"); } diff --git a/src/libstore-tests/nar-info-disk-cache.cc b/src/libstore-tests/nar-info-disk-cache.cc index 98a94b91e8f..40640eda6a8 100644 --- a/src/libstore-tests/nar-info-disk-cache.cc +++ b/src/libstore-tests/nar-info-disk-cache.cc @@ -1,10 +1,11 @@ -#include "nix/store/nar-info-disk-cache.hh" - #include #include -#include "nix/store/sqlite.hh" #include +#include "nix/store/globals.hh" +#include "nix/store/sqlite.hh" +#include "nix/store/nar-info-disk-cache.hh" + namespace nix { TEST(NarInfoDiskCacheImpl, create_and_read) @@ -23,8 +24,10 @@ TEST(NarInfoDiskCacheImpl, create_and_read) SQLite db; SQLiteStmt getIds; + Settings settings; + { - auto cache = getTestNarInfoDiskCache(dbPath); + auto cache = getTestNarInfoDiskCache(settings, dbPath); // Set up "background noise" and check that different caches receive different ids { @@ -48,7 +51,7 @@ TEST(NarInfoDiskCacheImpl, create_and_read) // We're going to pay special attention to the id field because we had a bug // that changed it. - db = SQLite(dbPath); + db = SQLite(dbPath, {.useWAL = settings.useSQLiteWAL}); getIds.create(db, "select id from BinaryCaches where url = 'http://foo'"); { @@ -73,7 +76,7 @@ TEST(NarInfoDiskCacheImpl, create_and_read) { // We can't clear the in-memory cache, so we use a new cache object. This is // more realistic anyway. - auto cache2 = getTestNarInfoDiskCache(dbPath); + auto cache2 = getTestNarInfoDiskCache(settings, dbPath); { auto r = cache2->upToDateCacheExists("http://foo"); diff --git a/src/libstore-tests/nix_api_store.cc b/src/libstore-tests/nix_api_store.cc index a7fa4d8d899..ce36c51568c 100644 --- a/src/libstore-tests/nix_api_store.cc +++ b/src/libstore-tests/nix_api_store.cc @@ -297,7 +297,7 @@ class NixApiStoreTestWithRealisedPath : public nix_api_store_test_base nix_api_store_test_base::SetUp(); nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations"); - nix::settings.substituters = {}; + cStoreSettings.substituters = {}; store = open_local_store(); @@ -307,7 +307,7 @@ class NixApiStoreTestWithRealisedPath : public nix_api_store_test_base buffer << t.rdbuf(); // Replace the hardcoded system with the current system - std::string jsonStr = nix::replaceStrings(buffer.str(), "x86_64-linux", nix::settings.thisSystem.get()); + std::string jsonStr = nix::replaceStrings(buffer.str(), "x86_64-linux", cStoreSettings.thisSystem.get()); drv = nix_derivation_from_json(ctx, store, jsonStr.c_str()); assert_ctx_ok(); @@ -352,7 +352,7 @@ TEST_F(nix_api_store_test_base, build_from_json) { // FIXME get rid of these nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations"); - nix::settings.substituters = {}; + cStoreSettings.substituters = {}; auto * store = open_local_store(); @@ -363,7 +363,7 @@ TEST_F(nix_api_store_test_base, build_from_json) buffer << t.rdbuf(); // Replace the hardcoded system with the current system - std::string jsonStr = nix::replaceStrings(buffer.str(), "x86_64-linux", nix::settings.thisSystem.get()); + std::string jsonStr = nix::replaceStrings(buffer.str(), "x86_64-linux", cStoreSettings.thisSystem.get()); auto * drv = nix_derivation_from_json(ctx, store, jsonStr.c_str()); assert_ctx_ok(); @@ -399,7 +399,7 @@ TEST_F(nix_api_store_test_base, nix_store_realise_invalid_system) { // Test that nix_store_realise properly reports errors when the system is invalid nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations"); - nix::settings.substituters = {}; + cStoreSettings.substituters = {}; auto * store = open_local_store(); @@ -444,7 +444,7 @@ TEST_F(nix_api_store_test_base, nix_store_realise_builder_fails) { // Test that nix_store_realise properly reports errors when the builder fails nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations"); - nix::settings.substituters = {}; + cStoreSettings.substituters = {}; auto * store = open_local_store(); @@ -454,7 +454,7 @@ TEST_F(nix_api_store_test_base, nix_store_realise_builder_fails) buffer << t.rdbuf(); // Replace with current system and make builder command fail - std::string jsonStr = nix::replaceStrings(buffer.str(), "x86_64-linux", nix::settings.thisSystem.get()); + std::string jsonStr = nix::replaceStrings(buffer.str(), "x86_64-linux", cStoreSettings.thisSystem.get()); jsonStr = nix::replaceStrings(jsonStr, "echo $name foo > $out", "exit 1"); auto * drv = nix_derivation_from_json(ctx, store, jsonStr.c_str()); @@ -489,7 +489,7 @@ TEST_F(nix_api_store_test_base, nix_store_realise_builder_no_output) { // Test that nix_store_realise properly reports errors when builder succeeds but produces no output nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations"); - nix::settings.substituters = {}; + cStoreSettings.substituters = {}; auto * store = open_local_store(); @@ -499,7 +499,7 @@ TEST_F(nix_api_store_test_base, nix_store_realise_builder_no_output) buffer << t.rdbuf(); // Replace with current system and make builder succeed but not produce output - std::string jsonStr = nix::replaceStrings(buffer.str(), "x86_64-linux", nix::settings.thisSystem.get()); + std::string jsonStr = nix::replaceStrings(buffer.str(), "x86_64-linux", cStoreSettings.thisSystem.get()); jsonStr = nix::replaceStrings(jsonStr, "echo $name foo > $out", "true"); auto * drv = nix_derivation_from_json(ctx, store, jsonStr.c_str()); @@ -685,7 +685,7 @@ TEST_F(NixApiStoreTestWithRealisedPath, nix_store_realise_output_ordering) // This test uses a CA derivation with 10 outputs in randomized input order // to verify that the callback order is deterministic and alphabetical. nix::experimentalFeatureSettings.set("extra-experimental-features", "ca-derivations"); - nix::settings.substituters = {}; + cStoreSettings.substituters = {}; auto * store = open_local_store(); @@ -704,14 +704,14 @@ TEST_F(NixApiStoreTestWithRealisedPath, nix_store_realise_output_ordering) std::string drvJson = R"({ "version": 4, "name": "multi-output-test", - "system": ")" + nix::settings.thisSystem.get() + "system": ")" + cStoreSettings.thisSystem.get() + R"(", "builder": "/bin/sh", "args": ["-c", "echo a > $outa; echo b > $outb; echo c > $outc; echo d > $outd; echo e > $oute; echo f > $outf; echo g > $outg; echo h > $outh; echo i > $outi; echo j > $outj"], "env": { "builder": "/bin/sh", "name": "multi-output-test", - "system": ")" + nix::settings.thisSystem.get() + "system": ")" + cStoreSettings.thisSystem.get() + R"(", "outf": ")" + outf_ph + R"(", diff --git a/src/libstore-tests/s3-binary-cache-store.cc b/src/libstore-tests/s3-binary-cache-store.cc index 59090a589f0..62629a7fd1d 100644 --- a/src/libstore-tests/s3-binary-cache-store.cc +++ b/src/libstore-tests/s3-binary-cache-store.cc @@ -1,7 +1,9 @@ +#include "nix/store/globals.hh" #include "nix/store/s3-binary-cache-store.hh" #include "nix/store/http-binary-cache-store.hh" #include "nix/store/filetransfer.hh" #include "nix/store/s3-url.hh" +#include "nix/store/tests/test-main.hh" #include @@ -9,7 +11,8 @@ namespace nix { TEST(S3BinaryCacheStore, constructConfig) { - S3BinaryCacheStoreConfig config{"s3", "foobar", {}}; + auto settings = getTestSettings(); + S3BinaryCacheStoreConfig config{settings, "s3", "foobar", {}}; // The bucket name is stored as the host part of the authority in cacheUri EXPECT_EQ( @@ -22,8 +25,9 @@ TEST(S3BinaryCacheStore, constructConfig) TEST(S3BinaryCacheStore, constructConfigWithRegion) { + auto settings = getTestSettings(); Store::Config::Params params{{"region", "eu-west-1"}}; - S3BinaryCacheStoreConfig config{"s3", "my-bucket", params}; + S3BinaryCacheStoreConfig config{settings, "s3", "my-bucket", params}; EXPECT_EQ( config.cacheUri, @@ -37,7 +41,8 @@ TEST(S3BinaryCacheStore, constructConfigWithRegion) TEST(S3BinaryCacheStore, defaultSettings) { - S3BinaryCacheStoreConfig config{"s3", "test-bucket", {}}; + auto settings = getTestSettings(); + S3BinaryCacheStoreConfig config{settings, "s3", "test-bucket", {}}; EXPECT_EQ( config.cacheUri, @@ -58,11 +63,13 @@ TEST(S3BinaryCacheStore, defaultSettings) */ TEST(S3BinaryCacheStore, s3StoreConfigPreservesParameters) { + auto settings = getTestSettings(); + StringMap params; params["region"] = "eu-west-1"; params["endpoint"] = "custom.s3.com"; - S3BinaryCacheStoreConfig config("s3", "test-bucket", params); + S3BinaryCacheStoreConfig config(settings, "s3", "test-bucket", params); // The config should preserve S3-specific parameters EXPECT_EQ( @@ -93,13 +100,15 @@ TEST(S3BinaryCacheStore, s3SchemeRegistration) */ TEST(S3BinaryCacheStore, parameterFiltering) { + auto settings = getTestSettings(); + StringMap params; params["region"] = "eu-west-1"; params["endpoint"] = "minio.local"; params["want-mass-query"] = "true"; // Non-S3 store parameter params["priority"] = "10"; // Non-S3 store parameter - S3BinaryCacheStoreConfig config("s3", "test-bucket", params); + S3BinaryCacheStoreConfig config(settings, "s3", "test-bucket", params); // Only S3-specific params should be in cacheUri.query EXPECT_EQ( @@ -127,16 +136,19 @@ TEST(S3BinaryCacheStore, parameterFiltering) */ TEST(S3BinaryCacheStore, storageClassDefault) { - S3BinaryCacheStoreConfig config{"s3", "test-bucket", {}}; + auto settings = getTestSettings(); + S3BinaryCacheStoreConfig config{settings, "s3", "test-bucket", {}}; EXPECT_EQ(config.storageClass.get(), std::nullopt); } TEST(S3BinaryCacheStore, storageClassConfiguration) { + auto settings = getTestSettings(); + StringMap params; params["storage-class"] = "GLACIER"; - S3BinaryCacheStoreConfig config("s3", "test-bucket", params); + S3BinaryCacheStoreConfig config(settings, "s3", "test-bucket", params); EXPECT_EQ(config.storageClass.get(), std::optional("GLACIER")); } diff --git a/src/libstore-tests/ssh-store.cc b/src/libstore-tests/ssh-store.cc index a156da52b71..c0a32d0a8dc 100644 --- a/src/libstore-tests/ssh-store.cc +++ b/src/libstore-tests/ssh-store.cc @@ -1,14 +1,16 @@ #include +#include "nix/store/globals.hh" #include "nix/store/ssh-store.hh" -#include "nix/util/config-impl.hh" -#include "nix/util/abstract-setting-to-json.hh" +#include "nix/store/tests/test-main.hh" namespace nix { TEST(SSHStore, constructConfig) { + auto settings = getTestSettings(); SSHStoreConfig config{ + settings, "ssh-ng", "me@localhost:2222", StoreConfig::Params{ @@ -34,7 +36,9 @@ TEST(SSHStore, constructConfig) TEST(MountedSSHStore, constructConfig) { + auto settings = getTestSettings(); MountedSSHStoreConfig config{ + settings, "mounted-ssh", "localhost", StoreConfig::Params{ diff --git a/src/libstore-tests/uds-remote-store.cc b/src/libstore-tests/uds-remote-store.cc index 415dfc4ac94..cc8eca25142 100644 --- a/src/libstore-tests/uds-remote-store.cc +++ b/src/libstore-tests/uds-remote-store.cc @@ -1,31 +1,38 @@ #include +#include "nix/store/globals.hh" #include "nix/store/uds-remote-store.hh" namespace nix { TEST(UDSRemoteStore, constructConfig) { - UDSRemoteStoreConfig config{"unix", "/tmp/socket", {}}; + Settings settings; + UDSRemoteStoreConfig config{settings, "unix", "/tmp/socket", {}}; EXPECT_EQ(config.path, "/tmp/socket"); } TEST(UDSRemoteStore, constructConfigWrongScheme) { - EXPECT_THROW(UDSRemoteStoreConfig("http", "/tmp/socket", {}), UsageError); + Settings settings; + EXPECT_THROW(UDSRemoteStoreConfig(settings, "http", "/tmp/socket", {}), UsageError); } TEST(UDSRemoteStore, constructConfig_to_string) { - UDSRemoteStoreConfig config{"unix", "", {}}; + Settings settings; + UDSRemoteStoreConfig config{settings, "unix", "", {}}; EXPECT_EQ(config.getReference().to_string(), "daemon"); } TEST(UDSRemoteStore, constructConfigWithParams) { + Settings settings; + StoreConfig::Params params{{"max-connections", "1"}}; - UDSRemoteStoreConfig config{"unix", "/tmp/socket", params}; + UDSRemoteStoreConfig config{settings, "unix", "/tmp/socket", params}; + auto storeReference = config.getReference(); EXPECT_EQ(storeReference.to_string(), "unix:///tmp/socket?max-connections=1"); EXPECT_EQ(storeReference.render(/*withParams=*/false), "unix:///tmp/socket"); @@ -34,8 +41,11 @@ TEST(UDSRemoteStore, constructConfigWithParams) TEST(UDSRemoteStore, constructConfigWithParamsNoPath) { + Settings settings; + StoreConfig::Params params{{"max-connections", "1"}}; - UDSRemoteStoreConfig config{"unix", "", params}; + UDSRemoteStoreConfig config{settings, "unix", "", params}; + auto storeReference = config.getReference(); EXPECT_EQ(storeReference.to_string(), "daemon?max-connections=1"); EXPECT_EQ(storeReference.render(/*withParams=*/false), "daemon"); diff --git a/src/libstore-tests/write-derivation.cc b/src/libstore-tests/write-derivation.cc index c320f92faf3..04161f15ac8 100644 --- a/src/libstore-tests/write-derivation.cc +++ b/src/libstore-tests/write-derivation.cc @@ -12,19 +12,22 @@ namespace { class WriteDerivationTest : public LibStoreTest { protected: - WriteDerivationTest(ref config_) - : LibStoreTest(config_->openDummyStore()) - , config(std::move(config_)) + WriteDerivationTest(auto && makeConfig) + : LibStoreTest([&](auto & settings) { + this->config = makeConfig(settings); + return config->openDummyStore(); + }) { config->readOnly = false; } WriteDerivationTest() - : WriteDerivationTest(make_ref(DummyStoreConfig::Params{})) + : WriteDerivationTest( + [](auto & settings) { return make_ref(settings, DummyStoreConfig::Params{}); }) { } - ref config; + std::shared_ptr config; }; static Derivation makeSimpleDrv() diff --git a/src/libstore/build/derivation-building-goal.cc b/src/libstore/build/derivation-building-goal.cc index 8221e12c697..ac0cdff1bdc 100644 --- a/src/libstore/build/derivation-building-goal.cc +++ b/src/libstore/build/derivation-building-goal.cc @@ -95,7 +95,11 @@ std::string showKnownOutputs(const StoreDirConfig & store, const Derivation & dr } static void runPostBuildHook( - const StoreDirConfig & store, Logger & logger, const StorePath & drvPath, const StorePathSet & outputPaths); + const Settings & settings, + const StoreDirConfig & store, + Logger & logger, + const StorePath & drvPath, + const StorePathSet & outputPaths); /* At least one of the output paths could not be produced using a substitute. So we have to build instead. */ @@ -119,7 +123,7 @@ Goal::Co DerivationBuildingGoal::gaveUpOnSubstitution(bool storeDerivation) for (auto & i : drv->inputSrcs) { if (worker.store.isValidPath(i)) continue; - if (!settings.useSubstitutes) + if (!worker.store.config.settings.useSubstitutes) throw Error( "dependency '%s' of '%s' does not exist, and substitution is disabled", worker.store.printStorePath(i), @@ -369,7 +373,7 @@ Goal::Co DerivationBuildingGoal::tryToBuild() `preferLocalBuild' set. Also, check and repair modes are only supported for local builds. */ bool buildLocally = (buildMode != bmNormal || drvOptions.willBuildLocally(worker.store, *drv)) - && settings.maxBuildJobs.get() != 0; + && worker.store.config.settings.maxBuildJobs.get() != 0; if (buildLocally) { useHook = false; @@ -401,7 +405,7 @@ Goal::Co DerivationBuildingGoal::tryToBuild() use that. If there is not, then check if we can do a "true" local build. */ - externalBuilder = settings.findExternalDerivationBuilderIfSupported(*drv); + externalBuilder = worker.store.config.settings.findExternalDerivationBuilderIfSupported(*drv); if (!externalBuilder && !drvOptions.canBuildLocally(worker.store, *drv)) { auto msg = @@ -413,12 +417,12 @@ Goal::Co DerivationBuildingGoal::tryToBuild() Magenta(worker.store.printStorePath(drvPath)), Magenta(drv->platform), concatStringsSep(", ", drvOptions.getRequiredSystemFeatures(*drv)), - Magenta(settings.thisSystem), + Magenta(worker.store.config.settings.thisSystem), concatStringsSep(", ", worker.store.Store::config.systemFeatures)); // since aarch64-darwin has Rosetta 2, this user can actually run x86_64-darwin on their hardware - // we should tell them to run the command to install Darwin 2 - if (drv->platform == "x86_64-darwin" && settings.thisSystem == "aarch64-darwin") + if (drv->platform == "x86_64-darwin" && worker.store.config.settings.thisSystem == "aarch64-darwin") msg += fmt( "\nNote: run `%s` to run programs for x86_64-darwin", Magenta( @@ -513,7 +517,7 @@ Goal::Co DerivationBuildingGoal::tryToBuild() StorePathSet outputPaths; for (auto & [_, output] : builtOutputs) outputPaths.insert(output.outPath); - runPostBuildHook(worker.store, *logger, drvPath, outputPaths); + runPostBuildHook(worker.store.config.settings, worker.store, *logger, drvPath, outputPaths); /* It is now safe to delete the lock files, since all future lockers will see that the output paths are valid; they will @@ -548,7 +552,7 @@ Goal::Co DerivationBuildingGoal::tryToBuild() while (true) { unsigned int curBuilds = worker.getNrLocalBuilds(); - if (curBuilds >= settings.maxBuildJobs) { + if (curBuilds >= worker.store.config.settings.maxBuildJobs) { outputLocks.unlock(); co_await waitForBuildSlot(); co_return tryToBuild(); @@ -590,7 +594,8 @@ Goal::Co DerivationBuildingGoal::tryToBuild() auto * localStoreP = dynamic_cast(&worker.store); assert(localStoreP); - decltype(DerivationBuilderParams::defaultPathsInChroot) defaultPathsInChroot = settings.sandboxPaths.get(); + decltype(DerivationBuilderParams::defaultPathsInChroot) defaultPathsInChroot = + worker.store.config.settings.sandboxPaths.get(); DesugaredEnv desugaredEnv; /* Add the closure of store paths to the chroot. */ @@ -618,6 +623,7 @@ Goal::Co DerivationBuildingGoal::tryToBuild() } DerivationBuilderParams params{ + .settings = worker.store.config.settings, .drvPath = drvPath, .buildResult = buildResult, .drv = *drv, @@ -716,7 +722,7 @@ Goal::Co DerivationBuildingGoal::tryToBuild() worker.markContentsGood(output.outPath); outputPaths.insert(output.outPath); } - runPostBuildHook(worker.store, *logger, drvPath, outputPaths); + runPostBuildHook(worker.store.config.settings, worker.store, *logger, drvPath, outputPaths); /* It is now safe to delete the lock files, since all future lockers will see that the output paths are valid; they will @@ -730,7 +736,11 @@ Goal::Co DerivationBuildingGoal::tryToBuild() } static void runPostBuildHook( - const StoreDirConfig & store, Logger & logger, const StorePath & drvPath, const StorePathSet & outputPaths) + const Settings & settings, + const StoreDirConfig & store, + Logger & logger, + const StorePath & drvPath, + const StorePathSet & outputPaths) { auto hook = settings.postBuildHook; if (hook == "") @@ -835,17 +845,19 @@ HookReply DerivationBuildingGoal::tryBuildHook( #else /* This should use `worker.evalStore`, but per #13179 the build hook doesn't work with eval store anyways. */ - if (settings.buildHook.get().empty() || !worker.tryBuildHook || !worker.store.isValidPath(drvPath)) + if (worker.store.config.settings.buildHook.get().empty() || !worker.tryBuildHook + || !worker.store.isValidPath(drvPath)) return rpDecline; if (!worker.hook) - worker.hook = std::make_unique(); + worker.hook = std::make_unique(worker.store.config.settings.buildHook.get()); try { /* Send the request to the hook. */ - worker.hook->sink << "try" << (worker.getNrLocalBuilds() < settings.maxBuildJobs ? 1 : 0) << drv->platform - << worker.store.printStorePath(drvPath) << drvOptions.getRequiredSystemFeatures(*drv); + worker.hook->sink << "try" << (worker.getNrLocalBuilds() < worker.store.config.settings.maxBuildJobs ? 1 : 0) + << drv->platform << worker.store.printStorePath(drvPath) + << drvOptions.getRequiredSystemFeatures(*drv); worker.hook->sink.flush(); /* Read the first line of input, which should be a word indicating @@ -940,7 +952,7 @@ Path DerivationBuildingGoal::openLogFile() { logSize = 0; - if (!settings.keepLog) + if (!worker.store.config.settings.keepLog) return ""; auto baseName = std::string(baseNameOf(worker.store.printStorePath(drvPath))); @@ -950,11 +962,11 @@ Path DerivationBuildingGoal::openLogFile() if (auto localStore = dynamic_cast(&worker.store)) logDir = localStore->config->logDir; else - logDir = settings.nixLogDir; + logDir = worker.store.config.settings.nixLogDir; Path dir = fmt("%s/%s/%s/", logDir, LocalFSStore::drvsLogDir, baseName.substr(0, 2)); createDirs(dir); - Path logFileName = fmt("%s/%s%s", dir, baseName.substr(2), settings.compressLog ? ".bz2" : ""); + Path logFileName = fmt("%s/%s%s", dir, baseName.substr(2), worker.store.config.settings.compressLog ? ".bz2" : ""); fdLogFile = toDescriptor(open( logFileName.c_str(), @@ -969,7 +981,7 @@ Path DerivationBuildingGoal::openLogFile() logFileSink = std::make_shared(fdLogFile.get()); - if (settings.compressLog) + if (worker.store.config.settings.compressLog) logSink = std::shared_ptr(makeCompressionSink("bzip2", *logFileSink)); else logSink = logFileSink; @@ -1003,7 +1015,7 @@ void DerivationBuildingGoal::handleChildOutput(Descriptor fd, std::string_view d auto isWrittenToLog = isReadDesc(fd); if (isWrittenToLog) { logSize += data.size(); - if (settings.maxLogSize && logSize > settings.maxLogSize) { + if (worker.store.config.settings.maxLogSize && logSize > worker.store.config.settings.maxLogSize) { killChild(); // We're not inside a coroutine, hence we can't use co_return here. // Thus we ignore the return value. @@ -1011,7 +1023,7 @@ void DerivationBuildingGoal::handleChildOutput(Descriptor fd, std::string_view d BuildResult::Failure::LogLimitExceeded, "%s killed after writing more than %d bytes of log output", getName(), - settings.maxLogSize)); + worker.store.config.settings.maxLogSize)); return; } @@ -1081,7 +1093,7 @@ void DerivationBuildingGoal::flushLine() else { logTail.push_back(currentLogLine); - if (logTail.size() > settings.logLines) + if (logTail.size() > worker.store.config.settings.logLines) logTail.pop_front(); act->result(resBuildLogLine, currentLogLine); diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc index b36685a242c..cff6f5dc47a 100644 --- a/src/libstore/build/derivation-goal.cc +++ b/src/libstore/build/derivation-goal.cc @@ -99,7 +99,8 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation) /* We are first going to try to create the invalid output paths through substitutes. If that doesn't work, we'll build them. */ - if (settings.useSubstitutes && drvOptions.substitutesAllowed()) { + if (worker.store.config.settings.useSubstitutes + && drvOptions.substitutesAllowed(worker.store.config.settings)) { if (!checkResult) waitees.insert(upcast_goal(worker.makeDrvOutputSubstitutionGoal(DrvOutput{outputHash, wantedOutput}))); else { @@ -117,7 +118,7 @@ Goal::Co DerivationGoal::haveDerivation(bool storeDerivation) assert(!drv->type().isImpure()); - if (nrFailed > 0 && nrFailed > nrNoSubstituters && !settings.tryFallback) { + if (nrFailed > 0 && nrFailed > nrNoSubstituters && !worker.store.config.settings.tryFallback) { co_return doneFailure(BuildError( BuildResult::Failure::TransientFailure, "some substitutes for the outputs of derivation '%s' failed (usually happens due to networking issues); try '--fallback' to build derivation from source ", diff --git a/src/libstore/build/drv-output-substitution-goal.cc b/src/libstore/build/drv-output-substitution-goal.cc index 8d0a307beda..098d89e0e2f 100644 --- a/src/libstore/build/drv-output-substitution-goal.cc +++ b/src/libstore/build/drv-output-substitution-goal.cc @@ -25,7 +25,8 @@ Goal::Co DrvOutputSubstitutionGoal::init() co_return amDone(ecSuccess); } - auto subs = settings.useSubstitutes ? getDefaultSubstituters() : std::list>(); + auto & settings = worker.store.config.settings; + auto subs = settings.useSubstitutes ? getDefaultSubstituters(settings) : std::list>(); bool substituterFailed = false; diff --git a/src/libstore/build/goal.cc b/src/libstore/build/goal.cc index 6266329e7e5..ba834fb6e10 100644 --- a/src/libstore/build/goal.cc +++ b/src/libstore/build/goal.cc @@ -165,7 +165,7 @@ Goal::Done Goal::amDone(ExitCode result, std::optional ex) if (goal->waitees.empty()) { worker.wakeUp(goal); - } else if (result == ecFailed && !settings.keepGoing) { + } else if (result == ecFailed && !worker.store.config.settings.keepGoing) { /* If we failed and keepGoing is not set, we remove all remaining waitees. */ for (auto & g : goal->waitees) { diff --git a/src/libstore/build/substitution-goal.cc b/src/libstore/build/substitution-goal.cc index ac18de304b7..7f4109c584e 100644 --- a/src/libstore/build/substitution-goal.cc +++ b/src/libstore/build/substitution-goal.cc @@ -56,11 +56,13 @@ Goal::Co PathSubstitutionGoal::init() co_return doneSuccess(BuildResult::Success::AlreadyValid); } + auto & settings = worker.store.config.settings; + if (settings.readOnlyMode) throw Error( "cannot substitute path '%s' - no write access to the Nix store", worker.store.printStorePath(storePath)); - auto subs = settings.useSubstitutes ? getDefaultSubstituters() : std::list>(); + auto subs = settings.useSubstitutes ? getDefaultSubstituters(settings) : std::list>(); bool substituterFailed = false; std::optional lastStoresException = std::nullopt; @@ -210,7 +212,8 @@ Goal::Co PathSubstitutionGoal::tryToRun( /* Make sure that we are allowed to start a substitution. Note that even if maxSubstitutionJobs == 0, we still allow a substituter to run. This prevents infinite waiting. */ - while (worker.getNrSubstitutions() >= std::max(1U, (unsigned int) settings.maxSubstitutionJobs)) { + while (worker.getNrSubstitutions() + >= std::max(1U, (unsigned int) worker.store.config.settings.maxSubstitutionJobs)) { co_await waitForBuildSlot(); } diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc index 3663a2c919f..650b9060e05 100644 --- a/src/libstore/build/worker.cc +++ b/src/libstore/build/worker.cc @@ -184,7 +184,7 @@ void Worker::removeGoal(GoalPtr goal) topGoals.erase(goal); /* If a top-level goal failed, then kill all other goals (unless keepGoing was set). */ - if (goal->exitCode == Goal::ecFailed && !settings.keepGoing) + if (goal->exitCode == Goal::ecFailed && !store.config.settings.keepGoing) topGoals.clear(); } @@ -285,8 +285,8 @@ void Worker::waitForBuildSlot(GoalPtr goal) { goal->trace("wait for build slot"); bool isSubstitutionGoal = goal->jobCategory() == JobCategory::Substitution; - if ((!isSubstitutionGoal && getNrLocalBuilds() < settings.maxBuildJobs) - || (isSubstitutionGoal && getNrSubstitutions() < settings.maxSubstitutionJobs)) + if ((!isSubstitutionGoal && getNrLocalBuilds() < store.config.settings.maxBuildJobs) + || (isSubstitutionGoal && getNrSubstitutions() < store.config.settings.maxSubstitutionJobs)) wakeUp(goal); /* we can do it right away */ else addToWeakGoals(wantingToBuild, goal); @@ -358,8 +358,8 @@ void Worker::run(const Goals & _topGoals) /* Wait for input. */ if (!children.empty() || !waitingForAWhile.empty()) waitForInput(); - else if (awake.empty() && 0U == settings.maxBuildJobs) { - if (getMachines().empty()) + else if (awake.empty() && 0U == store.config.settings.maxBuildJobs) { + if (getMachines(store.config.settings).empty()) throw Error( "Unable to start any build; either increase '--max-jobs' or enable remote builds.\n" "\n" @@ -376,9 +376,9 @@ void Worker::run(const Goals & _topGoals) /* If --keep-going is not set, it's possible that the main goal exited while some of its subgoals were still active. But if --keep-going *is* set, then they must all be finished now. */ - assert(!settings.keepGoing || awake.empty()); - assert(!settings.keepGoing || wantingToBuild.empty()); - assert(!settings.keepGoing || children.empty()); + assert(!store.config.settings.keepGoing || awake.empty()); + assert(!store.config.settings.keepGoing || wantingToBuild.empty()); + assert(!store.config.settings.keepGoing || children.empty()); } void Worker::waitForInput() @@ -399,16 +399,16 @@ void Worker::waitForInput() is a build timeout, then wait for input until the first deadline for any child. */ auto nearest = steady_time_point::max(); // nearest deadline - if (settings.minFree.get() != 0) + if (store.config.settings.minFree.get() != 0) // Periodicallty wake up to see if we need to run the garbage collector. nearest = before + std::chrono::seconds(10); for (auto & i : children) { if (!i.respectTimeouts) continue; - if (0 != settings.maxSilentTime) - nearest = std::min(nearest, i.lastOutput + std::chrono::seconds(settings.maxSilentTime)); - if (0 != settings.buildTimeout) - nearest = std::min(nearest, i.timeStarted + std::chrono::seconds(settings.buildTimeout)); + if (0 != store.config.settings.maxSilentTime) + nearest = std::min(nearest, i.lastOutput + std::chrono::seconds(store.config.settings.maxSilentTime)); + if (0 != store.config.settings.buildTimeout) + nearest = std::min(nearest, i.timeStarted + std::chrono::seconds(store.config.settings.buildTimeout)); } if (nearest != steady_time_point::max()) { timeout = std::max(1L, (long) std::chrono::duration_cast(nearest - before).count()); @@ -424,7 +424,7 @@ void Worker::waitForInput() timeout = std::max( 1L, (long) std::chrono::duration_cast( - lastWokenUp + std::chrono::seconds(settings.pollInterval) - before) + lastWokenUp + std::chrono::seconds(store.config.settings.pollInterval) - before) .count()); } else lastWokenUp = steady_time_point::min(); @@ -477,20 +477,21 @@ void Worker::waitForInput() goal->handleEOF(k); }); - if (goal->exitCode == Goal::ecBusy && 0 != settings.maxSilentTime && j->respectTimeouts - && after - j->lastOutput >= std::chrono::seconds(settings.maxSilentTime)) { - goal->timedOut( - Error("%1% timed out after %2% seconds of silence", goal->getName(), settings.maxSilentTime)); + if (goal->exitCode == Goal::ecBusy && 0 != store.config.settings.maxSilentTime && j->respectTimeouts + && after - j->lastOutput >= std::chrono::seconds(store.config.settings.maxSilentTime)) { + goal->timedOut(Error( + "%1% timed out after %2% seconds of silence", goal->getName(), store.config.settings.maxSilentTime)); } else if ( - goal->exitCode == Goal::ecBusy && 0 != settings.buildTimeout && j->respectTimeouts - && after - j->timeStarted >= std::chrono::seconds(settings.buildTimeout)) { - goal->timedOut(Error("%1% timed out after %2% seconds", goal->getName(), settings.buildTimeout)); + goal->exitCode == Goal::ecBusy && 0 != store.config.settings.buildTimeout && j->respectTimeouts + && after - j->timeStarted >= std::chrono::seconds(store.config.settings.buildTimeout)) { + goal->timedOut( + Error("%1% timed out after %2% seconds", goal->getName(), store.config.settings.buildTimeout)); } } - if (!waitingForAWhile.empty() && lastWokenUp + std::chrono::seconds(settings.pollInterval) <= after) { + if (!waitingForAWhile.empty() && lastWokenUp + std::chrono::seconds(store.config.settings.pollInterval) <= after) { lastWokenUp = after; for (auto & i : waitingForAWhile) { GoalPtr goal = i.lock(); diff --git a/src/libstore/builtins/fetchurl.cc b/src/libstore/builtins/fetchurl.cc index 126fb922eba..9448d558509 100644 --- a/src/libstore/builtins/fetchurl.cc +++ b/src/libstore/builtins/fetchurl.cc @@ -13,12 +13,12 @@ static void builtinFetchurl(const BuiltinBuilderContext & ctx) this to be stored in a file. It would be nice if we could just pass a pointer to the data. */ if (ctx.netrcData != "") { - settings.netrcFile = "netrc"; - writeFile(settings.netrcFile, ctx.netrcData, 0600); + fileTransferSettings.netrcFile = "netrc"; + writeFile(fileTransferSettings.netrcFile, ctx.netrcData, 0600); } - settings.caFile = "ca-certificates.crt"; - writeFile(settings.caFile, ctx.caFileData, 0600); + fileTransferSettings.caFile = "ca-certificates.crt"; + writeFile(fileTransferSettings.caFile, ctx.caFileData, 0600); auto out = get(ctx.drv.outputs, "out"); if (!out) @@ -73,7 +73,7 @@ static void builtinFetchurl(const BuiltinBuilderContext & ctx) /* Try the hashed mirrors first. */ auto dof = std::get_if(&out->raw); if (dof && dof->ca.method.getFileIngestionMethod() == FileIngestionMethod::Flat) - for (auto hashedMirror : settings.hashedMirrors.get()) + for (auto hashedMirror : ctx.hashedMirrors) try { if (!hasSuffix(hashedMirror, "/")) hashedMirror += '/'; diff --git a/src/libstore/common-ssh-store-config.cc b/src/libstore/common-ssh-store-config.cc index 12f187b4c9e..5eec1e5fa01 100644 --- a/src/libstore/common-ssh-store-config.cc +++ b/src/libstore/common-ssh-store-config.cc @@ -5,14 +5,15 @@ namespace nix { -CommonSSHStoreConfig::CommonSSHStoreConfig(std::string_view scheme, std::string_view authority, const Params & params) - : CommonSSHStoreConfig(scheme, ParsedURL::Authority::parse(authority), params) +CommonSSHStoreConfig::CommonSSHStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params) + : CommonSSHStoreConfig(settings, scheme, ParsedURL::Authority::parse(authority), params) { } CommonSSHStoreConfig::CommonSSHStoreConfig( - std::string_view scheme, const ParsedURL::Authority & authority, const Params & params) - : StoreConfig(params) + nix::Settings & settings, std::string_view scheme, const ParsedURL::Authority & authority, const Params & params) + : StoreConfig(settings, params) , authority(authority) { } diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 2a382dca7c0..8ebc272cbf8 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -229,7 +229,7 @@ struct ClientSettings bool useSubstitutes; StringMap overrides; - void apply(TrustedFlag trusted) + void apply(Settings & settings, TrustedFlag trusted) { settings.keepFailed = keepFailed; settings.keepGoing = keepGoing; @@ -794,7 +794,7 @@ static void performOp( // FIXME: use some setting in recursive mode. Will need to use // non-global variables. if (!recursive) - clientSettings.apply(trusted); + clientSettings.apply(store->config.settings, trusted); logger->stopWork(); break; diff --git a/src/libstore/derivation-options.cc b/src/libstore/derivation-options.cc index 2ead0c444c9..e7080aa0107 100644 --- a/src/libstore/derivation-options.cc +++ b/src/libstore/derivation-options.cc @@ -396,11 +396,11 @@ StringSet DerivationOptions::getRequiredSystemFeatures(const BasicDerivat template bool DerivationOptions::canBuildLocally(Store & localStore, const BasicDerivation & drv) const { - if (drv.platform != settings.thisSystem.get() && !settings.extraPlatforms.get().count(drv.platform) - && !drv.isBuiltin()) + if (drv.platform != localStore.config.settings.thisSystem.get() + && !localStore.config.settings.extraPlatforms.get().count(drv.platform) && !drv.isBuiltin()) return false; - if (settings.maxBuildJobs.get() == 0 && !drv.isBuiltin()) + if (localStore.config.settings.maxBuildJobs.get() == 0 && !drv.isBuiltin()) return false; for (auto & feature : getRequiredSystemFeatures(drv)) @@ -417,7 +417,7 @@ bool DerivationOptions::willBuildLocally(Store & localStore, const BasicD } template -bool DerivationOptions::substitutesAllowed() const +bool DerivationOptions::substitutesAllowed(const Settings & settings) const { return settings.alwaysAllowSubstitutes ? true : allowSubstitutes; } diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 842ef9056ee..95b58b0c43a 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -128,7 +128,7 @@ static auto infoForDerivation(Store & store, const Derivation & drv) StorePath writeDerivation(Store & store, const Derivation & drv, RepairFlag repair, bool readOnly) { - if (readOnly || settings.readOnlyMode) { + if (readOnly || store.config.settings.readOnlyMode) { auto [_x, _y, _z, path] = infoForDerivation(store, drv); return path; } else diff --git a/src/libstore/dummy-store.cc b/src/libstore/dummy-store.cc index aa763a679e4..a82d4fba208 100644 --- a/src/libstore/dummy-store.cc +++ b/src/libstore/dummy-store.cc @@ -409,10 +409,10 @@ void adl_serializer::to_json(json & json, const }; } -ref adl_serializer>::from_json(const json & json) +ref adl_serializer>::from_json(Settings & settings, const json & json) { auto & obj = getObject(json); - auto cfg = make_ref(DummyStore::Config::Params{}); + auto cfg = make_ref(settings, DummyStore::Config::Params{}); const_cast(cfg->storeDir_).set(getString(valueAt(obj, "store"))); cfg->readOnly = true; return cfg; @@ -425,10 +425,10 @@ void adl_serializer::to_json(json & json, const DummyStoreConf }; } -ref adl_serializer>::from_json(const json & json) +ref adl_serializer>::from_json(Settings & settings, const json & json) { auto & obj = getObject(json); - ref res = adl_serializer>::from_json(valueAt(obj, "config"))->openDummyStore(); + ref res = adl_serializer>::from_json(settings, valueAt(obj, "config"))->openDummyStore(); for (auto & [k, v] : getObject(valueAt(obj, "contents"))) res->contents.insert({StorePath{k}, v}); for (auto & [k, v] : getObject(valueAt(obj, "derivations"))) diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index 57caec38430..b06f345309e 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -37,6 +37,22 @@ namespace nix { const unsigned int RETRY_TIME_MS_DEFAULT = 250; const unsigned int RETRY_TIME_MS_TOO_MANY_REQUESTS = 60000; +Path FileTransferSettings::getDefaultSSLCertFile() +{ + for (auto & fn : + {"/etc/ssl/certs/ca-certificates.crt", "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"}) + if (pathAccessible(fn)) + return fn; + return ""; +} + +FileTransferSettings::FileTransferSettings() +{ + auto sslOverride = getEnv("NIX_SSL_CERT_FILE").value_or(getEnv("SSL_CERT_FILE").value_or("")); + if (sslOverride != "") + caFile = sslOverride; +} + FileTransferSettings fileTransferSettings; static GlobalConfig::Register rFileTransferSettings(&fileTransferSettings); @@ -430,8 +446,9 @@ struct curlFileTransfer : public FileTransfer curl_easy_setopt(req, CURLOPT_HTTPHEADER, requestHeaders); - if (settings.downloadSpeed.get() > 0) - curl_easy_setopt(req, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) (settings.downloadSpeed.get() * 1024)); + if (fileTransferSettings.downloadSpeed.get() > 0) + curl_easy_setopt( + req, CURLOPT_MAX_RECV_SPEED_LARGE, (curl_off_t) (fileTransferSettings.downloadSpeed.get() * 1024)); if (request.method == HttpMethod::Head) curl_easy_setopt(req, CURLOPT_NOBODY, 1); @@ -455,8 +472,8 @@ struct curlFileTransfer : public FileTransfer curl_easy_setopt(req, CURLOPT_SEEKDATA, this); } - if (settings.caFile != "") - curl_easy_setopt(req, CURLOPT_CAINFO, settings.caFile.get().c_str()); + if (fileTransferSettings.caFile != "") + curl_easy_setopt(req, CURLOPT_CAINFO, fileTransferSettings.caFile.get().c_str()); #if !defined(_WIN32) && LIBCURL_VERSION_NUM >= 0x071000 curl_easy_setopt(req, CURLOPT_SOCKOPTFUNCTION, cloexec_callback); @@ -469,7 +486,7 @@ struct curlFileTransfer : public FileTransfer /* If no file exist in the specified path, curl continues to work anyway as if netrc support was disabled. */ - curl_easy_setopt(req, CURLOPT_NETRC_FILE, settings.netrcFile.get().c_str()); + curl_easy_setopt(req, CURLOPT_NETRC_FILE, fileTransferSettings.netrcFile.get().c_str()); curl_easy_setopt(req, CURLOPT_NETRC, CURL_NETRC_OPTIONAL); if (writtenToSink) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 4846d445fe1..d3c87f632c3 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -463,6 +463,8 @@ struct GCLimitReached void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) { + const auto & settings = config->settings; + bool shouldDelete = options.action == GCOptions::gcDeleteDead || options.action == GCOptions::gcDeleteSpecific; bool gcKeepOutputs = settings.gcKeepOutputs; bool gcKeepDerivations = settings.gcKeepDerivations; @@ -917,6 +919,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) void LocalStore::autoGC(bool sync) { #if HAVE_STATVFS + const auto & settings = config->settings; static auto fakeFreeSpaceFile = getEnv("_NIX_TEST_FREE_SPACE_FILE"); auto getAvail = [this]() -> uint64_t { @@ -961,7 +964,7 @@ void LocalStore::autoGC(bool sync) std::promise promise; future = state->gcFuture = promise.get_future().share(); - std::thread([promise{std::move(promise)}, this, avail, getAvail]() mutable { + std::thread([promise{std::move(promise)}, this, avail, getAvail, &settings]() mutable { try { /* Wake up any threads waiting for the auto-GC to finish. */ diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index 8c542b686c2..3eb0c213121 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -6,6 +6,7 @@ #include "nix/util/abstract-setting-to-json.hh" #include "nix/util/compute-levels.hh" #include "nix/util/signals.hh" +#include "nix/store/filetransfer.hh" #include #include @@ -46,10 +47,6 @@ namespace nix { must be deleted and recreated on startup.) */ #define DEFAULT_SOCKET_PATH "/daemon-socket/socket" -Settings settings; - -static GlobalConfig::Register rSettings(&settings); - Settings::Settings() : nixPrefix(NIX_PREFIX) , nixStore( @@ -62,8 +59,6 @@ Settings::Settings() , nixDataDir(canonPath(getEnvNonEmpty("NIX_DATA_DIR").value_or(NIX_DATA_DIR))) , nixLogDir(canonPath(getEnvNonEmpty("NIX_LOG_DIR").value_or(NIX_LOG_DIR))) , nixStateDir(canonPath(getEnvNonEmpty("NIX_STATE_DIR").value_or(NIX_STATE_DIR))) - , nixConfDir(canonPath(getEnvNonEmpty("NIX_CONF_DIR").value_or(NIX_CONF_DIR))) - , nixUserConfFiles(getUserConfigFiles()) , nixDaemonSocketFile( canonPath(getEnvNonEmpty("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH))) { @@ -72,10 +67,6 @@ Settings::Settings() #endif allowSymlinkedStore = getEnv("NIX_IGNORE_SYMLINK_STORE") == "1"; - auto sslOverride = getEnv("NIX_SSL_CERT_FILE").value_or(getEnv("SSL_CERT_FILE").value_or("")); - if (sslOverride != "") - caFile = sslOverride; - /* Backwards compatibility. */ auto s = getEnv("NIX_REMOTE_SYSTEMS"); if (s) { @@ -116,13 +107,13 @@ void loadConfFile(AbstractConfig & config) } }; - applyConfigFile(settings.nixConfDir + "/nix.conf"); + applyConfigFile(bootstrapSettings.nixConfDir + "/nix.conf"); /* We only want to send overrides to the daemon, i.e. stuff from ~/.nix/nix.conf or the command line. */ config.resetOverridden(); - auto files = settings.nixUserConfFiles; + auto files = bootstrapSettings.nixUserConfFiles; for (auto file = files.rbegin(); file != files.rend(); file++) { applyConfigFile(*file); } @@ -133,23 +124,28 @@ void loadConfFile(AbstractConfig & config) } } -std::vector getUserConfigFiles() -{ - // Use the paths specified in NIX_USER_CONF_FILES if it has been defined - auto nixConfFiles = getEnv("NIX_USER_CONF_FILES"); - if (nixConfFiles.has_value()) { - return tokenizeString>(nixConfFiles.value(), ":"); - } +BootstrapSettings::BootstrapSettings() + : nixConfDir{canonPath(getEnvNonEmpty("NIX_CONF_DIR").value_or(NIX_CONF_DIR))} + , nixUserConfFiles{[] { + // Use the paths specified in NIX_USER_CONF_FILES if it has been defined + auto nixConfFiles = getEnv("NIX_USER_CONF_FILES"); + if (nixConfFiles.has_value()) { + return tokenizeString>(nixConfFiles.value(), ":"); + } - // Use the paths specified by the XDG spec - std::vector files; - auto dirs = getConfigDirs(); - for (auto & dir : dirs) { - files.insert(files.end(), dir + "/nix.conf"); - } - return files; + // Use the paths specified by the XDG spec + std::vector files; + auto dirs = getConfigDirs(); + for (auto & dir : dirs) { + files.insert(files.end(), dir + "/nix.conf"); + } + return files; + }()} +{ } +const BootstrapSettings bootstrapSettings; + unsigned int Settings::getDefaultCores() { const unsigned int concurrency = std::max(1U, std::thread::hardware_concurrency()); @@ -249,15 +245,6 @@ bool Settings::isWSL1() #endif } -Path Settings::getDefaultSSLCertFile() -{ - for (auto & fn : - {"/etc/ssl/certs/ca-certificates.crt", "/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt"}) - if (pathAccessible(fn)) - return fn; - return ""; -} - const ExternalBuilder * Settings::findExternalDerivationBuilderIfSupported(const Derivation & drv) { if (auto it = std::ranges::find_if( diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index ef6ae92a44d..5f3a392d993 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -19,9 +19,9 @@ StringSet HttpBinaryCacheStoreConfig::uriSchemes() } HttpBinaryCacheStoreConfig::HttpBinaryCacheStoreConfig( - std::string_view scheme, std::string_view _cacheUri, const Params & params) - : StoreConfig(params) - , BinaryCacheStoreConfig(params) + nix::Settings & settings, std::string_view scheme, std::string_view _cacheUri, const Params & params) + : StoreConfig(settings, params) + , BinaryCacheStoreConfig(settings, params) , cacheUri(parseURL( std::string{scheme} + "://" + (!_cacheUri.empty() ? _cacheUri @@ -55,7 +55,7 @@ HttpBinaryCacheStore::HttpBinaryCacheStore(ref config) , BinaryCacheStore{*config} , config{config} { - diskCache = getNarInfoDiskCache(); + diskCache = getNarInfoDiskCache(config->settings); } void HttpBinaryCacheStore::init() @@ -93,7 +93,7 @@ std::optional HttpBinaryCacheStore::getCompressionMethod(const std: void HttpBinaryCacheStore::maybeDisable() { auto state(_state.lock()); - if (state->enabled && settings.tryFallback) { + if (state->enabled && config->settings.tryFallback) { int t = 60; printError("disabling binary cache '%s' for %s seconds", config->getHumanReadableURI(), t); state->enabled = false; diff --git a/src/libstore/include/nix/store/build/derivation-builder.hh b/src/libstore/include/nix/store/build/derivation-builder.hh index af84661e252..7334f99fc95 100644 --- a/src/libstore/include/nix/store/build/derivation-builder.hh +++ b/src/libstore/include/nix/store/build/derivation-builder.hh @@ -15,6 +15,8 @@ namespace nix { +class Settings; + /** * Denotes a build failure that stemmed from the builder exiting with a * failing exist status. @@ -54,6 +56,8 @@ typedef std::map PathsInChroot; // maps target path to source */ struct DerivationBuilderParams { + Settings & settings; + /** The path of the derivation. */ const StorePath & drvPath; diff --git a/src/libstore/include/nix/store/builtins.hh b/src/libstore/include/nix/store/builtins.hh index 7cc9c091102..f5823bf1153 100644 --- a/src/libstore/include/nix/store/builtins.hh +++ b/src/libstore/include/nix/store/builtins.hh @@ -10,12 +10,15 @@ namespace nix { +class Settings; + struct BuiltinBuilderContext { const BasicDerivation & drv; std::map outputs; std::string netrcData; std::string caFileData; + Strings hashedMirrors; Path tmpDirInSandbox; #if NIX_WITH_AWS_AUTH diff --git a/src/libstore/include/nix/store/common-ssh-store-config.hh b/src/libstore/include/nix/store/common-ssh-store-config.hh index bbd81835d4f..8294e17ba73 100644 --- a/src/libstore/include/nix/store/common-ssh-store-config.hh +++ b/src/libstore/include/nix/store/common-ssh-store-config.hh @@ -12,8 +12,13 @@ struct CommonSSHStoreConfig : virtual StoreConfig { using StoreConfig::StoreConfig; - CommonSSHStoreConfig(std::string_view scheme, const ParsedURL::Authority & authority, const Params & params); - CommonSSHStoreConfig(std::string_view scheme, std::string_view authority, const Params & params); + CommonSSHStoreConfig( + nix::Settings & settings, + std::string_view scheme, + const ParsedURL::Authority & authority, + const Params & params); + CommonSSHStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params); const Setting sshKey{ this, "", "ssh-key", "Path to the SSH private key used to authenticate to the remote machine."}; diff --git a/src/libstore/include/nix/store/derivation-options.hh b/src/libstore/include/nix/store/derivation-options.hh index d733df1599b..31ab6071f8b 100644 --- a/src/libstore/include/nix/store/derivation-options.hh +++ b/src/libstore/include/nix/store/derivation-options.hh @@ -14,6 +14,7 @@ namespace nix { class Store; +class Settings; struct StoreDirConfig; struct BasicDerivation; struct StructuredAttrs; @@ -193,7 +194,7 @@ struct DerivationOptions */ bool willBuildLocally(Store & localStore, const BasicDerivation & drv) const; - bool substitutesAllowed() const; + bool substitutesAllowed(const Settings & settings) const; /** * @param drv See note on `getRequiredSystemFeatures` diff --git a/src/libstore/include/nix/store/dummy-store.hh b/src/libstore/include/nix/store/dummy-store.hh index febf351c975..1d3ae0915e8 100644 --- a/src/libstore/include/nix/store/dummy-store.hh +++ b/src/libstore/include/nix/store/dummy-store.hh @@ -12,15 +12,16 @@ struct DummyStore; struct DummyStoreConfig : public std::enable_shared_from_this, virtual StoreConfig { - DummyStoreConfig(const Params & params) - : StoreConfig(params) + DummyStoreConfig(nix::Settings & settings, const Params & params) + : StoreConfig(settings, params) { // Disable caching since this a temporary in-memory store. pathInfoCacheSize = 0; } - DummyStoreConfig(std::string_view scheme, std::string_view authority, const Params & params) - : DummyStoreConfig(params) + DummyStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params) + : DummyStoreConfig(settings, params) { if (!authority.empty()) throw UsageError("`%s` store URIs must not contain an authority part %s", scheme, authority); @@ -89,10 +90,16 @@ namespace nlohmann { template<> JSON_IMPL_INNER_TO(nix::DummyStoreConfig); template<> -JSON_IMPL_INNER_FROM(nix::ref); +struct adl_serializer> +{ + static nix::ref from_json(nix::Settings & settings, const json & json); +}; template<> JSON_IMPL_INNER_TO(nix::DummyStore); template<> -JSON_IMPL_INNER_FROM(nix::ref); +struct adl_serializer> +{ + static nix::ref from_json(nix::Settings & settings, const json & json); +}; } // namespace nlohmann diff --git a/src/libstore/include/nix/store/filetransfer.hh b/src/libstore/include/nix/store/filetransfer.hh index 76d036a7853..957ad49c8b8 100644 --- a/src/libstore/include/nix/store/filetransfer.hh +++ b/src/libstore/include/nix/store/filetransfer.hh @@ -12,6 +12,7 @@ #include "nix/util/url.hh" #include "nix/store/config.hh" +#include "nix/store/globals.hh" #if NIX_WITH_AWS_AUTH # include "nix/store/aws-creds.hh" #endif @@ -21,6 +22,12 @@ namespace nix { struct FileTransferSettings : Config { +private: + static Path getDefaultSSLCertFile(); + +public: + FileTransferSettings(); + Setting enableHttp2{this, true, "http2", "Whether to enable HTTP/2 support."}; Setting userAgentSuffix{ @@ -77,6 +84,64 @@ struct FileTransferSettings : Config not processed quickly enough to exceed the size of this buffer, downloads may stall. The default is 1048576 (1 MiB). )"}; + + Setting downloadSpeed{ + this, + 0, + "download-speed", + R"( + Specify the maximum transfer rate in kilobytes per second you want + Nix to use for downloads. + )"}; + + Setting netrcFile{ + this, + fmt("%s/%s", bootstrapSettings.nixConfDir, "netrc"), + "netrc-file", + R"( + If set to an absolute path to a `netrc` file, Nix uses the HTTP + authentication credentials in this file when trying to download from + a remote host through HTTP or HTTPS. Defaults to + `$NIX_CONF_DIR/netrc`. + + The `netrc` file consists of a list of accounts in the following + format: + + machine my-machine + login my-username + password my-password + + For the exact syntax, see [the `curl` + documentation](https://ec.haxx.se/usingcurl-netrc.html). + + > **Note** + > + > This must be an absolute path, and `~` is not resolved. For + > example, `~/.netrc` won't resolve to your home directory's + > `.netrc`. + )"}; + + Setting caFile{ + this, + getDefaultSSLCertFile(), + "ssl-cert-file", + R"( + The path of a file containing CA certificates used to + authenticate `https://` downloads. Nix by default uses + the first of the following files that exists: + + 1. `/etc/ssl/certs/ca-certificates.crt` + 2. `/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt` + + The path can be overridden by the following environment + variables, in order of precedence: + + 1. `NIX_SSL_CERT_FILE` + 2. `SSL_CERT_FILE` + )", + {}, + // Don't document the machine-specific default value + false}; }; extern FileTransferSettings fileTransferSettings; diff --git a/src/libstore/include/nix/store/globals.hh b/src/libstore/include/nix/store/globals.hh index 5ddfbee302b..783cbf1695d 100644 --- a/src/libstore/include/nix/store/globals.hh +++ b/src/libstore/include/nix/store/globals.hh @@ -62,6 +62,31 @@ const uint32_t maxIdsPerBuild = #endif ; +/** + * Settings that are needed very early during initialization, before a + * main `Settings` object can be constructed. + * + * For now, unlike `Settings`, this remains a global variable. The good + * news is that it is immutable except for depending on env vars, so it + * is almost a constant. + */ +struct BootstrapSettings +{ + /** + * The directory where system configuration files are stored. + */ + Path nixConfDir; + + /** + * A list of user configuration files to load. + */ + std::vector nixUserConfFiles; + + BootstrapSettings(); +}; + +extern const BootstrapSettings bootstrapSettings; + class Settings : public Config { @@ -71,8 +96,6 @@ class Settings : public Config bool isWSL1(); - Path getDefaultSSLCertFile(); - public: Settings(); @@ -98,16 +121,6 @@ public: */ Path nixStateDir; - /** - * The directory where system configuration files are stored. - */ - Path nixConfDir; - - /** - * A list of user configuration files to load. - */ - std::vector nixUserConfFiles; - /** * File name of the socket the daemon listens to. */ @@ -292,7 +305,7 @@ public: Setting builders{ this, - "@" + nixConfDir + "/machines", + "@" + bootstrapSettings.nixConfDir + "/machines", "builders", R"( A semicolon- or newline-separated list of build machines. @@ -1130,64 +1143,6 @@ public: /nix/store/xfghy8ixrhz3kyy6p724iv3cxji088dx-bash-4.4-p23`. )"}; - Setting downloadSpeed{ - this, - 0, - "download-speed", - R"( - Specify the maximum transfer rate in kilobytes per second you want - Nix to use for downloads. - )"}; - - Setting netrcFile{ - this, - fmt("%s/%s", nixConfDir, "netrc"), - "netrc-file", - R"( - If set to an absolute path to a `netrc` file, Nix uses the HTTP - authentication credentials in this file when trying to download from - a remote host through HTTP or HTTPS. Defaults to - `$NIX_CONF_DIR/netrc`. - - The `netrc` file consists of a list of accounts in the following - format: - - machine my-machine - login my-username - password my-password - - For the exact syntax, see [the `curl` - documentation](https://ec.haxx.se/usingcurl-netrc.html). - - > **Note** - > - > This must be an absolute path, and `~` is not resolved. For - > example, `~/.netrc` won't resolve to your home directory's - > `.netrc`. - )"}; - - Setting caFile{ - this, - getDefaultSSLCertFile(), - "ssl-cert-file", - R"( - The path of a file containing CA certificates used to - authenticate `https://` downloads. Nix by default uses - the first of the following files that exists: - - 1. `/etc/ssl/certs/ca-certificates.crt` - 2. `/nix/var/nix/profiles/default/etc/ssl/certs/ca-bundle.crt` - - The path can be overridden by the following environment - variables, in order of precedence: - - 1. `NIX_SSL_CERT_FILE` - 2. `SSL_CERT_FILE` - )", - {}, - // Don't document the machine-specific default value - false}; - #ifdef __linux__ Setting filterSyscalls{ this, @@ -1444,9 +1399,6 @@ public: const ExternalBuilder * findExternalDerivationBuilderIfSupported(const Derivation & drv); }; -// FIXME: don't use a global variable. -extern Settings settings; - /** * Load the configuration (from `nix.conf`, `NIX_CONFIG`, etc.) into the * given configuration object. @@ -1455,9 +1407,6 @@ extern Settings settings; */ void loadConfFile(AbstractConfig & config); -// Used by the Settings constructor -std::vector getUserConfigFiles(); - /** * The version of Nix itself. * diff --git a/src/libstore/include/nix/store/http-binary-cache-store.hh b/src/libstore/include/nix/store/http-binary-cache-store.hh index ea3d77b7987..fb85a4bbdbb 100644 --- a/src/libstore/include/nix/store/http-binary-cache-store.hh +++ b/src/libstore/include/nix/store/http-binary-cache-store.hh @@ -17,7 +17,10 @@ struct HttpBinaryCacheStoreConfig : std::enable_shared_from_this { using CommonSSHStoreConfig::CommonSSHStoreConfig; - LegacySSHStoreConfig(std::string_view scheme, std::string_view authority, const Params & params); + LegacySSHStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params); #ifndef _WIN32 // Hack for getting remote build log output. diff --git a/src/libstore/include/nix/store/local-binary-cache-store.hh b/src/libstore/include/nix/store/local-binary-cache-store.hh index 2846a9225c7..42847b59a43 100644 --- a/src/libstore/include/nix/store/local-binary-cache-store.hh +++ b/src/libstore/include/nix/store/local-binary-cache-store.hh @@ -12,7 +12,8 @@ struct LocalBinaryCacheStoreConfig : std::enable_shared_from_this, { using LocalFSStoreConfig::LocalFSStoreConfig; - LocalStoreConfig(std::string_view scheme, std::string_view authority, const Params & params); + LocalStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params); private: diff --git a/src/libstore/include/nix/store/machines.hh b/src/libstore/include/nix/store/machines.hh index 1f7bb669ab5..dedd81f4374 100644 --- a/src/libstore/include/nix/store/machines.hh +++ b/src/libstore/include/nix/store/machines.hh @@ -6,6 +6,7 @@ namespace nix { +class Settings; class Store; struct Machine; @@ -67,7 +68,7 @@ struct Machine * nix::openStore(completeStoreReference()) * ``` */ - ref openStore() const; + ref openStore(Settings & settings) const; /** * Parse a machine configuration. @@ -84,6 +85,6 @@ struct Machine * * @todo Remove, globals are bad. */ -Machines getMachines(); +Machines getMachines(const Settings & settings); } // namespace nix diff --git a/src/libstore/include/nix/store/nar-info-disk-cache.hh b/src/libstore/include/nix/store/nar-info-disk-cache.hh index 253487b3033..3e98ef0a32c 100644 --- a/src/libstore/include/nix/store/nar-info-disk-cache.hh +++ b/src/libstore/include/nix/store/nar-info-disk-cache.hh @@ -7,6 +7,8 @@ namespace nix { +class Settings; + class NarInfoDiskCache { public: @@ -40,9 +42,12 @@ public: /** * Return a singleton cache object that can be used concurrently by * multiple threads. + * + * @todo should use refined reference just with fields relevant to this, + * not the whole global settings. */ -ref getNarInfoDiskCache(); +ref getNarInfoDiskCache(const Settings & settings); -ref getTestNarInfoDiskCache(Path dbPath); +ref getTestNarInfoDiskCache(const Settings & settings, Path dbPath); } // namespace nix diff --git a/src/libstore/include/nix/store/posix-fs-canonicalise.hh b/src/libstore/include/nix/store/posix-fs-canonicalise.hh index 629759cfec3..f38830fd939 100644 --- a/src/libstore/include/nix/store/posix-fs-canonicalise.hh +++ b/src/libstore/include/nix/store/posix-fs-canonicalise.hh @@ -9,6 +9,8 @@ namespace nix { +class Settings; + typedef std::pair Inode; typedef std::set InodesSeen; @@ -30,6 +32,7 @@ typedef std::set InodesSeen; * [uidRange->first, uidRange->second]. */ void canonicalisePathMetaData( + const Settings & settings, const Path & path, #ifndef _WIN32 std::optional> uidRange, @@ -37,6 +40,7 @@ void canonicalisePathMetaData( InodesSeen & inodesSeen); void canonicalisePathMetaData( + const Settings & settings, const Path & path #ifndef _WIN32 , diff --git a/src/libstore/include/nix/store/profiles.hh b/src/libstore/include/nix/store/profiles.hh index 1cc306744f7..0704ba22e33 100644 --- a/src/libstore/include/nix/store/profiles.hh +++ b/src/libstore/include/nix/store/profiles.hh @@ -16,6 +16,7 @@ namespace nix { +class Settings; class StorePath; /** @@ -210,31 +211,31 @@ void lockProfile(PathLocks & lock, const std::filesystem::path & profile); std::string optimisticLockProfile(const std::filesystem::path & profile); /** - * Create and return the path to a directory suitable for storing the user’s + * Create and return the path to a directory suitable for storing the user's * profiles. */ -std::filesystem::path profilesDir(); +std::filesystem::path profilesDir(const Settings & settings); /** * Return the path to the profile directory for root (but don't try creating it) */ -std::filesystem::path rootProfilesDir(); +std::filesystem::path rootProfilesDir(const Settings & settings); /** * Create and return the path to the file used for storing the users's channels */ -std::filesystem::path defaultChannelsDir(); +std::filesystem::path defaultChannelsDir(const Settings & settings); /** * Return the path to the channel directory for root (but don't try creating it) */ -std::filesystem::path rootChannelsDir(); +std::filesystem::path rootChannelsDir(const Settings & settings); /** * Resolve the default profile (~/.nix-profile by default, * $XDG_STATE_HOME/nix/profile if XDG Base Directory Support is enabled), * and create if doesn't exist */ -std::filesystem::path getDefaultProfile(); +std::filesystem::path getDefaultProfile(const Settings & settings); } // namespace nix diff --git a/src/libstore/include/nix/store/s3-binary-cache-store.hh b/src/libstore/include/nix/store/s3-binary-cache-store.hh index 5896293f1c4..9a3295d4cfd 100644 --- a/src/libstore/include/nix/store/s3-binary-cache-store.hh +++ b/src/libstore/include/nix/store/s3-binary-cache-store.hh @@ -10,7 +10,8 @@ struct S3BinaryCacheStoreConfig : HttpBinaryCacheStoreConfig { using HttpBinaryCacheStoreConfig::HttpBinaryCacheStoreConfig; - S3BinaryCacheStoreConfig(std::string_view uriScheme, std::string_view bucketName, const Params & params); + S3BinaryCacheStoreConfig( + nix::Settings & settings, std::string_view uriScheme, std::string_view bucketName, const Params & params); const Setting profile{ this, diff --git a/src/libstore/include/nix/store/sqlite.hh b/src/libstore/include/nix/store/sqlite.hh index 3495c0bd143..9de569a3765 100644 --- a/src/libstore/include/nix/store/sqlite.hh +++ b/src/libstore/include/nix/store/sqlite.hh @@ -42,7 +42,13 @@ struct SQLite SQLite() {} - SQLite(const std::filesystem::path & path, SQLiteOpenMode mode = SQLiteOpenMode::Normal); + struct Settings + { + SQLiteOpenMode mode = SQLiteOpenMode::Normal; + bool useWAL; + }; + + SQLite(const std::filesystem::path & path, Settings && settings); SQLite(const SQLite & from) = delete; SQLite & operator=(const SQLite & from) = delete; diff --git a/src/libstore/include/nix/store/ssh-store.hh b/src/libstore/include/nix/store/ssh-store.hh index 9584a1a862c..f9b479044b4 100644 --- a/src/libstore/include/nix/store/ssh-store.hh +++ b/src/libstore/include/nix/store/ssh-store.hh @@ -15,7 +15,8 @@ struct SSHStoreConfig : std::enable_shared_from_this, using CommonSSHStoreConfig::CommonSSHStoreConfig; using RemoteStoreConfig::RemoteStoreConfig; - SSHStoreConfig(std::string_view scheme, std::string_view authority, const Params & params); + SSHStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params); const Setting remoteProgram{ this, {"nix-daemon"}, "remote-program", "Path to the `nix-daemon` executable on the remote machine."}; @@ -39,8 +40,8 @@ struct SSHStoreConfig : std::enable_shared_from_this, struct MountedSSHStoreConfig : virtual SSHStoreConfig, virtual LocalFSStoreConfig { - MountedSSHStoreConfig(StringMap params); - MountedSSHStoreConfig(std::string_view scheme, std::string_view host, StringMap params); + MountedSSHStoreConfig(nix::Settings & settings, StringMap params); + MountedSSHStoreConfig(nix::Settings & settings, std::string_view scheme, std::string_view host, StringMap params); static const std::string name() { diff --git a/src/libstore/include/nix/store/store-api.hh b/src/libstore/include/nix/store/store-api.hh index 9535227eb17..aae2e2605f5 100644 --- a/src/libstore/include/nix/store/store-api.hh +++ b/src/libstore/include/nix/store/store-api.hh @@ -43,6 +43,8 @@ struct SourceAccessor; class NarInfoDiskCache; class Store; +class Settings; + typedef std::map OutputPathMap; enum CheckSigsFlag : bool { NoCheckSigs = false, CheckSigs = true }; @@ -79,19 +81,32 @@ struct StoreConfigBase : Config { using Config::Config; + /** + * Global settings, which are we trying to triage and give better + * homes. Putting a reference to them on stores will help a bit with + * this, though we may find that some of the things here should + * *not* be per-store. + */ + nix::Settings & settings; + + StoreConfigBase(nix::Settings & settings) + : settings{settings} + { + } + private: /** * An indirection so that we don't need to refer to global settings * in headers. */ - static Path getDefaultNixStoreDir(); + static Path getDefaultNixStoreDir(const nix::Settings & settings); public: const PathSetting storeDir_{ this, - getDefaultNixStoreDir(), + getDefaultNixStoreDir(settings), "store", R"( Logical location of the Nix store, usually @@ -136,13 +151,13 @@ struct StoreConfig : public StoreConfigBase, public StoreDirConfig { using Params = StoreReference::Params; - StoreConfig(const Params & params); + StoreConfig(nix::Settings & settings, const Params & params); StoreConfig() = delete; virtual ~StoreConfig() {} - static StringSet getDefaultSystemFeatures(); + static StringSet getDefaultSystemFeatures(const nix::Settings & settings); /** * Documentation for this type of store. @@ -207,7 +222,7 @@ struct StoreConfig : public StoreConfigBase, public StoreDirConfig Setting systemFeatures{ this, - getDefaultSystemFeatures(), + getDefaultSystemFeatures(settings), "system-features", R"( Optional [system features](@docroot@/command-ref/conf-file.md#conf-system-features) available on the system this store uses to build derivations. @@ -294,7 +309,7 @@ protected: * Whether the value is valid as a cache entry. The path may not * exist. */ - bool isKnownNow(); + bool isKnownNow(const nix::Settings & settings); /** * Past tense, because a path can only be assumed to exists when diff --git a/src/libstore/include/nix/store/store-dir-config.hh b/src/libstore/include/nix/store/store-dir-config.hh index 34e928182ad..7572a3cde21 100644 --- a/src/libstore/include/nix/store/store-dir-config.hh +++ b/src/libstore/include/nix/store/store-dir-config.hh @@ -11,6 +11,7 @@ namespace nix { +class Settings; struct SourcePath; MakeError(BadStorePath, Error); @@ -89,6 +90,7 @@ struct StoreDirConfig * path for the given file system object. */ std::pair computeStorePath( + const Settings & settings, std::string_view name, const SourcePath & path, ContentAddressMethod method = ContentAddressMethod::Raw::NixArchive, diff --git a/src/libstore/include/nix/store/store-open.hh b/src/libstore/include/nix/store/store-open.hh index ef7d81675ec..f3c52638dc8 100644 --- a/src/libstore/include/nix/store/store-open.hh +++ b/src/libstore/include/nix/store/store-open.hh @@ -15,32 +15,37 @@ namespace nix { +class Settings; + /** * @return The store config denoted by `storeURI` (slight misnomer...). */ -ref resolveStoreConfig(StoreReference && storeURI); +ref resolveStoreConfig(Settings & settings, StoreReference && storeURI); /** * @return a Store object to access the Nix store denoted by - * ‘uri’ (slight misnomer...). + * 'uri' (slight misnomer...). */ -ref openStore(StoreReference && storeURI); +ref openStore(Settings & settings, StoreReference && storeURI); /** * Opens the store at `uri`, where `uri` is in the format expected by * `StoreReference::parse` */ -ref openStore(const std::string & uri, const StoreReference::Params & extraParams = StoreReference::Params()); +ref openStore( + Settings & settings, + const std::string & uri, + const StoreReference::Params & extraParams = StoreReference::Params()); /** * Short-hand which opens the default store, according to global settings */ -ref openStore(); +ref openStore(Settings & settings); /** * @return the default substituter stores, defined by the - * ‘substituters’ option and various legacy options. + * 'substituters' option and various legacy options. */ -std::list> getDefaultSubstituters(); +std::list> getDefaultSubstituters(Settings & settings); } // namespace nix diff --git a/src/libstore/include/nix/store/store-registration.hh b/src/libstore/include/nix/store/store-registration.hh index 8b0f344ba38..c47c7ed6974 100644 --- a/src/libstore/include/nix/store/store-registration.hh +++ b/src/libstore/include/nix/store/store-registration.hh @@ -14,6 +14,7 @@ */ #include "nix/store/store-api.hh" +#include "nix/store/globals.hh" namespace nix { @@ -40,7 +41,10 @@ struct StoreFactory * whatever comes after `://` and before `?`. */ std::function( - std::string_view scheme, std::string_view authorityPath, const Store::Config::Params & params)> + Settings & settings, + std::string_view scheme, + std::string_view authorityPath, + const Store::Config::Params & params)> parseConfig; /** @@ -64,10 +68,13 @@ struct Implementations .doc = TConfig::doc(), .uriSchemes = TConfig::uriSchemes(), .experimentalFeature = TConfig::experimentalFeature(), - .parseConfig = ([](auto scheme, auto uri, auto & params) -> ref { - return make_ref(scheme, uri, params); + .parseConfig = ([](Settings & settings, auto scheme, auto uri, auto & params) -> ref { + return make_ref(settings, scheme, uri, params); + }), + .getConfig = ([]() -> ref { + Settings settings; + return make_ref(settings, Store::Config::Params{}); }), - .getConfig = ([]() -> ref { return make_ref(Store::Config::Params{}); }), }; auto [it, didInsert] = registered().insert({TConfig::name(), std::move(factory)}); if (!didInsert) { diff --git a/src/libstore/include/nix/store/uds-remote-store.hh b/src/libstore/include/nix/store/uds-remote-store.hh index 764e8768a32..0480b31bce7 100644 --- a/src/libstore/include/nix/store/uds-remote-store.hh +++ b/src/libstore/include/nix/store/uds-remote-store.hh @@ -19,9 +19,10 @@ struct UDSRemoteStoreConfig : std::enable_shared_from_this /** * @param authority is the socket path. */ - UDSRemoteStoreConfig(std::string_view scheme, std::string_view authority, const Params & params); + UDSRemoteStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params); - UDSRemoteStoreConfig(const Params & params); + UDSRemoteStoreConfig(nix::Settings & settings, const Params & params); static const std::string name() { diff --git a/src/libstore/keys.cc b/src/libstore/keys.cc index 8b02e7a6681..159aff5ad88 100644 --- a/src/libstore/keys.cc +++ b/src/libstore/keys.cc @@ -4,7 +4,7 @@ namespace nix { -PublicKeys getDefaultPublicKeys() +PublicKeys getDefaultPublicKeys(const Settings & settings) { PublicKeys publicKeys; diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc index 3b466c9bb8b..fed3af4d725 100644 --- a/src/libstore/legacy-ssh-store.cc +++ b/src/libstore/legacy-ssh-store.cc @@ -17,9 +17,10 @@ namespace nix { -LegacySSHStoreConfig::LegacySSHStoreConfig(std::string_view scheme, std::string_view authority, const Params & params) - : StoreConfig(params) - , CommonSSHStoreConfig(scheme, ParsedURL::Authority::parse(authority), params) +LegacySSHStoreConfig::LegacySSHStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params) + : StoreConfig(settings, params) + , CommonSSHStoreConfig(settings, scheme, ParsedURL::Authority::parse(authority), params) { } @@ -177,7 +178,7 @@ void LegacySSHStore::narFromPath(const StorePath & path, std::functionnarFromPath(*this, path, fun); } -static ServeProto::BuildOptions buildSettings() +static ServeProto::BuildOptions buildSettings(const Settings & settings) { return { .maxSilentTime = settings.maxSilentTime, @@ -193,7 +194,7 @@ BuildResult LegacySSHStore::buildDerivation(const StorePath & drvPath, const Bas { auto conn(connections->get()); - conn->putBuildDerivationRequest(*this, drvPath, drv, buildSettings()); + conn->putBuildDerivationRequest(*this, drvPath, drv, buildSettings(config->settings)); return conn->getBuildDerivationResponse(*this); } @@ -237,7 +238,7 @@ void LegacySSHStore::buildPaths( } conn->to << ss; - ServeProto::write(*this, *conn, buildSettings()); + ServeProto::write(*this, *conn, buildSettings(config->settings)); conn->to.flush(); diff --git a/src/libstore/linux/include/nix/store/personality.hh b/src/libstore/linux/include/nix/store/personality.hh index 01bf2bf331e..69ef629f2c2 100644 --- a/src/libstore/linux/include/nix/store/personality.hh +++ b/src/libstore/linux/include/nix/store/personality.hh @@ -3,8 +3,14 @@ #include +namespace nix { + +class Settings; + +} + namespace nix::linux { -void setPersonality(std::string_view system); +void setPersonality(const nix::Settings & settings, std::string_view system); } diff --git a/src/libstore/linux/personality.cc b/src/libstore/linux/personality.cc index d268706b238..8ac221b6fe2 100644 --- a/src/libstore/linux/personality.cc +++ b/src/libstore/linux/personality.cc @@ -8,7 +8,7 @@ namespace nix::linux { -void setPersonality(std::string_view system) +void setPersonality(const Settings & settings, std::string_view system) { /* Change the personality to 32-bit if we're doing an i686-linux build on an x86_64-linux machine. */ diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index 63730a01bd7..80979b3c96d 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -9,9 +9,9 @@ namespace nix { LocalBinaryCacheStoreConfig::LocalBinaryCacheStoreConfig( - std::string_view scheme, PathView binaryCacheDir, const StoreReference::Params & params) - : Store::Config{params} - , BinaryCacheStoreConfig{params} + nix::Settings & settings, std::string_view scheme, PathView binaryCacheDir, const StoreReference::Params & params) + : Store::Config{settings, params} + , BinaryCacheStoreConfig{settings, params} , binaryCacheDir(binaryCacheDir) { } diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc index 1a38cac3b7f..fe9ce769cab 100644 --- a/src/libstore/local-fs-store.cc +++ b/src/libstore/local-fs-store.cc @@ -8,18 +8,18 @@ namespace nix { -Path LocalFSStoreConfig::getDefaultStateDir() +Path LocalFSStoreConfig::getDefaultStateDir(const nix::Settings & settings) { return settings.nixStateDir; } -Path LocalFSStoreConfig::getDefaultLogDir() +Path LocalFSStoreConfig::getDefaultLogDir(const nix::Settings & settings) { return settings.nixLogDir; } -LocalFSStoreConfig::LocalFSStoreConfig(PathView rootDir, const Params & params) - : StoreConfig(params) +LocalFSStoreConfig::LocalFSStoreConfig(nix::Settings & settings, PathView rootDir, const Params & params) + : StoreConfig(settings, params) /* Default `?root` from `rootDir` if non set * NOTE: We would like to just do rootDir.set(...), which would take care of * all normalization and error checking for us. Unfortunately we cannot do diff --git a/src/libstore/local-overlay-store.cc b/src/libstore/local-overlay-store.cc index c8aa1d1a2b6..835e1b40b74 100644 --- a/src/libstore/local-overlay-store.cc +++ b/src/libstore/local-overlay-store.cc @@ -43,7 +43,8 @@ LocalOverlayStore::LocalOverlayStore(ref config) , LocalFSStore{*config} , LocalStore{static_cast>(config)} , config{config} - , lowerStore(openStore(percentDecode(config->lowerStoreUri.get())).dynamic_pointer_cast()) + , lowerStore( + openStore(config->settings, percentDecode(config->lowerStoreUri.get())).dynamic_pointer_cast()) { if (config->checkMount.get()) { std::smatch match; diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index a849576f6ee..0e651755488 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -61,9 +61,10 @@ namespace nix { -LocalStoreConfig::LocalStoreConfig(std::string_view scheme, std::string_view authority, const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(authority, params) +LocalStoreConfig::LocalStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params) + : StoreConfig(settings, params) + , LocalFSStoreConfig(settings, authority, params) { } @@ -160,13 +161,14 @@ LocalStore::LocalStore(ref config) #ifndef _WIN32 /* Optionally, create directories and set permissions for a multi-user install. */ - if (isRootUser() && settings.buildUsersGroup != "") { + if (isRootUser() && config->settings.buildUsersGroup != "") { mode_t perm = 01775; - struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str()); + struct group * gr = getgrnam(config->settings.buildUsersGroup.get().c_str()); if (!gr) printError( - "warning: the group '%1%' specified in 'build-users-group' does not exist", settings.buildUsersGroup); + "warning: the group '%1%' specified in 'build-users-group' does not exist", + config->settings.buildUsersGroup); else if (!config->readOnly) { struct stat st; if (stat(config->realStoreDir.get().c_str(), &st)) @@ -183,7 +185,7 @@ LocalStore::LocalStore(ref config) #endif /* Ensure that the store and its parents are not symlinks. */ - if (!settings.allowSymlinkedStore) { + if (!config->settings.allowSymlinkedStore) { std::filesystem::path path = config->realStoreDir.get(); std::filesystem::path root = path.root_path(); while (path != root) { @@ -202,7 +204,7 @@ LocalStore::LocalStore(ref config) before doing a garbage collection. */ try { struct stat st; - if (stat(reservedPath.c_str(), &st) == -1 || st.st_size != settings.reservedSize) { + if (stat(reservedPath.c_str(), &st) == -1 || st.st_size != config->settings.reservedSize) { AutoCloseFD fd = toDescriptor(open( reservedPath.c_str(), O_WRONLY | O_CREAT @@ -213,16 +215,16 @@ LocalStore::LocalStore(ref config) 0600)); int res = -1; #if HAVE_POSIX_FALLOCATE - res = posix_fallocate(fd.get(), 0, settings.reservedSize); + res = posix_fallocate(fd.get(), 0, config->settings.reservedSize); #endif if (res == -1) { - writeFull(fd.get(), std::string(settings.reservedSize, 'X')); + writeFull(fd.get(), std::string(config->settings.reservedSize, 'X')); [[gnu::unused]] auto res2 = #ifdef _WIN32 SetEndOfFile(fd.get()) #else - ftruncate(fd.get(), settings.reservedSize) + ftruncate(fd.get(), config->settings.reservedSize) #endif ; } @@ -498,7 +500,8 @@ void LocalStore::openDB(State & state, bool create) auto openMode = config->readOnly ? SQLiteOpenMode::Immutable : create ? SQLiteOpenMode::Normal : SQLiteOpenMode::NoCreate; - state.db = SQLite(std::filesystem::path(dbDir) / "db.sqlite", openMode); + state.db = + SQLite(std::filesystem::path(dbDir) / "db.sqlite", {.mode = openMode, .useWAL = config->settings.useSQLiteWAL}); #ifdef __CYGWIN__ /* The cygwin version of sqlite3 has a patch which calls @@ -517,12 +520,12 @@ void LocalStore::openDB(State & state, bool create) should be safe enough. If the user asks for it, don't sync at all. This can cause database corruption if the system crashes. */ - std::string syncMode = settings.fsyncMetadata ? "normal" : "off"; + std::string syncMode = config->settings.fsyncMetadata ? "normal" : "off"; db.exec("pragma synchronous = " + syncMode); /* Set the SQLite journal mode. WAL mode is fastest, so it's the default. */ - std::string mode = settings.useSQLiteWAL ? "wal" : "truncate"; + std::string mode = config->settings.useSQLiteWAL ? "wal" : "truncate"; std::string prevMode; { SQLiteStmt stmt; @@ -907,7 +910,7 @@ std::optional LocalStore::queryPathFromHashPart(const std::string & h StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths) { - if (!settings.useSubstitutes) + if (!config->settings.useSubstitutes) return StorePathSet(); StorePathSet remaining; @@ -916,7 +919,7 @@ StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths) StorePathSet res; - for (auto & sub : getDefaultSubstituters()) { + for (auto & sub : getDefaultSubstituters(config->settings)) { if (remaining.empty()) break; if (sub->storeDir != storeDir) @@ -951,7 +954,7 @@ void LocalStore::registerValidPaths(const ValidPathInfos & infos) be fsync-ed. So some may want to fsync them before registering the validity, at the expense of some speed of the path registering operation. */ - if (settings.syncBeforeRegistering) + if (config->settings.syncBeforeRegistering) sync(); #endif @@ -1028,7 +1031,7 @@ const PublicKeys & LocalStore::getPublicKeys() { auto state(_state->lock()); if (!state->publicKeys) - state->publicKeys = std::make_unique(getDefaultPublicKeys()); + state->publicKeys = std::make_unique(getDefaultPublicKeys(config->settings)); return *state->publicKeys; } @@ -1085,7 +1088,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, RepairF TeeSource wrapperSource{source, hashSink}; narRead = true; - restorePath(realPath, wrapperSource, settings.fsyncStorePaths); + restorePath(realPath, wrapperSource, config->settings.fsyncStorePaths); auto hashResult = hashSink.finish(); @@ -1141,11 +1144,11 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, RepairF autoGC(); - canonicalisePathMetaData(realPath); + canonicalisePathMetaData(config->settings, realPath); optimisePath(realPath, repair); // FIXME: combine with hashPath() - if (settings.fsyncStorePaths) { + if (config->settings.fsyncStorePaths) { recursiveSync(realPath); syncParent(realPath); } @@ -1196,10 +1199,10 @@ StorePath LocalStore::addToStoreFromDump( /* Fill out buffer, and decide whether we are working strictly in memory based on whether we break out because the buffer is full or the original source is empty */ - while (dump.size() < settings.narBufferSize) { + while (dump.size() < config->settings.narBufferSize) { auto oldSize = dump.size(); constexpr size_t chunkSize = 65536; - auto want = std::min(chunkSize, settings.narBufferSize - oldSize); + auto want = std::min(chunkSize, config->settings.narBufferSize - oldSize); if (auto tmp = realloc(dumpBuffer.get(), oldSize + want)) { dumpBuffer.release(); dumpBuffer.reset((char *) tmp); @@ -1236,7 +1239,7 @@ StorePath LocalStore::addToStoreFromDump( delTempDir = std::make_unique(tempDir); tempPath = tempDir / "x"; - restorePath(tempPath.string(), bothSource, dumpMethod, settings.fsyncStorePaths); + restorePath(tempPath.string(), bothSource, dumpMethod, config->settings.fsyncStorePaths); dumpBuffer.reset(); dump = {}; @@ -1280,7 +1283,7 @@ StorePath LocalStore::addToStoreFromDump( switch (fim) { case FileIngestionMethod::Flat: case FileIngestionMethod::NixArchive: - restorePath(realPath, dumpSource, (FileSerialisationMethod) fim, settings.fsyncStorePaths); + restorePath(realPath, dumpSource, (FileSerialisationMethod) fim, config->settings.fsyncStorePaths); break; case FileIngestionMethod::Git: // doesn't correspond to serialization method, so @@ -1301,11 +1304,11 @@ StorePath LocalStore::addToStoreFromDump( narHash = narSink.finish(); } - canonicalisePathMetaData(realPath); // FIXME: merge into restorePath + canonicalisePathMetaData(config->settings, realPath); // FIXME: merge into restorePath optimisePath(realPath, repair); - if (settings.fsyncStorePaths) { + if (config->settings.fsyncStorePaths) { recursiveSync(realPath); syncParent(realPath); } diff --git a/src/libstore/machines.cc b/src/libstore/machines.cc index d614676668b..9b6e1130839 100644 --- a/src/libstore/machines.cc +++ b/src/libstore/machines.cc @@ -91,9 +91,9 @@ StoreReference Machine::completeStoreReference() const return storeUri; } -ref Machine::openStore() const +ref Machine::openStore(Settings & settings) const { - return nix::openStore(completeStoreReference()); + return nix::openStore(settings, completeStoreReference()); } static std::vector expandBuilderLines(const std::string & builders) @@ -207,7 +207,7 @@ Machines Machine::parseConfig(const StringSet & defaultSystems, const std::strin return parseBuilderLines(defaultSystems, builderLines); } -Machines getMachines() +Machines getMachines(const Settings & settings) { return Machine::parseConfig({settings.thisSystem}, settings.builders); } diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc index 9d11648d2a6..8ffc713c86d 100644 --- a/src/libstore/misc.cc +++ b/src/libstore/misc.cc @@ -236,7 +236,8 @@ MissingPaths Store::queryMissing(const std::vector & targets) throw; } - if (!knownOutputPaths && settings.useSubstitutes && drvOptions.substitutesAllowed()) { + if (!knownOutputPaths && config.settings.useSubstitutes + && drvOptions.substitutesAllowed(config.settings)) { experimentalFeatureSettings.require(Xp::CaDerivations); // If there are unknown output paths, attempt to find if the @@ -249,7 +250,7 @@ MissingPaths Store::queryMissing(const std::vector & targets) continue; bool found = false; - for (auto & sub : getDefaultSubstituters()) { + for (auto & sub : getDefaultSubstituters(config.settings)) { auto realisation = sub->queryRealisation({hash, outputName}); if (!realisation) continue; @@ -266,7 +267,8 @@ MissingPaths Store::queryMissing(const std::vector & targets) } } - if (knownOutputPaths && settings.useSubstitutes && drvOptions.substitutesAllowed()) { + if (knownOutputPaths && config.settings.useSubstitutes + && drvOptions.substitutesAllowed(config.settings)) { auto drvState = make_ref>(DrvState(invalid.size())); for (auto & output : invalid) pool.enqueue(std::bind(checkOutput, drvPath, drv, output, drvState)); diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc index 11608a667b3..55ca29f3d9b 100644 --- a/src/libstore/nar-info-disk-cache.cc +++ b/src/libstore/nar-info-disk-cache.cc @@ -62,6 +62,8 @@ class NarInfoDiskCacheImpl : public NarInfoDiskCache { public: + const Settings & settings; + /* How often to purge expired entries from the cache. */ const int purgeInterval = 24 * 3600; @@ -86,13 +88,14 @@ class NarInfoDiskCacheImpl : public NarInfoDiskCache Sync _state; - NarInfoDiskCacheImpl(Path dbPath = getCacheDir() + "/binary-cache-v7.sqlite") + NarInfoDiskCacheImpl(const Settings & settings, Path dbPath = getCacheDir() + "/binary-cache-v7.sqlite") + : settings(settings) { auto state(_state.lock()); createDirs(dirOf(dbPath)); - state->db = SQLite(dbPath); + state->db = SQLite(dbPath, {.useWAL = settings.useSQLiteWAL}); state->db.isCache(); @@ -371,15 +374,15 @@ class NarInfoDiskCacheImpl : public NarInfoDiskCache } }; -ref getNarInfoDiskCache() +ref getNarInfoDiskCache(const Settings & settings) { - static ref cache = make_ref(); + static ref cache = make_ref(settings); return cache; } -ref getTestNarInfoDiskCache(Path dbPath) +ref getTestNarInfoDiskCache(const Settings & settings, Path dbPath) { - return make_ref(dbPath); + return make_ref(settings, dbPath); } } // namespace nix diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index dca093e04c7..ed223461086 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -320,7 +320,7 @@ void LocalStore::optimisePath(const Path & path, RepairFlag repair) OptimiseStats stats; InodeHash inodeHash; - if (settings.autoOptimiseStore) + if (config->settings.autoOptimiseStore) optimisePath_(nullptr, stats, path, inodeHash, repair); } diff --git a/src/libstore/posix-fs-canonicalise.cc b/src/libstore/posix-fs-canonicalise.cc index a274468c329..662be36ad84 100644 --- a/src/libstore/posix-fs-canonicalise.cc +++ b/src/libstore/posix-fs-canonicalise.cc @@ -43,6 +43,7 @@ void canonicaliseTimestampAndPermissions(const Path & path) } static void canonicalisePathMetaData_( + const Settings & settings, const Path & path, #ifndef _WIN32 std::optional> uidRange, @@ -133,6 +134,7 @@ static void canonicalisePathMetaData_( for (auto & i : DirectoryIterator{path}) { checkInterrupt(); canonicalisePathMetaData_( + settings, i.path().string(), #ifndef _WIN32 uidRange, @@ -143,6 +145,7 @@ static void canonicalisePathMetaData_( } void canonicalisePathMetaData( + const Settings & settings, const Path & path, #ifndef _WIN32 std::optional> uidRange, @@ -150,6 +153,7 @@ void canonicalisePathMetaData( InodesSeen & inodesSeen) { canonicalisePathMetaData_( + settings, path, #ifndef _WIN32 uidRange, @@ -169,6 +173,7 @@ void canonicalisePathMetaData( } void canonicalisePathMetaData( + const Settings & settings, const Path & path #ifndef _WIN32 , @@ -178,6 +183,7 @@ void canonicalisePathMetaData( { InodesSeen inodesSeen; canonicalisePathMetaData_( + settings, path, #ifndef _WIN32 uidRange, diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index 22d3f8f8973..43a5f9ad0fe 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -291,25 +291,25 @@ std::string optimisticLockProfile(const std::filesystem::path & profile) return pathExists(profile) ? readLink(profile).string() : ""; } -std::filesystem::path profilesDir() +std::filesystem::path profilesDir(const Settings & settings) { - auto profileRoot = isRootUser() ? rootProfilesDir() : std::filesystem::path{createNixStateDir()} / "profiles"; + auto profileRoot = isRootUser() ? rootProfilesDir(settings) : std::filesystem::path{createNixStateDir()} / "profiles"; createDirs(profileRoot); return profileRoot; } -std::filesystem::path rootProfilesDir() +std::filesystem::path rootProfilesDir(const Settings & settings) { return std::filesystem::path{settings.nixStateDir} / "profiles/per-user/root"; } -std::filesystem::path getDefaultProfile() +std::filesystem::path getDefaultProfile(const Settings & settings) { std::filesystem::path profileLink = settings.useXDGBaseDirectories ? std::filesystem::path{createNixStateDir()} / "profile" : std::filesystem::path{getHome()} / ".nix-profile"; try { - auto profile = profilesDir() / "profile"; + auto profile = profilesDir(settings) / "profile"; if (!pathExists(profileLink)) { replaceSymlink(profile, profileLink); } @@ -328,14 +328,14 @@ std::filesystem::path getDefaultProfile() } } -std::filesystem::path defaultChannelsDir() +std::filesystem::path defaultChannelsDir(const Settings & settings) { - return profilesDir() / "channels"; + return profilesDir(settings) / "channels"; } -std::filesystem::path rootChannelsDir() +std::filesystem::path rootChannelsDir(const Settings & settings) { - return rootProfilesDir() / "channels"; + return rootProfilesDir(settings) / "channels"; } } // namespace nix diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index b07efc0241a..e69b20d5c36 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -105,6 +105,8 @@ void RemoteStore::initConnection(Connection & conn) void RemoteStore::setOptions(Connection & conn) { + auto & settings = config.settings; + conn.to << WorkerProto::Op::SetOptions << settings.keepFailed << settings.keepGoing << settings.tryFallback << verbosity << settings.maxBuildJobs << settings.maxSilentTime << true << (settings.verboseBuild ? lvlError : lvlVomit) << 0 // obsolete log type diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index 5dfc7f11de5..f11bb90bdb6 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -401,9 +401,9 @@ StringSet S3BinaryCacheStoreConfig::uriSchemes() } S3BinaryCacheStoreConfig::S3BinaryCacheStoreConfig( - std::string_view scheme, std::string_view _cacheUri, const Params & params) - : StoreConfig(params) - , HttpBinaryCacheStoreConfig(scheme, _cacheUri, params) + nix::Settings & settings, std::string_view scheme, std::string_view _cacheUri, const Params & params) + : StoreConfig(settings, params) + , HttpBinaryCacheStoreConfig(settings, scheme, _cacheUri, params) { assert(cacheUri.query.empty()); assert(cacheUri.scheme == "s3"); diff --git a/src/libstore/sqlite.cc b/src/libstore/sqlite.cc index 5f0b3ce51a1..836b5c63e01 100644 --- a/src/libstore/sqlite.cc +++ b/src/libstore/sqlite.cc @@ -62,7 +62,7 @@ static void traceSQL(void * x, const char * sql) notice("SQL<[%1%]>", sql); }; -SQLite::SQLite(const std::filesystem::path & path, SQLiteOpenMode mode) +SQLite::SQLite(const std::filesystem::path & path, Settings && settings) { // Work around a ZFS issue where SQLite's truncate() call on // db.sqlite-shm can randomly take up to a few seconds. See @@ -89,10 +89,10 @@ SQLite::SQLite(const std::filesystem::path & path, SQLiteOpenMode mode) // useSQLiteWAL also indicates what virtual file system we need. Using // `unix-dotfile` is needed on NFS file systems and on Windows' Subsystem // for Linux (WSL) where useSQLiteWAL should be false by default. - const char * vfs = settings.useSQLiteWAL ? 0 : "unix-dotfile"; - bool immutable = mode == SQLiteOpenMode::Immutable; + const char * vfs = settings.useWAL ? 0 : "unix-dotfile"; + bool immutable = settings.mode == SQLiteOpenMode::Immutable; int flags = immutable ? SQLITE_OPEN_READONLY : SQLITE_OPEN_READWRITE; - if (mode == SQLiteOpenMode::Normal) + if (settings.mode == SQLiteOpenMode::Normal) flags |= SQLITE_OPEN_CREATE; auto uri = "file:" + percentEncode(path.string()) + "?immutable=" + (immutable ? "1" : "0"); int ret = sqlite3_open_v2(uri.c_str(), &db, SQLITE_OPEN_URI | flags, vfs); diff --git a/src/libstore/ssh-store.cc b/src/libstore/ssh-store.cc index ce973e7343a..a9607a90c6a 100644 --- a/src/libstore/ssh-store.cc +++ b/src/libstore/ssh-store.cc @@ -11,10 +11,11 @@ namespace nix { -SSHStoreConfig::SSHStoreConfig(std::string_view scheme, std::string_view authority, const Params & params) - : Store::Config{params} - , RemoteStore::Config{params} - , CommonSSHStoreConfig{scheme, authority, params} +SSHStoreConfig::SSHStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view authority, const Params & params) + : Store::Config{settings, params} + , RemoteStore::Config{settings, params} + , CommonSSHStoreConfig{settings, scheme, authority, params} { } @@ -87,21 +88,22 @@ struct SSHStore : virtual RemoteStore }; }; -MountedSSHStoreConfig::MountedSSHStoreConfig(StringMap params) - : StoreConfig(params) - , RemoteStoreConfig(params) - , CommonSSHStoreConfig(params) - , SSHStoreConfig(params) - , LocalFSStoreConfig(params) +MountedSSHStoreConfig::MountedSSHStoreConfig(nix::Settings & settings, StringMap params) + : StoreConfig(settings, params) + , RemoteStoreConfig(settings, params) + , CommonSSHStoreConfig(settings, params) + , SSHStoreConfig(settings, params) + , LocalFSStoreConfig(settings, "", params) { } -MountedSSHStoreConfig::MountedSSHStoreConfig(std::string_view scheme, std::string_view host, StringMap params) - : StoreConfig(params) - , RemoteStoreConfig(params) - , CommonSSHStoreConfig(scheme, host, params) - , SSHStoreConfig(scheme, host, params) - , LocalFSStoreConfig(params) +MountedSSHStoreConfig::MountedSSHStoreConfig( + nix::Settings & settings, std::string_view scheme, std::string_view host, StringMap params) + : StoreConfig(settings, params) + , RemoteStoreConfig(settings, params) + , CommonSSHStoreConfig(settings, scheme, host, params) + , SSHStoreConfig(settings, scheme, host, params) + , LocalFSStoreConfig(settings, "", params) { } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 52130668ce5..a270ec35086 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -28,13 +28,13 @@ using json = nlohmann::json; namespace nix { -Path StoreConfigBase::getDefaultNixStoreDir() +Path StoreConfigBase::getDefaultNixStoreDir(const nix::Settings & settings) { return settings.nixStore; } -StoreConfig::StoreConfig(const Params & params) - : StoreConfigBase(params) +StoreConfig::StoreConfig(nix::Settings & settings, const Params & params) + : StoreConfigBase(settings) , StoreDirConfig{storeDir_} { } @@ -110,7 +110,7 @@ StorePath Store::addToStore( auto sink = sourceToSink([&](Source & source) { LengthSource lengthSource(source); storePath = addToStoreFromDump(lengthSource, name, fsm, method, hashAlgo, references, repair); - if (settings.warnLargePathThreshold && lengthSource.total >= settings.warnLargePathThreshold) + if (config.settings.warnLargePathThreshold && lengthSource.total >= config.settings.warnLargePathThreshold) warn("copied large path '%s' to the store (%s)", path, renderSize(lengthSource.total)); }); dumpPath(path, *sink, fsm, filter); @@ -176,7 +176,7 @@ void Store::addMultipleToStore(PathsSource && pathsToCopy, Activity & act, Repai addToStore(info, *source, repair, checkSigs); } catch (Error & e) { nrFailed++; - if (!settings.keepGoing) + if (!config.settings.keepGoing) throw e; printMsg(lvlError, "could not copy %s: %s", printStorePath(path), e.what()); showProgress(); @@ -307,7 +307,7 @@ void Store::narFromPath(const StorePath & path, Sink & sink) dumpPath(sourcePath, sink, FileSerialisationMethod::NixArchive); } -StringSet Store::Config::getDefaultSystemFeatures() +StringSet Store::Config::getDefaultSystemFeatures(const nix::Settings & settings) { auto res = settings.systemFeatures.get(); @@ -333,7 +333,7 @@ StoreReference StoreConfig::getReference() const return {.variant = StoreReference::Auto{}}; } -bool Store::PathInfoCacheValue::isKnownNow() +bool Store::PathInfoCacheValue::isKnownNow(const nix::Settings & settings) { std::chrono::duration ttl = didExist() ? std::chrono::seconds(settings.ttlPositiveNarInfoCache) : std::chrono::seconds(settings.ttlNegativeNarInfoCache); @@ -407,12 +407,12 @@ StorePathSet Store::queryDerivationOutputs(const StorePath & path) void Store::querySubstitutablePathInfos(const StorePathCAMap & paths, SubstitutablePathInfos & infos) { - if (!settings.useSubstitutes) + if (!config.settings.useSubstitutes) return; for (auto & path : paths) { std::optional lastStoresException = std::nullopt; - for (auto & sub : getDefaultSubstituters()) { + for (auto & sub : getDefaultSubstituters(config.settings)) { if (lastStoresException.has_value()) { logError(lastStoresException->info()); lastStoresException.reset(); @@ -461,7 +461,7 @@ void Store::querySubstitutablePathInfos(const StorePathCAMap & paths, Substituta } } if (lastStoresException.has_value()) { - if (!settings.tryFallback) { + if (!config.settings.tryFallback) { throw *lastStoresException; } else logError(lastStoresException->info()); @@ -472,7 +472,7 @@ void Store::querySubstitutablePathInfos(const StorePathCAMap & paths, Substituta bool Store::isValidPath(const StorePath & storePath) { auto res = pathInfoCache->lock()->get(storePath.to_string()); - if (res && res->isKnownNow()) { + if (res && res->isKnownNow(config.settings)) { stats.narInfoReadAverted++; return res->didExist(); } @@ -538,7 +538,7 @@ std::optional> Store::queryPathInfoFromClie auto hashPart = std::string(storePath.hashPart()); auto res = pathInfoCache->lock()->get(storePath.to_string()); - if (res && res->isKnownNow()) { + if (res && res->isKnownNow(config.settings)) { stats.narInfoReadAverted++; if (res->didExist()) return std::make_optional(res->value); @@ -1195,7 +1195,7 @@ void Store::signPathInfo(ValidPathInfo & info) { // FIXME: keep secret keys in memory. - auto secretKeyFiles = settings.secretKeyFiles; + auto secretKeyFiles = config.settings.secretKeyFiles; for (auto & secretKeyFile : secretKeyFiles.get()) { SecretKey secretKey(readFile(secretKeyFile)); @@ -1208,7 +1208,7 @@ void Store::signRealisation(Realisation & realisation) { // FIXME: keep secret keys in memory. - auto secretKeyFiles = settings.secretKeyFiles; + auto secretKeyFiles = config.settings.secretKeyFiles; for (auto & secretKeyFile : secretKeyFiles.get()) { SecretKey secretKey(readFile(secretKeyFile)); diff --git a/src/libstore/store-dir-config.cc b/src/libstore/store-dir-config.cc index 8c756ff5819..24bf8246230 100644 --- a/src/libstore/store-dir-config.cc +++ b/src/libstore/store-dir-config.cc @@ -149,6 +149,7 @@ StoreDirConfig::makeFixedOutputPathFromCA(std::string_view name, const ContentAd } std::pair StoreDirConfig::computeStorePath( + const Settings & settings, std::string_view name, const SourcePath & path, ContentAddressMethod method, diff --git a/src/libstore/store-registration.cc b/src/libstore/store-registration.cc index cfaf86b1e8b..828a26d1067 100644 --- a/src/libstore/store-registration.cc +++ b/src/libstore/store-registration.cc @@ -6,24 +6,24 @@ namespace nix { -ref openStore() +ref openStore(Settings & settings) { - return openStore(settings.storeUri.get()); + return openStore(settings, settings.storeUri.get()); } -ref openStore(const std::string & uri, const Store::Config::Params & extraParams) +ref openStore(Settings & settings, const std::string & uri, const Store::Config::Params & extraParams) { - return openStore(StoreReference::parse(uri, extraParams)); + return openStore(settings, StoreReference::parse(uri, extraParams)); } -ref openStore(StoreReference && storeURI) +ref openStore(Settings & settings, StoreReference && storeURI) { - auto store = resolveStoreConfig(std::move(storeURI))->openStore(); + auto store = resolveStoreConfig(settings, std::move(storeURI))->openStore(); store->init(); return store; } -ref resolveStoreConfig(StoreReference && storeURI) +ref resolveStoreConfig(Settings & settings, StoreReference && storeURI) { auto & params = storeURI.params; @@ -32,9 +32,9 @@ ref resolveStoreConfig(StoreReference && storeURI) [&](const StoreReference::Auto &) -> ref { auto stateDir = getOr(params, "state", settings.nixStateDir); if (access(stateDir.c_str(), R_OK | W_OK) == 0) - return make_ref(params); + return make_ref(settings, params); else if (pathExists(settings.nixDaemonSocketFile)) - return make_ref(params); + return make_ref(settings, params); #ifdef __linux__ else if ( !pathExists(stateDir) && params.empty() && !isRootUser() && !getEnv("NIX_STORE_DIR").has_value() @@ -47,21 +47,21 @@ ref resolveStoreConfig(StoreReference && storeURI) try { createDirs(chrootStore); } catch (SystemError & e) { - return make_ref(params); + return make_ref(settings, 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("local", chrootStore, params); + return make_ref(settings, "local", chrootStore, params); } #endif else - return make_ref(params); + return make_ref(settings, 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); + return implem.parseConfig(settings, g.scheme, g.authority, params); throw Error("don't know how to open Nix store with scheme '%s'", g.scheme); }, @@ -74,9 +74,9 @@ ref resolveStoreConfig(StoreReference && storeURI) return storeConfig; } -std::list> getDefaultSubstituters() +std::list> getDefaultSubstituters(Settings & settings) { - static auto stores([]() { + static auto stores([&]() { std::list> stores; StringSet done; @@ -85,7 +85,7 @@ std::list> getDefaultSubstituters() if (!done.insert(uri).second) return; try { - stores.push_back(openStore(uri)); + stores.push_back(openStore(settings, uri)); } catch (Error & e) { logWarning(e.info()); } diff --git a/src/libstore/uds-remote-store.cc b/src/libstore/uds-remote-store.cc index 6106a99ce38..fa9b7d40372 100644 --- a/src/libstore/uds-remote-store.cc +++ b/src/libstore/uds-remote-store.cc @@ -20,11 +20,14 @@ namespace nix { UDSRemoteStoreConfig::UDSRemoteStoreConfig( - std::string_view scheme, std::string_view authority, const StoreReference::Params & params) - : Store::Config{params} - , LocalFSStore::Config{params} - , RemoteStore::Config{params} - , path{authority.empty() ? settings.nixDaemonSocketFile : authority} + nix::Settings & settings, + std::string_view scheme, + std::string_view authority, + const StoreReference::Params & params) + : Store::Config{settings, params} + , LocalFSStore::Config{settings, "", params} + , RemoteStore::Config{settings, params} + , path{authority.empty() ? settings.nixDaemonSocketFile : std::string{authority}} { if (uriSchemes().count(scheme) == 0) { throw UsageError("Scheme must be 'unix'"); @@ -42,8 +45,8 @@ std::string UDSRemoteStoreConfig::doc() // empty string will later default to the same nixDaemonSocketFile. Why // don't we just wire it all through? I believe there are cases where it // will live reload so we want to continue to account for that. -UDSRemoteStoreConfig::UDSRemoteStoreConfig(const Params & params) - : UDSRemoteStoreConfig(*uriSchemes().begin(), "", params) +UDSRemoteStoreConfig::UDSRemoteStoreConfig(nix::Settings & settings, const Params & params) + : UDSRemoteStoreConfig(settings, *uriSchemes().begin(), "", params) { } diff --git a/src/libstore/unix/build/derivation-builder.cc b/src/libstore/unix/build/derivation-builder.cc index 333c4dff8fe..3700b3efac6 100644 --- a/src/libstore/unix/build/derivation-builder.cc +++ b/src/libstore/unix/build/derivation-builder.cc @@ -19,6 +19,7 @@ #include "nix/store/globals.hh" #include "nix/store/build/derivation-env-desugar.hh" #include "nix/util/terminal.hh" +#include "nix/store/filetransfer.hh" #include @@ -232,7 +233,7 @@ class DerivationBuilderImpl : public DerivationBuilder, public DerivationBuilder */ virtual std::unique_ptr getBuildUser() { - return acquireUserLock(1, false); + return acquireUserLock(settings, 1, false); } /** @@ -437,7 +438,13 @@ class DerivationBuilderImpl : public DerivationBuilder, public DerivationBuilder }; void handleDiffHook( - uid_t uid, uid_t gid, const Path & tryA, const Path & tryB, const Path & drvPath, const Path & tmpDir) + const Settings & settings, + uid_t uid, + uid_t gid, + const Path & tryA, + const Path & tryB, + const Path & drvPath, + const Path & tmpDir) { auto & diffHookOpt = settings.diffHook.get(); if (diffHookOpt && settings.runDiffHook) { @@ -693,7 +700,7 @@ static bool checkNotWorldWritable(std::filesystem::path path) std::optional DerivationBuilderImpl::startBuild() { - if (useBuildUsers()) { + if (useBuildUsers(settings)) { if (!buildUser) buildUser = getBuildUser(); @@ -1251,6 +1258,7 @@ void DerivationBuilderImpl::runChild(RunChildArgs args) different uid and/or in a sandbox). */ BuiltinBuilderContext ctx{ .drv = drv, + .hashedMirrors = settings.hashedMirrors, .tmpDirInSandbox = tmpDirInSandbox(), #if NIX_WITH_AWS_AUTH .awsCredentials = args.awsCredentials, @@ -1259,12 +1267,12 @@ void DerivationBuilderImpl::runChild(RunChildArgs args) if (drv.isBuiltin() && drv.builder == "builtin:fetchurl") { try { - ctx.netrcData = readFile(settings.netrcFile); + ctx.netrcData = readFile(fileTransferSettings.netrcFile); } catch (SystemError &) { } try { - ctx.caFileData = readFile(settings.caFile); + ctx.caFileData = readFile(fileTransferSettings.caFile); } catch (SystemError &) { } } @@ -1448,7 +1456,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() rewriting doesn't contain a hard link to /etc/shadow or something like that. */ canonicalisePathMetaData( - actualPath, buildUser ? std::optional(buildUser->getUIDRange()) : std::nullopt, inodesSeen); + settings, actualPath, buildUser ? std::optional(buildUser->getUIDRange()) : std::nullopt, inodesSeen); bool discardReferences = false; if (auto udr = get(drvOptions.unsafeDiscardReferences, outputName)) { @@ -1566,7 +1574,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() /* FIXME: set proper permissions in restorePath() so we don't have to do another traversal. */ - canonicalisePathMetaData(actualPath, {}, inodesSeen); + canonicalisePathMetaData(settings, actualPath, {}, inodesSeen); } }; @@ -1719,7 +1727,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() /* FIXME: set proper permissions in restorePath() so we don't have to do another traversal. */ - canonicalisePathMetaData(actualPath, {}, inodesSeen); + canonicalisePathMetaData(settings, actualPath, {}, inodesSeen); /* Calculate where we'll move the output files. In the checking case we will leave leave them where they are, for now, rather than move to @@ -1770,6 +1778,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs() movePath(actualPath, dst); handleDiffHook( + settings, buildUser ? buildUser->getUID() : getuid(), buildUser ? buildUser->getGID() : getgid(), finalDestPath, @@ -1954,6 +1963,8 @@ std::unique_ptr makeDerivationBuilder( { bool useSandbox = false; + auto & settings = store.config->settings; + /* Are we doing a sandboxed build? */ { if (settings.sandboxMode == smEnabled) { diff --git a/src/libstore/unix/build/hook-instance.cc b/src/libstore/unix/build/hook-instance.cc index 83824b51f75..48e53e6e417 100644 --- a/src/libstore/unix/build/hook-instance.cc +++ b/src/libstore/unix/build/hook-instance.cc @@ -8,15 +8,15 @@ namespace nix { -HookInstance::HookInstance() +HookInstance::HookInstance(const Strings & buildHookArgs_) { - debug("starting build hook '%s'", concatStringsSep(" ", settings.buildHook.get())); + debug("starting build hook '%s'", concatStringsSep(" ", buildHookArgs_)); - auto buildHookArgs = settings.buildHook.get(); - - if (buildHookArgs.empty()) + if (buildHookArgs_.empty()) throw Error("'build-hook' setting is empty"); + auto buildHookArgs = buildHookArgs_; + std::filesystem::path buildHook = buildHookArgs.front(); buildHookArgs.pop_front(); diff --git a/src/libstore/unix/build/linux-derivation-builder.cc b/src/libstore/unix/build/linux-derivation-builder.cc index 95ef7eafe42..2564ff50173 100644 --- a/src/libstore/unix/build/linux-derivation-builder.cc +++ b/src/libstore/unix/build/linux-derivation-builder.cc @@ -23,7 +23,7 @@ namespace nix { -static void setupSeccomp() +static void setupSeccomp(const Settings & settings) { if (!settings.filterSyscalls) return; @@ -160,9 +160,9 @@ struct LinuxDerivationBuilder : virtual DerivationBuilderImpl void enterChroot() override { - setupSeccomp(); + setupSeccomp(store.config->settings); - linux::setPersonality(drv.platform); + linux::setPersonality(store.config->settings, drv.platform); } }; @@ -212,12 +212,12 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu std::unique_ptr getBuildUser() override { - return acquireUserLock(drvOptions.useUidRange(drv) ? 65536 : 1, true); + return acquireUserLock(store.config->settings, drvOptions.useUidRange(drv) ? 65536 : 1, true); } void prepareUser() override { - if ((buildUser && buildUser->getUIDCount() != 1) || settings.useCgroups) { + if ((buildUser && buildUser->getUIDCount() != 1) || store.config->settings.useCgroups) { experimentalFeatureSettings.require(Xp::Cgroups); /* If we're running from the daemon, then this will return the @@ -550,8 +550,8 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu if (pathExists(path)) ss.push_back(path); - if (settings.caFile != "") { - Path caFile = settings.caFile; + if (fileTransferSettings.caFile != "") { + Path caFile = fileTransferSettings.caFile; if (pathExists(caFile)) pathsInChroot.try_emplace("/etc/ssl/certs/ca-certificates.crt", canonPath(caFile, true), true); } diff --git a/src/libstore/unix/include/nix/store/build/hook-instance.hh b/src/libstore/unix/include/nix/store/build/hook-instance.hh index 7657d5dbd08..96d9c6dc282 100644 --- a/src/libstore/unix/include/nix/store/build/hook-instance.hh +++ b/src/libstore/unix/include/nix/store/build/hook-instance.hh @@ -50,7 +50,7 @@ struct HookInstance std::map activities; - HookInstance(); + HookInstance(const Strings & buildHookArgs); ~HookInstance(); }; diff --git a/src/libstore/unix/include/nix/store/user-lock.hh b/src/libstore/unix/include/nix/store/user-lock.hh index 828980d6fdb..24b3a9150fd 100644 --- a/src/libstore/unix/include/nix/store/user-lock.hh +++ b/src/libstore/unix/include/nix/store/user-lock.hh @@ -7,8 +7,17 @@ namespace nix { +class Settings; + struct UserLock { + const Settings & settings; + + UserLock(const Settings & settings) + : settings{settings} + { + } + virtual ~UserLock() {} /** @@ -36,8 +45,8 @@ struct UserLock * Acquire a user lock for a UID range of size `nrIds`. Note that this * may return nullptr if no user is available. */ -std::unique_ptr acquireUserLock(uid_t nrIds, bool useUserNamespace); +std::unique_ptr acquireUserLock(const Settings & settings, uid_t nrIds, bool useUserNamespace); -bool useBuildUsers(); +bool useBuildUsers(const Settings & settings); } // namespace nix diff --git a/src/libstore/unix/user-lock.cc b/src/libstore/unix/user-lock.cc index c5e6455e8d9..ddd736e9fc5 100644 --- a/src/libstore/unix/user-lock.cc +++ b/src/libstore/unix/user-lock.cc @@ -42,6 +42,11 @@ struct SimpleUserLock : UserLock gid_t gid; std::vector supplementaryGIDs; + SimpleUserLock(const Settings & settings) + : UserLock{settings} + { + } + uid_t getUID() override { assert(uid); @@ -64,7 +69,7 @@ struct SimpleUserLock : UserLock return supplementaryGIDs; } - static std::unique_ptr acquire() + static std::unique_ptr acquire(const Settings & settings) { assert(settings.buildUsersGroup != ""); createDirs(settings.nixStateDir + "/userpool"); @@ -100,7 +105,7 @@ struct SimpleUserLock : UserLock throw SysError("opening user lock '%s'", fnUserLock); if (lockFile(fd.get(), ltWrite, false)) { - auto lock = std::make_unique(); + auto lock = std::make_unique(settings); lock->fdUserLock = std::move(fd); lock->uid = pw->pw_uid; @@ -136,6 +141,11 @@ struct AutoUserLock : UserLock gid_t firstGid = 0; uid_t nrIds = 1; + AutoUserLock(const Settings & settings) + : UserLock{settings} + { + } + uid_t getUID() override { assert(firstUid); @@ -158,7 +168,7 @@ struct AutoUserLock : UserLock return {}; } - static std::unique_ptr acquire(uid_t nrIds, bool useUserNamespace) + static std::unique_ptr acquire(const Settings & settings, uid_t nrIds, bool useUserNamespace) { #if !defined(__linux__) useUserNamespace = false; @@ -193,7 +203,7 @@ struct AutoUserLock : UserLock if (pw) throw Error("auto-allocated UID %d clashes with existing user account '%s'", firstUid, pw->pw_name); - auto lock = std::make_unique(); + auto lock = std::make_unique(settings); lock->fdUserLock = std::move(fd); lock->firstUid = firstUid; if (useUserNamespace) @@ -214,15 +224,15 @@ struct AutoUserLock : UserLock } }; -std::unique_ptr acquireUserLock(uid_t nrIds, bool useUserNamespace) +std::unique_ptr acquireUserLock(const Settings & settings, uid_t nrIds, bool useUserNamespace) { if (settings.autoAllocateUids) - return AutoUserLock::acquire(nrIds, useUserNamespace); + return AutoUserLock::acquire(settings, nrIds, useUserNamespace); else - return SimpleUserLock::acquire(); + return SimpleUserLock::acquire(settings); } -bool useBuildUsers() +bool useBuildUsers(const Settings & settings) { #ifdef __linux__ static bool b = (settings.buildUsersGroup != "" || settings.autoAllocateUids) && isRootUser(); diff --git a/src/nix/add-to-store.cc b/src/nix/add-to-store.cc index e87f4954607..d72545f8fbf 100644 --- a/src/nix/add-to-store.cc +++ b/src/nix/add-to-store.cc @@ -40,8 +40,10 @@ struct CmdAddToStore : MixDryRun, StoreCommand auto sourcePath = PosixSourceAccessor::createAtRoot(makeParentCanonical(path)); - auto storePath = dryRun ? store->computeStorePath(*namePart, sourcePath, caMethod, hashAlgo, {}).first - : store->addToStoreSlow(*namePart, sourcePath, caMethod, hashAlgo, {}).path; + auto storePath = + dryRun + ? store->computeStorePath(store->config.settings, *namePart, sourcePath, caMethod, hashAlgo, {}).first + : store->addToStoreSlow(*namePart, sourcePath, caMethod, hashAlgo, {}).path; logger->cout("%s", store->printStorePath(storePath)); } diff --git a/src/nix/build-remote/build-remote.cc b/src/nix/build-remote/build-remote.cc index f62712d30ea..c828e4572f7 100644 --- a/src/nix/build-remote/build-remote.cc +++ b/src/nix/build-remote/build-remote.cc @@ -81,7 +81,7 @@ static int main_build_remote(int argc, char ** argv) initPlugins(); - auto store = openStore(); + auto store = openStore(settings); /* It would be more appropriate to use $XDG_RUNTIME_DIR, since that gets cleared on reboot, but it wouldn't work on macOS. */ @@ -94,7 +94,7 @@ static int main_build_remote(int argc, char ** argv) std::shared_ptr sshStore; AutoCloseFD bestSlotLock; - auto machines = getMachines(); + auto machines = getMachines(settings); debug("got %d remote builders", machines.size()); if (machines.empty()) { @@ -234,7 +234,7 @@ static int main_build_remote(int argc, char ** argv) Activity act(*logger, lvlTalkative, actUnknown, fmt("connecting to '%s'", storeUri)); - sshStore = bestMachine->openStore(); + sshStore = bestMachine->openStore(settings); sshStore->connect(); } catch (std::exception & e) { auto msg = chomp(drainFD(5, false)); diff --git a/src/nix/flake-prefetch-inputs.cc b/src/nix/flake-prefetch-inputs.cc index 4ea6342c369..a9d73dc0d3a 100644 --- a/src/nix/flake-prefetch-inputs.cc +++ b/src/nix/flake-prefetch-inputs.cc @@ -1,10 +1,11 @@ -#include "flake-command.hh" -#include "nix/fetchers/fetch-to-store.hh" +#include + #include "nix/util/thread-pool.hh" -#include "nix/store/filetransfer.hh" #include "nix/util/exit.hh" +#include "nix/store/filetransfer.hh" +#include "nix/fetchers/fetch-to-store.hh" -#include +#include "flake-command.hh" using namespace nix; using namespace nix::flake; diff --git a/src/nix/flake.cc b/src/nix/flake.cc index be19b5317dd..cb1a77d5be0 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -1126,7 +1126,7 @@ struct CmdFlakeArchive : FlakeCommand, MixJSON, MixDryRun, MixNoCheckSigs } if (!dryRun && !dstUri.empty()) { - ref dstStore = dstUri.empty() ? openStore() : openStore(dstUri); + ref dstStore = dstUri.empty() ? openStore(settings) : openStore(settings, dstUri); copyPaths(*store, *dstStore, sources, NoRepair, checkSigs, substitute); } diff --git a/src/nix/log.cc b/src/nix/log.cc index 150b4b3711a..4bdc4fedd56 100644 --- a/src/nix/log.cc +++ b/src/nix/log.cc @@ -30,7 +30,7 @@ struct CmdLog : InstallableCommand { settings.readOnlyMode = true; - auto subs = getDefaultSubstituters(); + auto subs = getDefaultSubstituters(settings); subs.push_front(store); diff --git a/src/nix/main.cc b/src/nix/main.cc index 93c1dc42a38..88d043cc9e2 100644 --- a/src/nix/main.cc +++ b/src/nix/main.cc @@ -246,7 +246,7 @@ static void showHelp(std::vector subcommand, NixArgs & toplevel) evalSettings.restrictEval = true; evalSettings.pureEval = true; - EvalState state({}, openStore("dummy://"), fetchSettings, evalSettings); + EvalState state({}, openStore(settings, "dummy://"), fetchSettings, evalSettings); auto vGenerateManpage = state.allocValue(); state.eval( @@ -447,7 +447,7 @@ void mainWrapped(int argc, char ** argv) Xp::FetchTree, }; evalSettings.pureEval = false; - EvalState state({}, openStore("dummy://"), fetchSettings, evalSettings); + EvalState state({}, openStore(settings, "dummy://"), fetchSettings, evalSettings); auto builtinsJson = nlohmann::json::object(); for (auto & builtinPtr : state.getBuiltins().attrs()->lexicographicOrder(state.symbols)) { auto & builtin = *builtinPtr; diff --git a/src/nix/make-content-addressed.cc b/src/nix/make-content-addressed.cc index a54729c4542..6a8ecb301c3 100644 --- a/src/nix/make-content-addressed.cc +++ b/src/nix/make-content-addressed.cc @@ -30,7 +30,7 @@ struct CmdMakeContentAddressed : virtual CopyCommand, virtual StorePathsCommand, void run(ref srcStore, StorePaths && storePaths) override { - auto dstStore = dstUri.empty() ? openStore() : openStore(dstUri); + auto dstStore = dstUri.empty() ? openStore(settings) : openStore(settings, dstUri); auto remappings = makeContentAddressed(*srcStore, *dstStore, StorePathSet(storePaths.begin(), storePaths.end())); diff --git a/src/nix/nix-build/nix-build.cc b/src/nix/nix-build/nix-build.cc index a21d1a56549..2257f9b4437 100644 --- a/src/nix/nix-build/nix-build.cc +++ b/src/nix/nix-build/nix-build.cc @@ -312,8 +312,8 @@ static void main_nix_build(int argc, char ** argv) if (packages && fromArgs) throw UsageError("'-p' and '-E' are mutually exclusive"); - auto store = openStore(); - auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store; + auto store = openStore(settings); + auto evalStore = myArgs.evalStoreUrl ? openStore(settings, *myArgs.evalStoreUrl) : store; auto state = std::make_unique(myArgs.lookupPath, evalStore, fetchSettings, evalSettings, store); state->repair = myArgs.repair; diff --git a/src/nix/nix-channel/nix-channel.cc b/src/nix/nix-channel/nix-channel.cc index 6d9a0ea5898..6047fefb72c 100644 --- a/src/nix/nix-channel/nix-channel.cc +++ b/src/nix/nix-channel/nix-channel.cc @@ -82,7 +82,7 @@ static void update(const StringSet & channelNames) { readChannels(); - auto store = openStore(); + auto store = openStore(settings); auto [fd, unpackChannelPath] = createTempFile(); writeFull( @@ -183,10 +183,10 @@ static int main_nix_channel(int argc, char ** argv) // Figure out the name of the `.nix-channels' file to use auto home = getHome(); channelsList = settings.useXDGBaseDirectories ? createNixStateDir() + "/channels" : home + "/.nix-channels"; - nixDefExpr = getNixDefExpr(); + nixDefExpr = getNixDefExpr(settings); // Figure out the name of the channels profile. - profile = profilesDir() + "/channels"; + profile = profilesDir(settings) + "/channels"; createDirs(dirOf(profile)); enum { cNone, cAdd, cRemove, cList, cUpdate, cListGenerations, cRollback } cmd = cNone; diff --git a/src/nix/nix-collect-garbage/nix-collect-garbage.cc b/src/nix/nix-collect-garbage/nix-collect-garbage.cc index 29ca17a5de2..5acdbb0acd8 100644 --- a/src/nix/nix-collect-garbage/nix-collect-garbage.cc +++ b/src/nix/nix-collect-garbage/nix-collect-garbage.cc @@ -89,9 +89,9 @@ static int main_nix_collect_garbage(int argc, char ** argv) if (removeOld) { std::set dirsToClean = { - profilesDir(), + profilesDir(settings), std::filesystem::path{settings.nixStateDir} / "profiles", - getDefaultProfile().parent_path(), + getDefaultProfile(settings).parent_path(), }; for (auto & dir : dirsToClean) removeOldGenerations(dir); @@ -99,7 +99,7 @@ static int main_nix_collect_garbage(int argc, char ** argv) // Run the actual garbage collector. if (!dryRun) { - auto store = openStore(); + auto store = openStore(settings); auto & gcStore = require(*store); options.action = GCOptions::gcDeleteDead; GCResults results; diff --git a/src/nix/nix-copy-closure/nix-copy-closure.cc b/src/nix/nix-copy-closure/nix-copy-closure.cc index 87d0f65905b..ad0464f7d3b 100644 --- a/src/nix/nix-copy-closure/nix-copy-closure.cc +++ b/src/nix/nix-copy-closure/nix-copy-closure.cc @@ -49,8 +49,8 @@ static int main_nix_copy_closure(int argc, char ** argv) throw UsageError("no host name specified"); auto remoteUri = "ssh://" + sshHost + (gzip ? "?compress=true" : ""); - auto to = toMode ? openStore(remoteUri) : openStore(); - auto from = toMode ? openStore() : openStore(remoteUri); + auto to = toMode ? openStore(settings, remoteUri) : openStore(settings); + auto from = toMode ? openStore(settings) : openStore(settings, remoteUri); RealisedPath::Set storePaths2; for (auto & path : storePaths) diff --git a/src/nix/nix-env/nix-env.cc b/src/nix/nix-env/nix-env.cc index edfccffa610..1095c188235 100644 --- a/src/nix/nix-env/nix-env.cc +++ b/src/nix/nix-env/nix-env.cc @@ -1407,14 +1407,14 @@ static int main_nix_env(int argc, char ** argv) globals.instSource.type = srcUnknown; globals.instSource.systemFilter = "*"; - std::filesystem::path nixExprPath = getNixDefExpr(); + std::filesystem::path nixExprPath = getNixDefExpr(settings); if (!pathExists(nixExprPath)) { try { createDirs(nixExprPath); - replaceSymlink(defaultChannelsDir(), nixExprPath / "channels"); + replaceSymlink(defaultChannelsDir(settings), nixExprPath / "channels"); if (!isRootUser()) - replaceSymlink(rootChannelsDir(), nixExprPath / "channels_root"); + replaceSymlink(rootChannelsDir(settings), nixExprPath / "channels_root"); } catch (std::filesystem::filesystem_error &) { } catch (Error &) { } @@ -1505,7 +1505,7 @@ static int main_nix_env(int argc, char ** argv) if (!op) throw UsageError("no operation specified"); - auto store = openStore(); + auto store = openStore(settings); globals.state = std::shared_ptr(new EvalState(myArgs.lookupPath, store, fetchSettings, evalSettings)); @@ -1521,7 +1521,7 @@ static int main_nix_env(int argc, char ** argv) globals.profile = getEnv("NIX_PROFILE").value_or(""); if (globals.profile == "") - globals.profile = getDefaultProfile().string(); + globals.profile = getDefaultProfile(settings).string(); op(globals, std::move(opFlags), std::move(opArgs)); diff --git a/src/nix/nix-instantiate/nix-instantiate.cc b/src/nix/nix-instantiate/nix-instantiate.cc index 3d5c3e26a46..ddaa3d98bd2 100644 --- a/src/nix/nix-instantiate/nix-instantiate.cc +++ b/src/nix/nix-instantiate/nix-instantiate.cc @@ -166,8 +166,8 @@ static int main_nix_instantiate(int argc, char ** argv) if (evalOnly && !wantsReadWrite) settings.readOnlyMode = true; - auto store = openStore(); - auto evalStore = myArgs.evalStoreUrl ? openStore(*myArgs.evalStoreUrl) : store; + auto store = openStore(settings); + auto evalStore = myArgs.evalStoreUrl ? openStore(settings, *myArgs.evalStoreUrl) : store; auto state = std::make_unique(myArgs.lookupPath, evalStore, fetchSettings, evalSettings, store); state->repair = myArgs.repair; diff --git a/src/nix/nix-store/nix-store.cc b/src/nix/nix-store/nix-store.cc index 3798c7fa015..9725452c61f 100644 --- a/src/nix/nix-store/nix-store.cc +++ b/src/nix/nix-store/nix-store.cc @@ -599,7 +599,7 @@ static void registerValidity(bool reregister, bool hashGiven, bool canonicalise) #ifdef _WIN32 // TODO implement on Windows throw UnimplementedError("file attribute canonicalisation Is not implemented on Windows"); #else - canonicalisePathMetaData(store->printStorePath(info->path), {}); + canonicalisePathMetaData(settings, store->printStorePath(info->path), {}); #endif if (!hashGiven) { HashResult hash = hashPath( @@ -1234,7 +1234,7 @@ static int main_nix_store(int argc, char ** argv) throw UsageError("no operation specified"); if (op != opDump && op != opRestore) /* !!! hack */ - store = openStore(); + store = openStore(settings); op(std::move(opFlags), std::move(opArgs)); diff --git a/src/nix/prefetch.cc b/src/nix/prefetch.cc index d494b098686..6eb2f306858 100644 --- a/src/nix/prefetch.cc +++ b/src/nix/prefetch.cc @@ -202,7 +202,7 @@ static int main_nix_prefetch_url(int argc, char ** argv) setLogFormat("bar"); - auto store = openStore(); + auto store = openStore(settings); auto state = std::make_unique(myArgs.lookupPath, store, fetchSettings, evalSettings); Bindings & autoArgs = *myArgs.getAutoArgs(*state); diff --git a/src/nix/repl.cc b/src/nix/repl.cc index 19f02e759c5..016c2e45649 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -99,7 +99,7 @@ struct CmdRepl : RawInstallablesCommand } return values; }; - auto repl = AbstractNixRepl::create(lookupPath, openStore(), state, getValues, runNix); + auto repl = AbstractNixRepl::create(lookupPath, openStore(settings), state, getValues, runNix); repl->autoArgs = getAutoArgs(*repl->state); repl->initEnv(); repl->mainLoop(); diff --git a/src/nix/run.cc b/src/nix/run.cc index 324b736a6a5..565029733d5 100644 --- a/src/nix/run.cc +++ b/src/nix/run.cc @@ -96,7 +96,7 @@ void execProgramInStore( #ifdef __linux__ if (system) - linux::setPersonality(*system); + linux::setPersonality(store->config.settings, *system); #endif if (useLookupPath == UseLookupPath::Use) { @@ -251,7 +251,7 @@ void chrootHelper(int argc, char ** argv) # ifdef __linux__ if (system != "") - linux::setPersonality(system); + linux::setPersonality(settings, system); # endif execvp(cmd.c_str(), stringsToCharPtrs(args).data()); diff --git a/src/nix/sigs.cc b/src/nix/sigs.cc index e82f0d284b9..edaa77719bc 100644 --- a/src/nix/sigs.cc +++ b/src/nix/sigs.cc @@ -44,7 +44,7 @@ struct CmdCopySigs : StorePathsCommand // FIXME: factor out commonality with MixVerify. std::vector> substituters; for (auto & s : substituterUris) - substituters.push_back(openStore(s)); + substituters.push_back(openStore(settings, s)); ThreadPool pool{fileTransferSettings.httpConnections}; diff --git a/src/nix/unix/daemon.cc b/src/nix/unix/daemon.cc index 33ad8757a51..42590fff300 100644 --- a/src/nix/unix/daemon.cc +++ b/src/nix/unix/daemon.cc @@ -252,7 +252,7 @@ static ref openUncachedStore() Store::Config::Params params; // FIXME: get params from somewhere // Disable caching since the client already does that. params["path-info-cache-size"] = "0"; - return openStore(settings.storeUri, params); + return openStore(settings, settings.storeUri, params); } /** diff --git a/src/nix/verify.cc b/src/nix/verify.cc index 309d19a1d4e..870b7e4e34c 100644 --- a/src/nix/verify.cc +++ b/src/nix/verify.cc @@ -65,9 +65,9 @@ struct CmdVerify : StorePathsCommand { std::vector> substituters; for (auto & s : substituterUris) - substituters.push_back(openStore(s)); + substituters.push_back(openStore(settings, s)); - auto publicKeys = getDefaultPublicKeys(); + auto publicKeys = getDefaultPublicKeys(settings); Activity act(*logger, actVerifyPaths); diff --git a/src/perl/lib/Nix/Store.xs b/src/perl/lib/Nix/Store.xs index 93e9f0f9541..789220f4bf3 100644 --- a/src/perl/lib/Nix/Store.xs +++ b/src/perl/lib/Nix/Store.xs @@ -13,6 +13,9 @@ #include "nix/util/posix-source-accessor.hh" #include "nix/store/export-import.hh" +// TODO get rid of this, and stop relying on global store settings. +#include "nix/main/shared.hh" + #include #include @@ -62,13 +65,13 @@ StoreWrapper::new(char * s = nullptr) libStoreInitialized = true; } if (items == 1) { - _store = openStore(); + _store = openStore(settings); RETVAL = new StoreWrapper { .store = ref{_store} }; } else { RETVAL = new StoreWrapper { - .store = openStore(s) + .store = openStore(settings, s) }; } } catch (Error & e) { diff --git a/src/perl/meson.build b/src/perl/meson.build index 59f2a66b838..56d121e552d 100644 --- a/src/perl/meson.build +++ b/src/perl/meson.build @@ -77,6 +77,10 @@ libsodium_dep = dependency('libsodium') nix_store_dep = dependency('nix-store') +# TEMP hack to get global settings, until we extend Perl API with +# explicit settings loading or similar. +nix_main_dep = dependency('nix-main') + # Finding Perl Headers is a pain. as they do not have # pkgconfig available, are not in a standard location, @@ -170,6 +174,7 @@ nix_perl_store_dep_list = [ curl_dep, libsodium_dep, nix_store_dep, + nix_main_dep, ] # # build diff --git a/src/perl/package.nix b/src/perl/package.nix index 864558ec855..42ef9e62ddf 100644 --- a/src/perl/package.nix +++ b/src/perl/package.nix @@ -6,6 +6,7 @@ perl, perlPackages, nix-store, + nix-main, version, curl, bzip2, @@ -45,6 +46,7 @@ perl.pkgs.toPerlModule ( buildInputs = [ nix-store + nix-main bzip2 libsodium ]; diff --git a/tests/functional/test-libstoreconsumer/main.cc b/tests/functional/test-libstoreconsumer/main.cc index 6cfe50047af..625fa7d7f6d 100644 --- a/tests/functional/test-libstoreconsumer/main.cc +++ b/tests/functional/test-libstoreconsumer/main.cc @@ -17,7 +17,9 @@ int main(int argc, char ** argv) initLibStore(); - auto store = nix::openStore(); + Settings settings; + + auto store = nix::openStore(settings); // build the derivation