From 95a9a4cece71a7676bf7526f229370420531dbb0 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Sun, 17 Nov 2024 14:43:57 +0100 Subject: [PATCH] libstore: don't derive store classes from their configs the very slight speedup in config setting access is not worth the maintenance overhead of conflating concers like this. the virtual inheritance scheme used for configs requires too much duplication of base class constructor arguments to be worth doing. perhaps we should get rid of all virtual inheritance of data-membered bases? Change-Id: I4acf5ceaedb4ed7476efe1114c2e065ec72d2c6d --- lix/legacy/build-remote.cc | 4 +- lix/legacy/nix-build.cc | 2 +- lix/libexpr/builtin-constants/storeDir.md | 2 +- lix/libstore/binary-cache-store.cc | 45 ++++++----- lix/libstore/binary-cache-store.hh | 8 +- lix/libstore/build/derivation-goal.cc | 2 +- lix/libstore/build/local-derivation-goal.cc | 43 ++++++----- lix/libstore/build/substitution-goal.cc | 12 ++- lix/libstore/dummy-store.cc | 17 +++-- lix/libstore/filetransfer.cc | 2 +- lix/libstore/gc.cc | 31 ++++---- lix/libstore/http-binary-cache-store.cc | 24 +++--- lix/libstore/legacy-ssh-store.cc | 41 ++++++---- lix/libstore/local-binary-cache-store.cc | 20 ++--- lix/libstore/local-fs-store.cc | 13 +--- lix/libstore/local-fs-store.hh | 10 +-- lix/libstore/local-store.cc | 85 ++++++++++----------- lix/libstore/local-store.hh | 14 ++-- lix/libstore/machines.cc | 2 +- lix/libstore/optimise-store.cc | 12 ++- lix/libstore/parsed-derivations.cc | 2 +- lix/libstore/path.cc | 6 +- lix/libstore/platform.cc | 2 +- lix/libstore/platform/darwin.cc | 2 +- lix/libstore/platform/darwin.hh | 13 +--- lix/libstore/platform/fallback.hh | 14 +--- lix/libstore/platform/freebsd.cc | 2 +- lix/libstore/platform/freebsd.hh | 14 +--- lix/libstore/platform/linux.cc | 4 +- lix/libstore/platform/linux.hh | 14 +--- lix/libstore/remote-store.cc | 9 +-- lix/libstore/remote-store.hh | 8 +- lix/libstore/s3-binary-cache-store.cc | 56 +++++++------- lix/libstore/s3-binary-cache-store.hh | 2 +- lix/libstore/ssh-store.cc | 30 ++++---- lix/libstore/store-api.cc | 43 ++++++----- lix/libstore/store-api.hh | 27 ++++--- lix/libstore/uds-remote-store.cc | 17 ++--- lix/libstore/uds-remote-store.hh | 12 ++- lix/nix/daemon.cc | 2 +- lix/nix/run.cc | 10 ++- tests/unit/libstore/path.cc | 2 +- 42 files changed, 356 insertions(+), 324 deletions(-) diff --git a/lix/legacy/build-remote.cc b/lix/legacy/build-remote.cc index 6d0ecaaa2..7e659ebf8 100644 --- a/lix/legacy/build-remote.cc +++ b/lix/legacy/build-remote.cc @@ -51,7 +51,7 @@ static AutoCloseFD openSlotLock(const Machine & m, uint64_t slot) static bool allSupportedLocally(Store & store, const std::set& requiredFeatures) { for (auto & feature : requiredFeatures) - if (!store.systemFeatures.get().count(feature)) return false; + if (!store.config().systemFeatures.get().count(feature)) return false; return true; } @@ -92,7 +92,7 @@ static int main_build_remote(int argc, char * * argv) that gets cleared on reboot, but it wouldn't work on macOS. */ auto currentLoadName = "/current-load"; if (auto localStore = store.dynamic_pointer_cast()) - currentLoad = std::string { localStore->stateDir } + currentLoadName; + currentLoad = std::string { localStore->config().stateDir } + currentLoadName; else currentLoad = settings.nixStateDir + currentLoadName; diff --git a/lix/legacy/nix-build.cc b/lix/legacy/nix-build.cc index 451bf66c0..30b271bbd 100644 --- a/lix/legacy/nix-build.cc +++ b/lix/legacy/nix-build.cc @@ -430,7 +430,7 @@ static void main_nix_build(int argc, char * * argv) // Don't use defaultTempDir() here! We want to preserve the user's TMPDIR for the shell env["NIX_BUILD_TOP"] = env["TMPDIR"] = env["TEMPDIR"] = env["TMP"] = env["TEMP"] = getEnvNonEmpty("TMPDIR").value_or("/tmp"); - env["NIX_STORE"] = store->storeDir; + env["NIX_STORE"] = store->config().storeDir; env["NIX_BUILD_CORES"] = std::to_string(settings.buildCores); auto passAsFile = tokenizeString(getOr(drv.env, "passAsFile", "")); diff --git a/lix/libexpr/builtin-constants/storeDir.md b/lix/libexpr/builtin-constants/storeDir.md index d37530bdd..ab4800cf0 100644 --- a/lix/libexpr/builtin-constants/storeDir.md +++ b/lix/libexpr/builtin-constants/storeDir.md @@ -1,7 +1,7 @@ --- name: storeDir type: string -constructorArgs: [store->storeDir] +constructorArgs: [store->config().storeDir] --- Logical file system location of the [Nix store](@docroot@/glossary.md#gloss-store) currently in use. diff --git a/lix/libstore/binary-cache-store.cc b/lix/libstore/binary-cache-store.cc index 895629210..4e174e5a9 100644 --- a/lix/libstore/binary-cache-store.cc +++ b/lix/libstore/binary-cache-store.cc @@ -22,12 +22,10 @@ namespace nix { -BinaryCacheStore::BinaryCacheStore(const Params & params) - : BinaryCacheStoreConfig(params) - , Store(params) +BinaryCacheStore::BinaryCacheStore(const BinaryCacheStoreConfig & config) { - if (secretKeyFile != "") - secretKey = std::unique_ptr(new SecretKey(readFile(secretKeyFile))); + if (config.secretKeyFile != "") + secretKey = std::unique_ptr(new SecretKey(readFile(config.secretKeyFile))); StringSink sink; sink << narVersionMagic1; @@ -40,7 +38,7 @@ void BinaryCacheStore::init() auto cacheInfo = getFileContents(cacheInfoFile); if (!cacheInfo) { - upsertFile(cacheInfoFile, "StoreDir: " + storeDir + "\n", "text/x-nix-cache-info"); + upsertFile(cacheInfoFile, "StoreDir: " + config().storeDir + "\n", "text/x-nix-cache-info"); } else { for (auto & line : tokenizeString(*cacheInfo, "\n")) { size_t colon= line.find(':'); @@ -48,13 +46,13 @@ void BinaryCacheStore::init() auto name = line.substr(0, colon); auto value = trim(line.substr(colon + 1, std::string::npos)); if (name == "StoreDir") { - if (value != storeDir) + if (value != config().storeDir) throw Error("binary cache '%s' is for Nix stores with prefix '%s', not '%s'", - getUri(), value, storeDir); + getUri(), value, config().storeDir); } else if (name == "WantMassQuery") { - wantMassQuery.setDefault(value == "1"); + config().wantMassQuery.setDefault(value == "1"); } else if (name == "Priority") { - priority.setDefault(std::stoi(value)); + config().priority.setDefault(std::stoi(value)); } } } @@ -134,7 +132,12 @@ ref BinaryCacheStore::addToStoreCommon( { FdSink fileSink(fdTemp.get()); TeeSink teeSinkCompressed { fileSink, fileHashSink }; - auto compressionSink = makeCompressionSink(compression, teeSinkCompressed, parallelCompression, compressionLevel); + auto compressionSink = makeCompressionSink( + config().compression, + teeSinkCompressed, + config().parallelCompression, + config().compressionLevel + ); TeeSink teeSinkUncompressed { *compressionSink, narHashSink }; TeeSource teeSource { narSource, teeSinkUncompressed }; narAccessor = makeNarAccessor(teeSource); @@ -146,17 +149,17 @@ ref BinaryCacheStore::addToStoreCommon( auto info = mkInfo(narHashSink.finish()); auto narInfo = make_ref(info); - narInfo->compression = compression; + narInfo->compression = config().compression; auto [fileHash, fileSize] = fileHashSink.finish(); narInfo->fileHash = fileHash; narInfo->fileSize = fileSize; narInfo->url = "nar/" + narInfo->fileHash->to_string(Base::Base32, false) + ".nar" - + (compression == "xz" ? ".xz" : - compression == "bzip2" ? ".bz2" : - compression == "zstd" ? ".zst" : - compression == "lzip" ? ".lzip" : - compression == "lz4" ? ".lz4" : - compression == "br" ? ".br" : + + (config().compression == "xz" ? ".xz" : + config().compression == "bzip2" ? ".bz2" : + config().compression == "zstd" ? ".zst" : + config().compression == "lzip" ? ".lzip" : + config().compression == "lz4" ? ".lz4" : + config().compression == "br" ? ".br" : ""); auto duration = std::chrono::duration_cast(now2 - now1).count(); @@ -178,7 +181,7 @@ ref BinaryCacheStore::addToStoreCommon( /* Optionally write a JSON file containing a listing of the contents of the NAR. */ - if (writeNARListing) { + if (config().writeNARListing) { nlohmann::json j = { {"version", 1}, {"root", listNar(ref(narAccessor), "", true)}, @@ -190,7 +193,7 @@ ref BinaryCacheStore::addToStoreCommon( /* Optionally maintain an index of DWARF debug info files consisting of JSON files named 'debuginfo/' that specify the NAR file and member containing the debug info. */ - if (writeDebugInfo) { + if (config().writeDebugInfo) { std::string buildIdDir = "/lib/debug/.build-id"; @@ -470,7 +473,7 @@ void BinaryCacheStore::registerDrvOutput(const Realisation& info) { ref BinaryCacheStore::getFSAccessor() { - return make_ref(ref(shared_from_this()), localNarCache); + return make_ref(ref(shared_from_this()), config().localNarCache); } void BinaryCacheStore::addSignatures(const StorePath & storePath, const StringSet & sigs) diff --git a/lix/libstore/binary-cache-store.hh b/lix/libstore/binary-cache-store.hh index b58c391be..538da50b6 100644 --- a/lix/libstore/binary-cache-store.hh +++ b/lix/libstore/binary-cache-store.hh @@ -51,8 +51,7 @@ struct BinaryCacheStoreConfig : virtual StoreConfig * @note subclasses must implement at least one of the two * virtual getFile() methods. */ -class BinaryCacheStore : public virtual BinaryCacheStoreConfig, - public virtual Store, +class BinaryCacheStore : public virtual Store, public virtual LogStore { @@ -65,10 +64,13 @@ protected: // The prefix under which realisation infos will be stored const std::string realisationsPrefix = "realisations"; - BinaryCacheStore(const Params & params); + BinaryCacheStore(const BinaryCacheStoreConfig & config); public: + BinaryCacheStoreConfig & config() override = 0; + const BinaryCacheStoreConfig & config() const override = 0; + virtual bool fileExists(const std::string & path) = 0; virtual void upsertFile(const std::string & path, diff --git a/lix/libstore/build/derivation-goal.cc b/lix/libstore/build/derivation-goal.cc index edea769ac..5ea5e50c2 100644 --- a/lix/libstore/build/derivation-goal.cc +++ b/lix/libstore/build/derivation-goal.cc @@ -1316,7 +1316,7 @@ Path DerivationGoal::openLogFile() /* Create a log file. */ Path logDir; if (auto localStore = dynamic_cast(&worker.store)) - logDir = localStore->logDir; + logDir = localStore->config().logDir; else logDir = settings.nixLogDir; Path dir = fmt("%s/%s/%s/", logDir, LocalFSStore::drvsLogDir, baseName.substr(0, 2)); diff --git a/lix/libstore/build/local-derivation-goal.cc b/lix/libstore/build/local-derivation-goal.cc index dc86f1315..d9d08082e 100644 --- a/lix/libstore/build/local-derivation-goal.cc +++ b/lix/libstore/build/local-derivation-goal.cc @@ -200,7 +200,7 @@ retry: } auto & localStore = getLocalStore(); - if (localStore.storeDir != localStore.realStoreDir.get()) { + if (localStore.config().storeDir != localStore.config().realStoreDir.get()) { #if __linux__ useChroot = true; #else @@ -355,7 +355,7 @@ bool LocalDerivationGoal::cleanupDecideWhetherDiskFull() auto & localStore = getLocalStore(); uint64_t required = 8ULL * 1024 * 1024; // FIXME: make configurable struct statvfs st; - if (statvfs(localStore.realStoreDir.get().c_str(), &st) == 0 && + if (statvfs(localStore.config().realStoreDir.get().c_str(), &st) == 0 && (uint64_t) st.f_bavail * st.f_bsize < required) diskFull = true; if (statvfs(tmpDir.c_str(), &st) == 0 && @@ -475,7 +475,7 @@ kj::Promise> LocalDerivationGoal::startBuilder() concatStringsSep(", ", parsedDrv->getRequiredSystemFeatures()), worker.store.printStorePath(drvPath), settings.thisSystem, - concatStringsSep(", ", worker.store.systemFeatures), + concatStringsSep(", ", worker.store.config().systemFeatures), Uncolored(addendum)) }); } @@ -596,7 +596,7 @@ kj::Promise> LocalDerivationGoal::startBuilder() else pathsInChroot[i.substr(0, p)] = {i.substr(p + 1), optional}; } - if (worker.store.storeDir.starts_with(tmpDirInSandbox)) + if (worker.store.config().storeDir.starts_with(tmpDirInSandbox)) { throw Error("`sandbox-build-dir` must not contain the storeDir"); } @@ -872,7 +872,7 @@ void LocalDerivationGoal::initEnv() shouldn't care, but this is useful for purity checking (e.g., the compiler or linker might only want to accept paths to files in the store or in the build directory). */ - env["NIX_STORE"] = worker.store.storeDir; + env["NIX_STORE"] = worker.store.config().storeDir; /* The maximum number of cores to utilize for parallel building. */ env["NIX_BUILD_CORES"] = fmt("%d", settings.buildCores); @@ -975,23 +975,25 @@ struct RestrictedStoreConfig : virtual LocalFSStoreConfig /* A wrapper around LocalStore that only allows building/querying of paths that are in the input closures of the build or were added via recursive Nix calls. */ -struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual IndirectRootStore, public virtual GcStore +struct RestrictedStore : public virtual IndirectRootStore, public virtual GcStore { + RestrictedStoreConfig config_; + + RestrictedStoreConfig & config() override { return config_; } + const RestrictedStoreConfig & config() const override { return config_; } + ref next; LocalDerivationGoal & goal; - RestrictedStore(const Params & params, ref next, LocalDerivationGoal & goal) - : StoreConfig(params) - , LocalFSStoreConfig(params) - , RestrictedStoreConfig(params) - , Store(params) - , LocalFSStore(params) + RestrictedStore(RestrictedStoreConfig config, ref next, LocalDerivationGoal & goal) + : Store(config) + , config_(std::move(config)) , next(next), goal(goal) { } Path getRealStoreDir() override - { return next->realStoreDir; } + { return next->config().realStoreDir; } std::string getUri() override { return next->getUri(); } @@ -1203,10 +1205,10 @@ void LocalDerivationGoal::startDaemon() { experimentalFeatureSettings.require(Xp::RecursiveNix); - Store::Params params; + StoreConfig::Params params; params["path-info-cache-size"] = "0"; - params["store"] = worker.store.storeDir; - if (auto & optRoot = getLocalStore().rootDir.get()) + params["store"] = worker.store.config().storeDir; + if (auto & optRoot = getLocalStore().config().rootDir.get()) params["root"] = *optRoot; params["state"] = "/no-such-path"; params["log"] = "/no-such-path"; @@ -1444,7 +1446,7 @@ void LocalDerivationGoal::runChild() Marking chrootRootDir as MS_SHARED causes pivot_root() to fail with EINVAL. Don't know why. */ - Path chrootStoreDir = chrootRootDir + worker.store.storeDir; + Path chrootStoreDir = chrootRootDir + worker.store.config().storeDir; if (mount(chrootStoreDir.c_str(), chrootStoreDir.c_str(), 0, MS_BIND, 0) == -1) throw SysError("unable to bind mount the Nix store", chrootStoreDir); @@ -1459,8 +1461,11 @@ void LocalDerivationGoal::runChild() createDirs(chrootRootDir + "/dev/shm"); createDirs(chrootRootDir + "/dev/pts"); ss.push_back("/dev/full"); - if (worker.store.systemFeatures.get().count("kvm") && pathExists("/dev/kvm")) + if (worker.store.config().systemFeatures.get().count("kvm") + && pathExists("/dev/kvm")) + { ss.push_back("/dev/kvm"); + } ss.push_back("/dev/null"); ss.push_back("/dev/random"); ss.push_back("/dev/tty"); @@ -1702,7 +1707,7 @@ void LocalDerivationGoal::runChild() /* And we want the store in there regardless of how empty pathsInChroot. We include the innermost path component this time, since it's typically /nix/store and we care about that. */ - Path cur = worker.store.storeDir; + Path cur = worker.store.config().storeDir; while (cur.compare("/") != 0) { ancestry.insert(cur); cur = dirOf(cur); diff --git a/lix/libstore/build/substitution-goal.cc b/lix/libstore/build/substitution-goal.cc index a464632c3..6303801f0 100644 --- a/lix/libstore/build/substitution-goal.cc +++ b/lix/libstore/build/substitution-goal.cc @@ -100,9 +100,9 @@ try { subPath = sub->makeFixedOutputPathFromCA( std::string { storePath.name() }, ContentAddressWithReferences::withoutRefs(*ca)); - if (sub->storeDir == worker.store.storeDir) + if (sub->config().storeDir == worker.store.config().storeDir) assert(subPath == storePath); - } else if (sub->storeDir != worker.store.storeDir) { + } else if (sub->config().storeDir != worker.store.config().storeDir) { co_return co_await tryNext(); } @@ -151,7 +151,7 @@ try { /* Bail out early if this substituter lacks a valid signature. LocalStore::addToStore() also checks for this, but only after we've downloaded the path. */ - if (!sub->isTrusted && worker.store.pathInfoIsUntrusted(*info)) + if (!sub->config().isTrusted && worker.store.pathInfoIsUntrusted(*info)) { warn("ignoring substitute for '%s' from '%s', as it's not signed by any of the keys in 'trusted-public-keys'", worker.store.printStorePath(storePath), sub->getUri()); @@ -220,7 +220,11 @@ try { PushActivity pact(act.id); copyStorePath( - *sub, worker.store, fetchPath, repair, sub->isTrusted ? NoCheckSigs : CheckSigs + *sub, + worker.store, + fetchPath, + repair, + sub->config().isTrusted ? NoCheckSigs : CheckSigs ); } catch (const EndOfFile &) { throw EndOfFile( diff --git a/lix/libstore/dummy-store.cc b/lix/libstore/dummy-store.cc index 39ac49177..97fb484c4 100644 --- a/lix/libstore/dummy-store.cc +++ b/lix/libstore/dummy-store.cc @@ -16,17 +16,18 @@ struct DummyStoreConfig : virtual StoreConfig { } }; -struct DummyStore : public virtual DummyStoreConfig, public virtual Store +struct DummyStore : public virtual Store { - DummyStore(const std::string scheme, const std::string uri, const Params & params) - : DummyStore(params) + DummyStoreConfig config_; + + DummyStoreConfig & config() override { return config_; } + const DummyStoreConfig & config() const override { return config_; } + + DummyStore(const std::string scheme, const std::string uri, DummyStoreConfig config) + : DummyStore(std::move(config)) { } - DummyStore(const Params & params) - : StoreConfig(params) - , DummyStoreConfig(params) - , Store(params) - { } + DummyStore(DummyStoreConfig config) : Store(config), config_(std::move(config)) {} std::string getUri() override { diff --git a/lix/libstore/filetransfer.cc b/lix/libstore/filetransfer.cc index 19ccef2bb..d960f6878 100644 --- a/lix/libstore/filetransfer.cc +++ b/lix/libstore/filetransfer.cc @@ -619,7 +619,7 @@ struct curlFileTransfer : public FileTransfer } #if ENABLE_S3 - static std::tuple parseS3Uri(std::string uri) + static std::tuple parseS3Uri(std::string uri) { auto [path, params] = splitUriAndParams(uri); diff --git a/lix/libstore/gc.cc b/lix/libstore/gc.cc index fa79b43cf..750bdbc1d 100644 --- a/lix/libstore/gc.cc +++ b/lix/libstore/gc.cc @@ -46,7 +46,7 @@ static void makeSymlink(const Path & link, const Path & target) void LocalStore::addIndirectRoot(const Path & path) { std::string hash = hashString(HashType::SHA1, path).to_string(Base::Base32, false); - Path realRoot = canonPath(fmt("%1%/%2%/auto/%3%", stateDir, gcRootsDir, hash)); + Path realRoot = canonPath(fmt("%1%/%2%/auto/%3%", config().stateDir, gcRootsDir, hash)); makeSymlink(realRoot, path); } @@ -111,7 +111,7 @@ void LocalStore::createTempRootsFile() void LocalStore::addTempRoot(const StorePath & path) { - if (readOnly) { + if (config().readOnly) { debug("Read-only store doesn't support creating lock files for temp roots, but nothing can be deleted anyways."); return; } @@ -138,7 +138,7 @@ void LocalStore::addTempRoot(const StorePath & path) auto fdRootsSocket(_fdRootsSocket.lock()); if (!*fdRootsSocket) { - auto socketPath = stateDir.get() + gcSocketPath; + auto socketPath = config().stateDir.get() + gcSocketPath; debug("connecting to '%s'", socketPath); *fdRootsSocket = createUnixDomainSocket(); try { @@ -268,7 +268,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots) else { target = absPath(target, dirOf(path)); if (!pathExists(target)) { - if (isInDir(path, stateDir + "/" + gcRootsDir + "/auto")) { + if (isInDir(path, config().stateDir + "/" + gcRootsDir + "/auto")) { printInfo("removing stale link from '%1%' to '%2%'", path, target); unlink(path.c_str()); } @@ -282,7 +282,8 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots) } else if (type == DT_REG) { - auto storePath = maybeParseStorePath(storeDir + "/" + std::string(baseNameOf(path))); + auto storePath = + maybeParseStorePath(config().storeDir + "/" + std::string(baseNameOf(path))); if (storePath && isValidPath(*storePath)) roots[std::move(*storePath)].emplace(path); } @@ -302,8 +303,8 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots) void LocalStore::findRootsNoTemp(Roots & roots, bool censor) { /* Process direct roots in {gcroots,profiles}. */ - findRoots(stateDir + "/" + gcRootsDir, DT_UNKNOWN, roots); - findRoots(stateDir + "/profiles", DT_UNKNOWN, roots); + findRoots(config().stateDir + "/" + gcRootsDir, DT_UNKNOWN, roots); + findRoots(config().stateDir + "/profiles", DT_UNKNOWN, roots); /* Add additional roots returned by different platforms-specific heuristics. This is typically used to add running programs to @@ -589,7 +590,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) if (auto p = getEnv("_NIX_TEST_GC_SYNC_1")) readFile(*p); - GCOperation gcServer {*this, stateDir.get()}; + GCOperation gcServer {*this, config().stateDir.get()}; /* Find the roots. Since we've grabbed the GC lock, the set of permanent roots cannot increase now. */ @@ -617,8 +618,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) GCLimitReached if we've deleted enough garbage. */ auto deleteFromStore = [&](std::string_view baseName) { - Path path = storeDir + "/" + std::string(baseName); - Path realPath = realStoreDir + "/" + std::string(baseName); + Path path = config().storeDir + "/" + std::string(baseName); + Path realPath = config().realStoreDir + "/" + std::string(baseName); /* There may be temp directories in the store that are still in use by another process. We need to be sure that we can acquire an @@ -774,8 +775,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) printInfo("determining live/dead paths..."); try { - AutoCloseDir dir(opendir(realStoreDir.get().c_str())); - if (!dir) throw SysError("opening directory '%1%'", realStoreDir); + AutoCloseDir dir(opendir(config().realStoreDir.get().c_str())); + if (!dir) throw SysError("opening directory '%1%'", config().realStoreDir); /* Read the store and delete all paths that are invalid or unreachable. We don't use readDirectory() here so that @@ -788,7 +789,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) std::string name = dirent->d_name; if (name == "." || name == ".." || name == linksName) continue; - if (auto storePath = maybeParseStorePath(storeDir + "/" + name)) + if (auto storePath = maybeParseStorePath(config().storeDir + "/" + name)) deleteReferrersClosure(*storePath); else deleteFromStore(name); @@ -870,8 +871,8 @@ void LocalStore::autoGC(bool sync) return std::stoll(readFile(*fakeFreeSpaceFile)); struct statvfs st; - if (statvfs(realStoreDir.get().c_str(), &st)) - throw SysError("getting filesystem info about '%s'", realStoreDir); + if (statvfs(config().realStoreDir.get().c_str(), &st)) + throw SysError("getting filesystem info about '%s'", config().realStoreDir); return (uint64_t) st.f_bavail * st.f_frsize; }; diff --git a/lix/libstore/http-binary-cache-store.cc b/lix/libstore/http-binary-cache-store.cc index 260ede2a4..c4f1922e7 100644 --- a/lix/libstore/http-binary-cache-store.cc +++ b/lix/libstore/http-binary-cache-store.cc @@ -22,10 +22,11 @@ struct HttpBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig } }; -class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public virtual BinaryCacheStore +class HttpBinaryCacheStore : public virtual BinaryCacheStore { private: + HttpBinaryCacheStoreConfig config_; Path cacheUri; struct State @@ -41,12 +42,10 @@ public: HttpBinaryCacheStore( const std::string & scheme, const Path & _cacheUri, - const Params & params) - : StoreConfig(params) - , BinaryCacheStoreConfig(params) - , HttpBinaryCacheStoreConfig(params) - , Store(params) - , BinaryCacheStore(params) + HttpBinaryCacheStoreConfig config) + : Store(config) + , BinaryCacheStore(config) + , config_(std::move(config)) , cacheUri(scheme + "://" + _cacheUri) { if (cacheUri.back() == '/') @@ -55,6 +54,9 @@ public: diskCache = getNarInfoDiskCache(); } + HttpBinaryCacheStoreConfig & config() override { return config_; } + const HttpBinaryCacheStoreConfig & config() const override { return config_; } + std::string getUri() override { return cacheUri; @@ -64,15 +66,17 @@ public: { // FIXME: do this lazily? if (auto cacheInfo = diskCache->upToDateCacheExists(cacheUri)) { - wantMassQuery.setDefault(cacheInfo->wantMassQuery); - priority.setDefault(cacheInfo->priority); + config_.wantMassQuery.setDefault(cacheInfo->wantMassQuery); + config_.priority.setDefault(cacheInfo->priority); } else { try { BinaryCacheStore::init(); } catch (UploadToHTTP &) { throw Error("'%s' does not appear to be a binary cache", cacheUri); } - diskCache->createCache(cacheUri, storeDir, wantMassQuery, priority); + diskCache->createCache( + cacheUri, config_.storeDir, config_.wantMassQuery, config_.priority + ); } } diff --git a/lix/libstore/legacy-ssh-store.cc b/lix/libstore/legacy-ssh-store.cc index 4a0b33a0b..e9fbf543d 100644 --- a/lix/libstore/legacy-ssh-store.cc +++ b/lix/libstore/legacy-ssh-store.cc @@ -14,7 +14,7 @@ namespace nix { -struct LegacySSHStoreConfig : virtual CommonSSHStoreConfig +struct LegacySSHStoreConfig : CommonSSHStoreConfig { using CommonSSHStoreConfig::CommonSSHStoreConfig; @@ -34,12 +34,22 @@ struct LegacySSHStoreConfig : virtual CommonSSHStoreConfig } }; -struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Store +struct LegacySSHStoreConfigWithLog : LegacySSHStoreConfig { + using LegacySSHStoreConfig::LegacySSHStoreConfig; + // Hack for getting remote build log output. // Intentionally not in `LegacySSHStoreConfig` so that it doesn't appear in // the documentation const Setting logFD{this, -1, "log-fd", "file descriptor to which SSH's stderr is connected"}; +}; + +struct LegacySSHStore : public virtual Store +{ + LegacySSHStoreConfigWithLog config_; + + LegacySSHStoreConfigWithLog & config() override { return config_; } + const LegacySSHStoreConfigWithLog & config() const override { return config_; } struct Connection { @@ -89,25 +99,25 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor static std::set uriSchemes() { return {"ssh"}; } - LegacySSHStore(const std::string & scheme, const std::string & host, const Params & params) - : StoreConfig(params) - , CommonSSHStoreConfig(params) - , LegacySSHStoreConfig(params) - , Store(params) + LegacySSHStore( + const std::string & scheme, const std::string & host, LegacySSHStoreConfigWithLog config + ) + : Store(config) + , config_(std::move(config)) , host(host) , connections(make_ref>( - std::max(1, (int) maxConnections), + std::max(1, (int) config_.maxConnections), [this]() { return openConnection(); }, [](const ref & r) { return r->good; } )) , master( host, - sshKey, - sshPublicHostKey, + config_.sshKey, + config_.sshPublicHostKey, // Use SSH master only if using more than 1 connection. connections->capacity() > 1, - compress, - logFD) + config_.compress, + config_.logFD) { } @@ -115,8 +125,11 @@ struct LegacySSHStore : public virtual LegacySSHStoreConfig, public virtual Stor { auto conn = make_ref(); conn->sshConn = master.startCommand( - fmt("%s --serve --write", remoteProgram) - + (remoteStore.get() == "" ? "" : " --store " + shellEscape(remoteStore.get()))); + fmt("%s --serve --write", config_.remoteProgram) + + (config_.remoteStore.get() == "" + ? "" + : " --store " + shellEscape(config_.remoteStore.get())) + ); conn->to = FdSink(conn->sshConn->in.get()); conn->from = FdSource(conn->sshConn->out.get()); diff --git a/lix/libstore/local-binary-cache-store.cc b/lix/libstore/local-binary-cache-store.cc index de66bee98..9772289bf 100644 --- a/lix/libstore/local-binary-cache-store.cc +++ b/lix/libstore/local-binary-cache-store.cc @@ -21,23 +21,25 @@ struct LocalBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig } }; -class LocalBinaryCacheStore : public virtual LocalBinaryCacheStoreConfig, public virtual BinaryCacheStore +class LocalBinaryCacheStore : public virtual BinaryCacheStore { private: + LocalBinaryCacheStoreConfig config_; Path binaryCacheDir; public: + LocalBinaryCacheStoreConfig & config() override { return config_; } + const LocalBinaryCacheStoreConfig & config() const override { return config_; } + LocalBinaryCacheStore( const std::string scheme, const Path & binaryCacheDir, - const Params & params) - : StoreConfig(params) - , BinaryCacheStoreConfig(params) - , LocalBinaryCacheStoreConfig(params) - , Store(params) - , BinaryCacheStore(params) + LocalBinaryCacheStoreConfig config) + : Store(config) + , BinaryCacheStore(config) + , config_(std::move(config)) , binaryCacheDir(binaryCacheDir) { } @@ -89,7 +91,7 @@ protected: !entry.name.ends_with(".narinfo")) continue; paths.insert(parseStorePath( - storeDir + "/" + entry.name.substr(0, entry.name.size() - 8) + config_.storeDir + "/" + entry.name.substr(0, entry.name.size() - 8) + "-" + MissingName)); } @@ -106,7 +108,7 @@ void LocalBinaryCacheStore::init() { createDirs(binaryCacheDir + "/nar"); createDirs(binaryCacheDir + "/" + realisationsPrefix); - if (writeDebugInfo) + if (config_.writeDebugInfo) createDirs(binaryCacheDir + "/debuginfo"); createDirs(binaryCacheDir + "/log"); BinaryCacheStore::init(); diff --git a/lix/libstore/local-fs-store.cc b/lix/libstore/local-fs-store.cc index 52d9c04f5..02481cef3 100644 --- a/lix/libstore/local-fs-store.cc +++ b/lix/libstore/local-fs-store.cc @@ -8,11 +8,6 @@ namespace nix { -LocalFSStore::LocalFSStore(const Params & params) - : Store(params) -{ -} - struct LocalStoreAccessor : public FSAccessor { ref store; @@ -24,7 +19,7 @@ struct LocalStoreAccessor : public FSAccessor auto storePath = store->toStorePath(path).first; if (requireValidPath && !store->isValidPath(storePath)) throw InvalidPath("path '%1%' does not exist in the store", store->printStorePath(storePath)); - return store->getRealStoreDir() + std::string(path, store->storeDir.size()); + return store->getRealStoreDir() + std::string(path, store->config().storeDir.size()); } FSAccessor::Stat stat(const Path & path) override @@ -82,7 +77,7 @@ WireFormatGenerator LocalFSStore::narFromPath(const StorePath & path) { if (!isValidPath(path)) throw Error("path '%s' does not exist in store", printStorePath(path)); - return dumpPath(getRealStoreDir() + std::string(printStorePath(path), storeDir.size())); + return dumpPath(getRealStoreDir() + std::string(printStorePath(path), config().storeDir.size())); } const std::string LocalFSStore::drvsLogDir = "drvs"; @@ -95,8 +90,8 @@ std::optional LocalFSStore::getBuildLogExact(const StorePath & path Path logPath = j == 0 - ? fmt("%s/%s/%s/%s", logDir, drvsLogDir, baseName.substr(0, 2), baseName.substr(2)) - : fmt("%s/%s/%s", logDir, drvsLogDir, baseName); + ? fmt("%s/%s/%s/%s", config().logDir, drvsLogDir, baseName.substr(0, 2), baseName.substr(2)) + : fmt("%s/%s/%s", config().logDir, drvsLogDir, baseName); Path logBz2Path = logPath + ".bz2"; if (pathExists(logPath)) diff --git a/lix/libstore/local-fs-store.hh b/lix/libstore/local-fs-store.hh index bebddeb56..31eba2e66 100644 --- a/lix/libstore/local-fs-store.hh +++ b/lix/libstore/local-fs-store.hh @@ -30,8 +30,7 @@ struct LocalFSStoreConfig : virtual StoreConfig "Physical path of the Nix store."}; }; -class LocalFSStore : public virtual LocalFSStoreConfig, - public virtual Store, +class LocalFSStore : public virtual Store, public virtual GcStore, public virtual LogStore { @@ -40,7 +39,8 @@ public: const static std::string drvsLogDir; - LocalFSStore(const Params & params); + LocalFSStoreConfig & config() override = 0; + const LocalFSStoreConfig & config() const override = 0; WireFormatGenerator narFromPath(const StorePath & path) override; ref getFSAccessor() override; @@ -61,12 +61,12 @@ public: */ virtual Path addPermRoot(const StorePath & storePath, const Path & gcRoot) = 0; - virtual Path getRealStoreDir() { return realStoreDir; } + virtual Path getRealStoreDir() { return config().realStoreDir; } Path toRealPath(const Path & storePath) override { assert(isInStore(storePath)); - return getRealStoreDir() + "/" + std::string(storePath, storeDir.size() + 1); + return getRealStoreDir() + "/" + std::string(storePath, config().storeDir.size() + 1); } std::optional getBuildLogExact(const StorePath & path) override; diff --git a/lix/libstore/local-store.cc b/lix/libstore/local-store.cc index 7a3cf62d7..9f2828920 100644 --- a/lix/libstore/local-store.cc +++ b/lix/libstore/local-store.cc @@ -174,17 +174,14 @@ void migrateCASchema(SQLite& db, Path schemaPath, AutoCloseFD& lockFd) } } -LocalStore::LocalStore(const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(params) - , LocalStoreConfig(params) - , Store(params) - , LocalFSStore(params) - , dbDir(stateDir + "/db") - , linksDir(realStoreDir + "/.links") +LocalStore::LocalStore(LocalStoreConfig config) + : Store(config) + , config_(std::move(config)) + , dbDir(config_.stateDir + "/db") + , linksDir(config_.realStoreDir + "/.links") , reservedSpacePath(dbDir + "/reserved") , schemaPath(dbDir + "/schema") - , tempRootsDir(stateDir + "/temproots") + , tempRootsDir(config_.stateDir + "/temproots") , fnTempRoots(fmt("%s/%d", tempRootsDir, getpid())) , locksHeld(tokenizeString(getEnv("NIX_HELD_LOCKS").value_or(""))) { @@ -192,18 +189,18 @@ LocalStore::LocalStore(const Params & params) state->stmts = std::make_unique(); /* Create missing state directories if they don't already exist. */ - createDirs(realStoreDir); - if (readOnly) { + createDirs(config_.realStoreDir); + if (config_.readOnly) { experimentalFeatureSettings.require(Xp::ReadOnlyLocalStore); } else { makeStoreWritable(); } createDirs(linksDir); - Path profilesDir = stateDir + "/profiles"; + Path profilesDir = config_.stateDir + "/profiles"; createDirs(profilesDir); createDirs(tempRootsDir); createDirs(dbDir); - Path gcRootsDir = stateDir + "/gcroots"; + Path gcRootsDir = config_.stateDir + "/gcroots"; if (!pathExists(gcRootsDir)) { createDirs(gcRootsDir); createSymlink(profilesDir, gcRootsDir + "/profiles"); @@ -211,7 +208,7 @@ LocalStore::LocalStore(const Params & params) for (auto & perUserDir : {profilesDir + "/per-user", gcRootsDir + "/per-user"}) { createDirs(perUserDir); - if (!readOnly) { + if (!config_.readOnly) { if (chmod(perUserDir.c_str(), 0755) == -1) throw SysError("could not set permissions on '%s' to 755", perUserDir); } @@ -227,21 +224,21 @@ LocalStore::LocalStore(const Params & params) printError("warning: the group '%1%' specified in 'build-users-group' does not exist", settings.buildUsersGroup); else { struct stat st; - if (stat(realStoreDir.get().c_str(), &st)) - throw SysError("getting attributes of path '%1%'", realStoreDir); + if (stat(config_.realStoreDir.get().c_str(), &st)) + throw SysError("getting attributes of path '%1%'", config_.realStoreDir); if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) { - if (chown(realStoreDir.get().c_str(), 0, gr->gr_gid) == -1) - throw SysError("changing ownership of path '%1%'", realStoreDir); - if (chmod(realStoreDir.get().c_str(), perm) == -1) - throw SysError("changing permissions on path '%1%'", realStoreDir); + if (chown(config_.realStoreDir.get().c_str(), 0, gr->gr_gid) == -1) + throw SysError("changing ownership of path '%1%'", config_.realStoreDir); + if (chmod(config_.realStoreDir.get().c_str(), perm) == -1) + throw SysError("changing permissions on path '%1%'", config_.realStoreDir); } } } /* Ensure that the store and its parents are not symlinks. */ if (!settings.allowSymlinkedStore) { - Path path = realStoreDir; + Path path = config_.realStoreDir; struct stat st; while (path != "/") { st = lstat(path); @@ -278,12 +275,12 @@ LocalStore::LocalStore(const Params & params) /* Acquire the big fat lock in shared mode to make sure that no schema upgrade is in progress. */ - if (!readOnly) { + if (!config_.readOnly) { Path globalLockPath = dbDir + "/big-lock"; globalLock = openLockFile(globalLockPath.c_str(), true); } - if (!readOnly && !lockFile(globalLock.get(), ltRead, false)) { + if (!config_.readOnly && !lockFile(globalLock.get(), ltRead, false)) { printInfo("waiting for the big Nix store lock..."); lockFile(globalLock.get(), ltRead, true); } @@ -291,7 +288,7 @@ LocalStore::LocalStore(const Params & params) /* Check the current database schema and if necessary do an upgrade. */ int curSchema = getSchema(); - if (readOnly && curSchema < nixSchemaVersion) { + if (config_.readOnly && curSchema < nixSchemaVersion) { debug("current schema version: %d", curSchema); debug("supported schema version: %d", nixSchemaVersion); throw Error(curSchema == 0 ? @@ -363,7 +360,7 @@ LocalStore::LocalStore(const Params & params) else openDB(*state, false); if (experimentalFeatureSettings.isEnabled(Xp::CaDerivations)) { - if (!readOnly) { + if (!config_.readOnly) { migrateCASchema(state->db, dbDir + "/ca-schema", globalLock); } else { throw Error("need to migrate to content-addressed schema, but this cannot be done in read-only mode"); @@ -443,8 +440,8 @@ LocalStore::LocalStore(const Params & params) } -LocalStore::LocalStore(std::string scheme, std::string path, const Params & params) - : LocalStore(params) +LocalStore::LocalStore(std::string scheme, std::string path, LocalStoreConfig config) + : LocalStore(std::move(config)) { throw UnimplementedError("LocalStore"); } @@ -452,7 +449,7 @@ LocalStore::LocalStore(std::string scheme, std::string path, const Params & para AutoCloseFD LocalStore::openGCLock() { - Path fnGCLock = stateDir + "/gc.lock"; + Path fnGCLock = config_.stateDir + "/gc.lock"; AutoCloseFD fdGCLock{open(fnGCLock.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600)}; if (!fdGCLock) throw SysError("opening global GC lock '%1%'", fnGCLock); @@ -498,17 +495,17 @@ int LocalStore::getSchema() void LocalStore::openDB(State & state, bool create) { - if (create && readOnly) { + if (create && config_.readOnly) { throw Error("cannot create database while in read-only mode"); } - if (access(dbDir.c_str(), R_OK | (readOnly ? 0 : W_OK))) + if (access(dbDir.c_str(), R_OK | (config_.readOnly ? 0 : W_OK))) throw SysError("Nix database directory '%1%' is not writable", dbDir); /* Open the Nix database. */ std::string dbPath = dbDir + "/db.sqlite"; auto & db(state.db); - auto openMode = readOnly ? SQLiteOpenMode::Immutable + auto openMode = config_.readOnly ? SQLiteOpenMode::Immutable : create ? SQLiteOpenMode::Normal : SQLiteOpenMode::NoCreate; state.db = SQLite(dbPath, openMode); @@ -587,12 +584,12 @@ void LocalStore::makeStoreWritable() if (getuid() != 0) return; /* Check if /nix/store is on a read-only mount. */ struct statvfs stat; - if (statvfs(realStoreDir.get().c_str(), &stat) != 0) + if (statvfs(config_.realStoreDir.get().c_str(), &stat) != 0) throw SysError("getting info about the Nix store mount point"); if (stat.f_flag & ST_RDONLY) { - if (mount(0, realStoreDir.get().c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) - throw SysError("remounting %1% writable", realStoreDir); + if (mount(0, config_.realStoreDir.get().c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) + throw SysError("remounting %1% writable", config_.realStoreDir); } #endif } @@ -1068,7 +1065,7 @@ std::optional LocalStore::queryPathFromHashPart(const std::string & h { if (hashPart.size() != StorePath::HashLen) throw Error("invalid hash part"); - Path prefix = storeDir + "/" + hashPart; + Path prefix = config_.storeDir + "/" + hashPart; return retrySQLite>([&]() -> std::optional { auto state(_state.lock()); @@ -1097,8 +1094,8 @@ StorePathSet LocalStore::querySubstitutablePaths(const StorePathSet & paths) for (auto & sub : getDefaultSubstituters()) { if (remaining.empty()) break; - if (sub->storeDir != storeDir) continue; - if (!sub->wantMassQuery) continue; + if (sub->config().storeDir != config_.storeDir) continue; + if (!sub->config().wantMassQuery) continue; auto valid = sub->queryValidPaths(remaining); @@ -1208,12 +1205,12 @@ const PublicKeys & LocalStore::getPublicKeys() bool LocalStore::pathInfoIsUntrusted(const ValidPathInfo & info) { - return requireSigs && !info.checkSignatures(*this, getPublicKeys()); + return config_.requireSigs && !info.checkSignatures(*this, getPublicKeys()); } bool LocalStore::realisationIsUntrusted(const Realisation & realisation) { - return requireSigs && !realisation.checkSignatures(getPublicKeys()); + return config_.requireSigs && !realisation.checkSignatures(getPublicKeys()); } void LocalStore::addToStore(const ValidPathInfo & info, Source & source, @@ -1508,7 +1505,7 @@ std::pair LocalStore::createTempDirInStore() /* There is a slight possibility that `tmpDir' gets deleted by the GC between createTempDir() and when we acquire a lock on it. We'll repeat until 'tmpDir' exists and we've locked it. */ - tmpDirFn = createTempDir(realStoreDir, "tmp"); + tmpDirFn = createTempDir(config_.realStoreDir, "tmp"); tmpDirFd = AutoCloseFD{open(tmpDirFn.c_str(), O_RDONLY | O_DIRECTORY)}; if (tmpDirFd.get() < 0) { continue; @@ -1564,7 +1561,7 @@ bool LocalStore::verifyStore(bool checkContents, RepairFlag repair) database and the filesystem) in the loop below, in order to catch invalid states. */ - for (auto & i : readDirectory(realStoreDir)) { + for (auto & i : readDirectory(config_.realStoreDir)) { try { storePathsInStoreDir.insert({i.name}); } catch (BadStorePath &) { } @@ -1758,7 +1755,7 @@ void LocalStore::upgradeStore7() { if (getuid() != 0) return; printInfo("removing immutable bits from the Nix store (this may take a while)..."); - makeMutable(realStoreDir); + makeMutable(config_.realStoreDir); } #else @@ -1927,7 +1924,9 @@ void LocalStore::addBuildLog(const StorePath & drvPath, std::string_view log) auto baseName = drvPath.to_string(); - auto logPath = fmt("%s/%s/%s/%s.bz2", logDir, drvsLogDir, baseName.substr(0, 2), baseName.substr(2)); + auto logPath = + fmt("%s/%s/%s/%s.bz2", config_.logDir, drvsLogDir, baseName.substr(0, 2), baseName.substr(2) + ); if (pathExists(logPath)) return; diff --git a/lix/libstore/local-store.hh b/lix/libstore/local-store.hh index 6a88faa21..81ae6f573 100644 --- a/lix/libstore/local-store.hh +++ b/lix/libstore/local-store.hh @@ -68,12 +68,13 @@ struct LocalStoreConfig : virtual LocalFSStoreConfig std::string doc() override; }; -class LocalStore : public virtual LocalStoreConfig - , public virtual IndirectRootStore +class LocalStore : public virtual IndirectRootStore , public virtual GcStore { private: + LocalStoreConfig config_; + /** * Lock file used for upgrading. */ @@ -125,6 +126,9 @@ public: const Path tempRootsDir; const Path fnTempRoots; + LocalStoreConfig & config() override { return config_; } + const LocalStoreConfig & config() const override { return config_; } + private: const PublicKeys & getPublicKeys(); @@ -137,8 +141,8 @@ protected: * Protected so that users don't accidentally create a LocalStore * instead of a platform's subclass. */ - LocalStore(const Params & params); - LocalStore(std::string scheme, std::string path, const Params & params); + LocalStore(LocalStoreConfig config); + LocalStore(std::string scheme, std::string path, LocalStoreConfig config); public: @@ -155,7 +159,7 @@ public: /** * Create a LocalStore, possibly a platform-specific subclass */ - static std::shared_ptr makeLocalStore(const Params & params); + static std::shared_ptr makeLocalStore(const StoreConfig::Params & params); /** * Implementations of abstract store API methods. diff --git a/lix/libstore/machines.cc b/lix/libstore/machines.cc index b5a1bfea0..fff5df8aa 100644 --- a/lix/libstore/machines.cc +++ b/lix/libstore/machines.cc @@ -66,7 +66,7 @@ bool Machine::mandatoryMet(const std::set & features) const ref Machine::openStore() const { - Store::Params storeParams; + StoreConfig::Params storeParams; if (storeUri.starts_with("ssh://")) { storeParams["log-fd"] = "4"; storeParams["max-connections"] = "1"; diff --git a/lix/libstore/optimise-store.cc b/lix/libstore/optimise-store.cc index 2effe5f88..15a793096 100644 --- a/lix/libstore/optimise-store.cc +++ b/lix/libstore/optimise-store.cc @@ -208,14 +208,14 @@ void LocalStore::optimisePath_(Activity * act, OptimiseStats & stats, the store itself (we don't want or need to mess with its permissions). */ const Path dirOfPath(dirOf(path)); - bool mustToggle = dirOfPath != realStoreDir.get(); + bool mustToggle = dirOfPath != config().realStoreDir.get(); if (mustToggle) makeWritable(dirOfPath); /* When we're done, make the directory read-only again and reset its timestamp back to 0. */ MakeReadOnly makeReadOnly(mustToggle ? dirOfPath : ""); - Path tempLink = makeTempPath(realStoreDir, "/.tmp-link"); + Path tempLink = makeTempPath(config().realStoreDir, "/.tmp-link"); unlink(tempLink.c_str()); // just in case; ignore errors if (link(linkPath.c_str(), tempLink.c_str()) == -1) { @@ -272,7 +272,13 @@ void LocalStore::optimiseStore(OptimiseStats & stats) if (!isValidPath(i)) continue; /* path was GC'ed, probably */ { Activity act(*logger, lvlTalkative, actUnknown, fmt("optimising path '%s'", printStorePath(i))); - optimisePath_(&act, stats, realStoreDir + "/" + std::string(i.to_string()), inodeHash, NoRepair); + optimisePath_( + &act, + stats, + config().realStoreDir + "/" + std::string(i.to_string()), + inodeHash, + NoRepair + ); } done++; act.progress(done, paths.size()); diff --git a/lix/libstore/parsed-derivations.cc b/lix/libstore/parsed-derivations.cc index 324c6906e..a4ecec5f2 100644 --- a/lix/libstore/parsed-derivations.cc +++ b/lix/libstore/parsed-derivations.cc @@ -111,7 +111,7 @@ bool ParsedDerivation::canBuildLocally(Store & localStore) const return false; for (auto & feature : getRequiredSystemFeatures()) - if (!localStore.systemFeatures.get().count(feature)) return false; + if (!localStore.config().systemFeatures.get().count(feature)) return false; return true; } diff --git a/lix/libstore/path.cc b/lix/libstore/path.cc index 8e818a9ca..4bdfb2483 100644 --- a/lix/libstore/path.cc +++ b/lix/libstore/path.cc @@ -68,7 +68,7 @@ StorePath StorePath::random(std::string_view name) StorePath Store::parseStorePath(std::string_view path) const { auto p = canonPath(std::string(path)); - if (dirOf(p) != storeDir) + if (dirOf(p) != config().storeDir) throw BadStorePath("path '%s' is not in the Nix store", p); return StorePath(baseNameOf(p)); } @@ -77,7 +77,7 @@ std::optional Store::maybeParseStorePath(std::string_view path) const { // If it's not an absolute path, or if the dirname of the path isn't /nix/store // (or whatever our storeDir is), then it can't be a store path. - if ((path.size() > 0 && path[0] != '/') || dirOf(canonPath(path)) != this->storeDir) { + if ((path.size() > 0 && path[0] != '/') || dirOf(canonPath(path)) != config().storeDir) { return std::nullopt; } try { @@ -101,7 +101,7 @@ StorePathSet Store::parseStorePathSet(const PathSet & paths) const std::string Store::printStorePath(const StorePath & path) const { - return (storeDir + "/").append(path.to_string()); + return (config().storeDir + "/").append(path.to_string()); } PathSet Store::printStorePathSet(const StorePathSet & paths) const diff --git a/lix/libstore/platform.cc b/lix/libstore/platform.cc index e7db1b769..7a1d9c502 100644 --- a/lix/libstore/platform.cc +++ b/lix/libstore/platform.cc @@ -12,7 +12,7 @@ #endif namespace nix { -std::shared_ptr LocalStore::makeLocalStore(const Params & params) +std::shared_ptr LocalStore::makeLocalStore(const StoreConfig::Params & params) { #if __linux__ return std::shared_ptr(new LinuxLocalStore(params)); diff --git a/lix/libstore/platform/darwin.cc b/lix/libstore/platform/darwin.cc index 6e5a5f796..ac540e286 100644 --- a/lix/libstore/platform/darwin.cc +++ b/lix/libstore/platform/darwin.cc @@ -16,7 +16,7 @@ namespace nix { void DarwinLocalStore::findPlatformRoots(UncheckedRoots & unchecked) { - auto storePathRegex = regex::storePathRegex(storeDir); + auto storePathRegex = regex::storePathRegex(config().storeDir); std::vector pids; std::size_t pidBufSize = 1; diff --git a/lix/libstore/platform/darwin.hh b/lix/libstore/platform/darwin.hh index 580d8963a..db44fe632 100644 --- a/lix/libstore/platform/darwin.hh +++ b/lix/libstore/platform/darwin.hh @@ -13,17 +13,12 @@ namespace nix { class DarwinLocalStore : public LocalStore { public: - DarwinLocalStore(const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(params) - , LocalStoreConfig(params) - , Store(params) - , LocalFSStore(params) - , LocalStore(params) + DarwinLocalStore(LocalStoreConfig config) + : Store(config), LocalStore(config) { } - DarwinLocalStore(const std::string scheme, std::string path, const Params & params) - : DarwinLocalStore(params) + DarwinLocalStore(const std::string scheme, std::string path, LocalStoreConfig config) + : DarwinLocalStore(config) { throw UnimplementedError("DarwinLocalStore"); } diff --git a/lix/libstore/platform/fallback.hh b/lix/libstore/platform/fallback.hh index 63dfebba9..e349d2808 100644 --- a/lix/libstore/platform/fallback.hh +++ b/lix/libstore/platform/fallback.hh @@ -13,17 +13,9 @@ namespace nix { class FallbackLocalStore : public LocalStore { public: - FallbackLocalStore(const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(params) - , LocalStoreConfig(params) - , Store(params) - , LocalFSStore(params) - , LocalStore(params) - { - } - FallbackLocalStore(const std::string scheme, std::string path, const Params & params) - : FallbackLocalStore(params) + FallbackLocalStore(LocalStoreConfig config) : Store(config), LocalStore(config) {} + FallbackLocalStore(const std::string scheme, std::string path, LocalStoreConfig config) + : FallbackLocalStore(config) { throw UnimplementedError("FallbackLocalStore"); } diff --git a/lix/libstore/platform/freebsd.cc b/lix/libstore/platform/freebsd.cc index a904cd359..fb7de0129 100644 --- a/lix/libstore/platform/freebsd.cc +++ b/lix/libstore/platform/freebsd.cc @@ -62,7 +62,7 @@ void FreeBSDLocalStore::findPlatformRoots(UncheckedRoots & unchecked) { readSysctlRoots("kern.module_path", unchecked); - auto storePathRegex = regex::storePathRegex(storeDir); + auto storePathRegex = regex::storePathRegex(config().storeDir); auto ps = std::unique_ptr(procstat_open_sysctl()); if (!ps) { diff --git a/lix/libstore/platform/freebsd.hh b/lix/libstore/platform/freebsd.hh index bafeea34c..2a9907a5e 100644 --- a/lix/libstore/platform/freebsd.hh +++ b/lix/libstore/platform/freebsd.hh @@ -13,17 +13,9 @@ namespace nix { class FreeBSDLocalStore : public LocalStore { public: - FreeBSDLocalStore(const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(params) - , LocalStoreConfig(params) - , Store(params) - , LocalFSStore(params) - , LocalStore(params) - { - } - FreeBSDLocalStore(const std::string scheme, std::string path, const Params & params) - : FreeBSDLocalStore(params) + FreeBSDLocalStore(LocalStoreConfig config) : Store(config), LocalStore(config) {} + FreeBSDLocalStore(const std::string scheme, std::string path, LocalStoreConfig config) + : FreeBSDLocalStore(config) { throw UnimplementedError("FreeBSDLocalStore"); } diff --git a/lix/libstore/platform/linux.cc b/lix/libstore/platform/linux.cc index c22203bcc..d8e5bf6d8 100644 --- a/lix/libstore/platform/linux.cc +++ b/lix/libstore/platform/linux.cc @@ -67,7 +67,7 @@ void LinuxLocalStore::findPlatformRoots(UncheckedRoots & unchecked) struct dirent * ent; auto digitsRegex = std::regex(R"(^\d+$)"); auto mapRegex = std::regex(R"(^\s*\S+\s+\S+\s+\S+\s+\S+\s+\S+\s+(/\S+)\s*$)"); - auto storePathRegex = regex::storePathRegex(storeDir); + auto storePathRegex = regex::storePathRegex(config().storeDir); while (errno = 0, ent = readdir(procDir.get())) { checkInterrupt(); if (std::regex_match(ent->d_name, digitsRegex)) { @@ -797,7 +797,7 @@ void LinuxLocalDerivationGoal::prepareSandbox() can be bind-mounted). !!! As an extra security precaution, make the fake Nix store only writable by the build user. */ - Path chrootStoreDir = chrootRootDir + worker.store.storeDir; + Path chrootStoreDir = chrootRootDir + worker.store.config().storeDir; createDirs(chrootStoreDir); chmodPath(chrootStoreDir, 01775); diff --git a/lix/libstore/platform/linux.hh b/lix/libstore/platform/linux.hh index c89f92876..4cf64265c 100644 --- a/lix/libstore/platform/linux.hh +++ b/lix/libstore/platform/linux.hh @@ -13,17 +13,9 @@ namespace nix { class LinuxLocalStore : public LocalStore { public: - LinuxLocalStore(const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(params) - , LocalStoreConfig(params) - , Store(params) - , LocalFSStore(params) - , LocalStore(params) - { - } - LinuxLocalStore(const std::string scheme, std::string path, const Params & params) - : LinuxLocalStore(params) + LinuxLocalStore(LocalStoreConfig config) : Store(config), LocalStore(config) {} + LinuxLocalStore(const std::string scheme, std::string path, LocalStoreConfig config) + : LinuxLocalStore(config) { throw UnimplementedError("LinuxLocalStore"); } diff --git a/lix/libstore/remote-store.cc b/lix/libstore/remote-store.cc index ab8ddc547..909e85ca7 100644 --- a/lix/libstore/remote-store.cc +++ b/lix/libstore/remote-store.cc @@ -24,11 +24,10 @@ namespace nix { /* TODO: Separate these store impls into different files, give them better names */ -RemoteStore::RemoteStore(const Params & params) - : RemoteStoreConfig(params) - , Store(params) +RemoteStore::RemoteStore(const RemoteStoreConfig & config) + : Store(config) , connections(make_ref>( - std::max(1, (int) maxConnections), + std::max(1, (int) config.maxConnections), [this]() { auto conn = openConnectionWrapper(); try { @@ -44,7 +43,7 @@ RemoteStore::RemoteStore(const Params & params) r->to.good() && r->from.good() && std::chrono::duration_cast( - std::chrono::steady_clock::now() - r->startTime).count() < maxConnectionAge; + std::chrono::steady_clock::now() - r->startTime).count() < this->config().maxConnectionAge; } )) { diff --git a/lix/libstore/remote-store.hh b/lix/libstore/remote-store.hh index 857c65631..df8d4f294 100644 --- a/lix/libstore/remote-store.hh +++ b/lix/libstore/remote-store.hh @@ -35,14 +35,16 @@ struct RemoteStoreConfig : virtual StoreConfig * \todo RemoteStore is a misnomer - should be something like * DaemonStore. */ -class RemoteStore : public virtual RemoteStoreConfig, - public virtual Store, +class RemoteStore : public virtual Store, public virtual GcStore, public virtual LogStore { public: - RemoteStore(const Params & params); + RemoteStore(const RemoteStoreConfig & config); + + RemoteStoreConfig & config() override = 0; + const RemoteStoreConfig & config() const override = 0; /* Implementations of abstract store API methods. */ diff --git a/lix/libstore/s3-binary-cache-store.cc b/lix/libstore/s3-binary-cache-store.cc index ad813f3d4..2cf6bac27 100644 --- a/lix/libstore/s3-binary-cache-store.cc +++ b/lix/libstore/s3-binary-cache-store.cc @@ -184,11 +184,6 @@ S3Helper::FileTransferResult S3Helper::getObject( return res; } -S3BinaryCacheStore::S3BinaryCacheStore(const Params & params) - : BinaryCacheStoreConfig(params) - , BinaryCacheStore(params) -{ } - struct S3BinaryCacheStoreConfig : virtual BinaryCacheStoreConfig { using BinaryCacheStoreConfig::BinaryCacheStoreConfig; @@ -260,8 +255,13 @@ struct S3BinaryCacheStoreConfig : virtual BinaryCacheStoreConfig } }; -struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual S3BinaryCacheStore +struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore { + S3BinaryCacheStoreConfig config_; + + S3BinaryCacheStoreConfig & config() override { return config_; } + const S3BinaryCacheStoreConfig & config() const override { return config_; } + std::string bucketName; Stats stats; @@ -271,15 +271,13 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual S3BinaryCacheStoreImpl( const std::string & uriScheme, const std::string & bucketName, - const Params & params) - : StoreConfig(params) - , BinaryCacheStoreConfig(params) - , S3BinaryCacheStoreConfig(params) - , Store(params) - , BinaryCacheStore(params) - , S3BinaryCacheStore(params) + S3BinaryCacheStoreConfig config) + : Store(config) + , BinaryCacheStore(config) + , S3BinaryCacheStore(config) + , config_(std::move(config)) , bucketName(bucketName) - , s3Helper(profile, region, scheme, endpoint) + , s3Helper(config_.profile, config_.region, config_.scheme, config_.endpoint) { diskCache = getNarInfoDiskCache(); } @@ -292,11 +290,13 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual void init() override { if (auto cacheInfo = diskCache->upToDateCacheExists(getUri())) { - wantMassQuery.setDefault(cacheInfo->wantMassQuery); - priority.setDefault(cacheInfo->priority); + config().wantMassQuery.setDefault(cacheInfo->wantMassQuery); + config().priority.setDefault(cacheInfo->priority); } else { BinaryCacheStore::init(); - diskCache->createCache(getUri(), storeDir, wantMassQuery, priority); + diskCache->createCache( + getUri(), config().storeDir, config().wantMassQuery, config().priority + ); } } @@ -360,11 +360,11 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual std::call_once(transferManagerCreated, [&]() { - if (multipartUpload) { + if (config().multipartUpload) { TransferManagerConfiguration transferConfig(executor.get()); transferConfig.s3Client = s3Helper.client; - transferConfig.bufferSize = bufferSize; + transferConfig.bufferSize = config().bufferSize; transferConfig.uploadProgressCallback = [](const TransferManager *transferManager, @@ -448,12 +448,14 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual return std::make_shared(std::move(compressed)); }; - if (narinfoCompression != "" && path.ends_with(".narinfo")) - uploadFile(path, compress(narinfoCompression), mimeType, narinfoCompression); - else if (lsCompression != "" && path.ends_with(".ls")) - uploadFile(path, compress(lsCompression), mimeType, lsCompression); - else if (logCompression != "" && path.starts_with("log/")) - uploadFile(path, compress(logCompression), mimeType, logCompression); + if (config().narinfoCompression != "" && path.ends_with(".narinfo")) { + uploadFile( + path, compress(config().narinfoCompression), mimeType, config().narinfoCompression + ); + } else if (config().lsCompression != "" && path.ends_with(".ls")) { + uploadFile(path, compress(config().lsCompression), mimeType, config().lsCompression); + } else if (config().logCompression != "" && path.starts_with("log/")) + uploadFile(path, compress(config().logCompression), mimeType, config().logCompression); else uploadFile(path, istream, mimeType, ""); } @@ -504,7 +506,9 @@ struct S3BinaryCacheStoreImpl : virtual S3BinaryCacheStoreConfig, public virtual for (auto object : contents) { auto & key = object.GetKey(); if (key.size() != 40 || !key.ends_with(".narinfo")) continue; - paths.insert(parseStorePath(storeDir + "/" + key.substr(0, key.size() - 8) + "-" + MissingName)); + paths.insert(parseStorePath( + config().storeDir + "/" + key.substr(0, key.size() - 8) + "-" + MissingName + )); } marker = res.GetNextMarker(); diff --git a/lix/libstore/s3-binary-cache-store.hh b/lix/libstore/s3-binary-cache-store.hh index dc2877caf..9bedaad50 100644 --- a/lix/libstore/s3-binary-cache-store.hh +++ b/lix/libstore/s3-binary-cache-store.hh @@ -11,7 +11,7 @@ class S3BinaryCacheStore : public virtual BinaryCacheStore { protected: - S3BinaryCacheStore(const Params & params); + using BinaryCacheStore::BinaryCacheStore; public: diff --git a/lix/libstore/ssh-store.cc b/lix/libstore/ssh-store.cc index 1fea4e5a1..65bb28ddb 100644 --- a/lix/libstore/ssh-store.cc +++ b/lix/libstore/ssh-store.cc @@ -27,27 +27,29 @@ struct SSHStoreConfig : virtual RemoteStoreConfig, virtual CommonSSHStoreConfig } }; -class SSHStore : public virtual SSHStoreConfig, public virtual RemoteStore +class SSHStore : public virtual RemoteStore { + SSHStoreConfig config_; + public: - SSHStore(const std::string & scheme, const std::string & host, const Params & params) - : StoreConfig(params) - , RemoteStoreConfig(params) - , CommonSSHStoreConfig(params) - , SSHStoreConfig(params) - , Store(params) - , RemoteStore(params) + SSHStore(const std::string & scheme, const std::string & host, SSHStoreConfig config) + : Store(config) + , RemoteStore(config) + , config_(std::move(config)) , host(host) , master( host, - sshKey, - sshPublicHostKey, + config_.sshKey, + config_.sshPublicHostKey, // Use SSH master only if using more than 1 connection. connections->capacity() > 1, - compress) + config_.compress) { } + SSHStoreConfig & config() override { return config_; } + const SSHStoreConfig & config() const override { return config_; } + static std::set uriSchemes() { return {"ssh-ng"}; } std::string getUri() override @@ -92,9 +94,9 @@ ref SSHStore::openConnection() { auto conn = make_ref(); - std::string command = remoteProgram + " --stdio"; - if (remoteStore.get() != "") - command += " --store " + shellEscape(remoteStore.get()); + std::string command = config_.remoteProgram + " --stdio"; + if (config_.remoteStore.get() != "") + command += " --store " + shellEscape(config_.remoteStore.get()); conn->sshConn = master.startCommand(command); conn->to = FdSink(conn->sshConn->in.get()); diff --git a/lix/libstore/store-api.cc b/lix/libstore/store-api.cc index 1987012c3..08cde6e99 100644 --- a/lix/libstore/store-api.cc +++ b/lix/libstore/store-api.cc @@ -32,7 +32,7 @@ BuildMode buildModeFromInteger(int raw) { bool Store::isInStore(PathView path) const { - return isInDir(path, storeDir); + return isInDir(path, config().storeDir); } @@ -40,7 +40,7 @@ std::pair Store::toStorePath(PathView path) const { if (!isInStore(path)) throw Error("path '%1%' is not in the Nix store", path); - auto slash = path.find('/', storeDir.size() + 1); + auto slash = path.find('/', config().storeDir.size() + 1); if (slash == Path::npos) return {parseStorePath(path), ""}; else @@ -155,7 +155,7 @@ StorePath Store::makeStorePath(std::string_view type, { /* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */ auto s = std::string(type) + ":" + std::string(hash) - + ":" + storeDir + ":" + std::string(name); + + ":" + config().storeDir + ":" + std::string(name); auto h = compressHash(hashString(HashType::SHA256, s), 20); return StorePath(h, name); } @@ -524,9 +524,7 @@ StringSet StoreConfig::getDefaultSystemFeatures() return res; } -Store::Store(const Params & params) - : StoreConfig(params) - , state({(size_t) pathInfoCacheSize}) +Store::Store(const StoreConfig & config) : state({(size_t) config.pathInfoCacheSize}) { assertLibStoreInitialized(); } @@ -622,18 +620,21 @@ void Store::querySubstitutablePathInfos(const StorePathCAMap & paths, Substituta subPath = makeFixedOutputPathFromCA( path.first.name(), ContentAddressWithReferences::withoutRefs(*path.second)); - if (sub->storeDir == storeDir) + if (sub->config().storeDir == config().storeDir) assert(subPath == path.first); if (subPath != path.first) debug("replaced path '%s' with '%s' for substituter '%s'", printStorePath(path.first), sub->printStorePath(subPath), sub->getUri()); - } else if (sub->storeDir != storeDir) continue; + } else if (sub->config().storeDir != config().storeDir) continue; debug("checking substituter '%s' for path '%s'", sub->getUri(), sub->printStorePath(subPath)); try { auto info = sub->queryPathInfo(subPath); - if (sub->storeDir != storeDir && !(info->isContentAddressed(*sub) && info->references.empty())) + if (sub->config().storeDir != config().storeDir + && !(info->isContentAddressed(*sub) && info->references.empty())) + { continue; + } auto narInfo = std::dynamic_pointer_cast( std::shared_ptr(info)); @@ -1090,7 +1091,7 @@ void copyStorePath( info2->path = dstStore.makeFixedOutputPathFromCA( info->path.name(), info->contentAddressWithReferences().value()); - if (dstStore.storeDir == srcStore.storeDir) + if (dstStore.config().storeDir == srcStore.config().storeDir) assert(info->path == info2->path); info = info2; } @@ -1205,7 +1206,7 @@ std::map copyPaths( storePathForDst = dstStore.makeFixedOutputPathFromCA( currentPathInfo.path.name(), currentPathInfo.contentAddressWithReferences().value()); - if (dstStore.storeDir == srcStore.storeDir) + if (dstStore.config().storeDir == srcStore.config().storeDir) assert(storePathForDst == storePathForSrc); if (storePathForDst != storePathForSrc) debug("replaced path '%s' to '%s' for substituter '%s'", @@ -1402,10 +1403,10 @@ Derivation Store::readInvalidDerivation(const StorePath & drvPath) namespace nix { /* Split URI into protocol+hierarchy part and its parameter set. */ -std::pair splitUriAndParams(const std::string & uri_) +std::pair splitUriAndParams(const std::string & uri_) { auto uri(uri_); - Store::Params params; + StoreConfig::Params params; auto q = uri.find('?'); if (q != std::string::npos) { params = decodeQuery(uri.substr(q + 1)); @@ -1424,7 +1425,7 @@ static bool isNonUriPath(const std::string & spec) && spec.find("/") != std::string::npos; } -std::shared_ptr openFromNonUri(const std::string & uri, const Store::Params & params) +std::shared_ptr openFromNonUri(const std::string & uri, const StoreConfig::Params & params) { if (uri == "" || uri == "auto") { auto stateDir = getOr(params, "state", settings.nixStateDir); @@ -1452,7 +1453,7 @@ std::shared_ptr openFromNonUri(const std::string & uri, const Store::Para warn("'%s' does not exist, so Lix will use '%s' as a chroot store", stateDir, chrootStore); } else debug("'%s' does not exist, so Lix will use '%s' as a chroot store", stateDir, chrootStore); - Store::Params chrootStoreParams; + StoreConfig::Params chrootStoreParams; chrootStoreParams["root"] = chrootStore; // FIXME? this ignores *all* store parameters passed to this function? return LocalStore::makeLocalStore(chrootStoreParams); @@ -1465,7 +1466,7 @@ std::shared_ptr openFromNonUri(const std::string & uri, const Store::Para } else if (uri == "local") { return LocalStore::makeLocalStore(params); } else if (isNonUriPath(uri)) { - Store::Params params2 = params; + StoreConfig::Params params2 = params; params2["root"] = absPath(uri); return LocalStore::makeLocalStore(params2); } else { @@ -1502,7 +1503,7 @@ static std::string extractConnStr(const std::string &proto, const std::string &c } ref openStore(const std::string & uri_, - const Store::Params & extraParams) + const StoreConfig::Params & extraParams) { auto params = extraParams; try { @@ -1518,9 +1519,9 @@ ref openStore(const std::string & uri_, if (implem.uriSchemes.count(parsedUri.scheme)) { auto store = implem.create(parsedUri.scheme, baseURI, params); if (store) { - experimentalFeatureSettings.require(store->experimentalFeature()); + experimentalFeatureSettings.require(store->config().experimentalFeature()); store->init(); - store->warnUnknownSettings(); + store->config().warnUnknownSettings(); return ref(store); } } @@ -1531,7 +1532,7 @@ ref openStore(const std::string & uri_, params.insert(uriParams.begin(), uriParams.end()); if (auto store = openFromNonUri(uri, params)) { - store->warnUnknownSettings(); + store->config().warnUnknownSettings(); return ref(store); } } @@ -1559,7 +1560,7 @@ std::list> getDefaultSubstituters() addStore(uri); stores.sort([](ref & a, ref & b) { - return a->priority < b->priority; + return a->config().priority < b->config().priority; }); return stores; diff --git a/lix/libstore/store-api.hh b/lix/libstore/store-api.hh index 299048dac..21ab07f70 100644 --- a/lix/libstore/store-api.hh +++ b/lix/libstore/store-api.hh @@ -43,11 +43,11 @@ namespace nix { * of it) and inherit the constructors of `StoreConfig` * (`using StoreConfig::StoreConfig`). * - * 2. A class `Foo : virtual Store, virtual FooConfig` that contains the + * 2. A class `Foo : virtual Store` that contains the * implementation of the store. * - * This class is expected to have a constructor `Foo(const Params & params)` - * that calls `StoreConfig(params)` (otherwise you're gonna encounter an + * This class is expected to have a constructor `Foo(FooConfig config)` + * that calls `StoreConfig(config)` (otherwise you're gonna encounter an * `assertion failure` when trying to instantiate it). * * You can then register the new store by defining a registration function @@ -181,7 +181,7 @@ struct StoreConfig : public Config false}; }; -class Store : public std::enable_shared_from_this, public virtual StoreConfig +class Store : public std::enable_shared_from_this { protected: @@ -221,7 +221,7 @@ protected: std::shared_ptr diskCache; - Store(const Params & params); + Store(const StoreConfig & config); public: /** @@ -230,6 +230,9 @@ public: */ virtual void init() {}; + virtual StoreConfig & config() = 0; + virtual const StoreConfig & config() const = 0; + virtual ~Store() noexcept(false) { } virtual std::string getUri() = 0; @@ -986,7 +989,7 @@ OutputPathMap resolveDerivedPath(Store &, const DerivedPath::Built &, Store * ev * ‘?key=value&key=value&...’ to the URI. */ ref openStore(const std::string & uri = settings.storeUri.get(), - const Store::Params & extraParams = Store::Params()); + const StoreConfig::Params & extraParams = {}); /** @@ -998,7 +1001,13 @@ std::list> getDefaultSubstituters(); struct StoreFactory { std::set uriSchemes; - std::function (const std::string & scheme, const std::string & uri, const Store::Params & params)> create; + std::function< + std::shared_ptr ( + const std::string & scheme, + const std::string & uri, + const StoreConfig::Params & params + ) + > create; std::function ()> getConfig; }; @@ -1013,7 +1022,7 @@ struct StoreImplementations StoreFactory factory{ .uriSchemes = T::uriSchemes(), .create = - ([](const std::string & scheme, const std::string & uri, const Store::Params & params) + ([](const std::string & scheme, const std::string & uri, const StoreConfig::Params & params) -> std::shared_ptr { return std::make_shared(scheme, uri, params); }), .getConfig = @@ -1041,7 +1050,7 @@ std::optional decodeValidPathInfo( /** * Split URI into protocol+hierarchy part and its parameter set. */ -std::pair splitUriAndParams(const std::string & uri); +std::pair splitUriAndParams(const std::string & uri); const ContentAddress * getDerivationCA(const BasicDerivation & drv); diff --git a/lix/libstore/uds-remote-store.cc b/lix/libstore/uds-remote-store.cc index b2562db2f..d3153ff1a 100644 --- a/lix/libstore/uds-remote-store.cc +++ b/lix/libstore/uds-remote-store.cc @@ -22,15 +22,10 @@ std::string UDSRemoteStoreConfig::doc() ; } - -UDSRemoteStore::UDSRemoteStore(const Params & params) - : StoreConfig(params) - , LocalFSStoreConfig(params) - , RemoteStoreConfig(params) - , UDSRemoteStoreConfig(params) - , Store(params) - , LocalFSStore(params) - , RemoteStore(params) +UDSRemoteStore::UDSRemoteStore(UDSRemoteStoreConfig config) + : Store(config) + , RemoteStore(config) + , config_(std::move(config)) { } @@ -38,8 +33,8 @@ UDSRemoteStore::UDSRemoteStore(const Params & params) UDSRemoteStore::UDSRemoteStore( const std::string scheme, std::string socket_path, - const Params & params) - : UDSRemoteStore(params) + UDSRemoteStoreConfig config) + : UDSRemoteStore(std::move(config)) { path.emplace(socket_path); } diff --git a/lix/libstore/uds-remote-store.hh b/lix/libstore/uds-remote-store.hh index 69591f5f8..fbc8fa2e1 100644 --- a/lix/libstore/uds-remote-store.hh +++ b/lix/libstore/uds-remote-store.hh @@ -21,14 +21,18 @@ struct UDSRemoteStoreConfig : virtual LocalFSStoreConfig, virtual RemoteStoreCon std::string doc() override; }; -class UDSRemoteStore : public virtual UDSRemoteStoreConfig - , public virtual IndirectRootStore +class UDSRemoteStore : public virtual IndirectRootStore , public virtual RemoteStore { + UDSRemoteStoreConfig config_; + public: - UDSRemoteStore(const Params & params); - UDSRemoteStore(const std::string scheme, std::string path, const Params & params); + UDSRemoteStore(UDSRemoteStoreConfig config); + UDSRemoteStore(const std::string scheme, std::string path, UDSRemoteStoreConfig config); + + UDSRemoteStoreConfig & config() override { return config_; } + const UDSRemoteStoreConfig & config() const override { return config_; } std::string getUri() override; diff --git a/lix/nix/daemon.cc b/lix/nix/daemon.cc index 23811ef76..0fe089e7f 100644 --- a/lix/nix/daemon.cc +++ b/lix/nix/daemon.cc @@ -204,7 +204,7 @@ static PeerInfo getPeerInfo(int remote) */ static ref openUncachedStore() { - Store::Params params; // FIXME: get params from somewhere + StoreConfig::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); diff --git a/lix/nix/run.cc b/lix/nix/run.cc index 4e16a8045..a490dc7f7 100644 --- a/lix/nix/run.cc +++ b/lix/nix/run.cc @@ -48,8 +48,14 @@ void runProgramInStore(ref store, if (!store2) throw Error("store '%s' is not a local store so it does not support command execution", store->getUri()); - if (store->storeDir != store2->getRealStoreDir()) { - Strings helperArgs = { chrootHelperName, store->storeDir, store2->getRealStoreDir(), std::string(system.value_or("")), program }; + if (store->config().storeDir != store2->getRealStoreDir()) { + Strings helperArgs = { + chrootHelperName, + store->config().storeDir, + store2->getRealStoreDir(), + std::string(system.value_or("")), + program + }; for (auto & arg : args) helperArgs.push_back(arg); execv(getSelfExe().value_or("nix").c_str(), stringsToCharPtrs(helperArgs).data()); diff --git a/tests/unit/libstore/path.cc b/tests/unit/libstore/path.cc index e8cc1b80a..830f2828f 100644 --- a/tests/unit/libstore/path.cc +++ b/tests/unit/libstore/path.cc @@ -142,7 +142,7 @@ RC_GTEST_FIXTURE_PROP( auto name = *nameFuzzer; - std::string path = store->storeDir + "/575s52sh487i0ylmbs9pvi606ljdszr0-" + name; + std::string path = store->config().storeDir + "/575s52sh487i0ylmbs9pvi606ljdszr0-" + name; bool parsed = false; try { store->parseStorePath(path);