From d3e8d2e4c4ab45b09956d6b4ddecc3ec06ef17b1 Mon Sep 17 00:00:00 2001 From: Ryan Mulligan Date: Wed, 7 Jun 2023 22:20:49 -0700 Subject: [PATCH 1/3] wip local-cache-store --- src/libstore/local-cache-store.cc | 92 +++++++++++++++++++++++++++++++ src/libstore/local-cache-store.hh | 77 ++++++++++++++++++++++++++ src/libstore/store-api.cc | 3 + test.sh | 34 ++++++++++++ 4 files changed, 206 insertions(+) create mode 100644 src/libstore/local-cache-store.cc create mode 100644 src/libstore/local-cache-store.hh create mode 100755 test.sh diff --git a/src/libstore/local-cache-store.cc b/src/libstore/local-cache-store.cc new file mode 100644 index 000000000000..d10b1596ec85 --- /dev/null +++ b/src/libstore/local-cache-store.cc @@ -0,0 +1,92 @@ +#include "archive.hh" +#include "local-cache-store.hh" +#include "callback.hh" +#include "url.hh" +#include + +namespace nix { + +LocalCacheStore::LocalCacheStore(const Params & params) + : StoreConfig(params) + , LocalFSStoreConfig(params) + , LocalCacheStoreConfig(params) + , Store(params) + , LocalFSStore(params) +{ +} + +LocalCacheStore::LocalCacheStore(std::string scheme, std::string path, const Params & params) + : LocalCacheStore(params) +{ + debug("LocalCacheStore"); + for (const auto& [key, value] : params) + debug("params[%s] = %s", key, value); + debug("rootDir: %s", this->rootDir.get()); + debug("realStoreDir: %s", this->realStoreDir.get()); +} + +void LocalCacheStore::narFromPath(const StorePath & path, Sink & sink) +{ + debug("narFromPath"); + if (!isValidPath(path)) + throw Error("path '%s' is not valid", printStorePath(path)); + auto pathToDump = std::string(printStorePath(path), storeDir.size()); + dumpPath(pathToDump, sink); +} + +void LocalCacheStore::queryPathInfoUncached( + const StorePath & path, Callback> callback) noexcept +{ + debug("queryPathInfoUncached"); + auto callbackPtr = std::make_shared(std::move(callback)); + try + { + debug("LocalCacheStore.queryPathInfoUncached storePath: %s", printStorePath(path)); + auto narinfo_path = std::string{path.hashPart()} + ".narinfo"; + auto real_narinfo_path = this->rootDir + "/nix/store/" + narinfo_path; + debug("LocalCacheStore.queryPathInfoUncached: %s", narinfo_path); + try { + auto narinfo_str = nix::readFile(real_narinfo_path); + debug("LocalCacheStore.queryPathInfoUncached read success"); + debug(narinfo_str); + debug(narinfo_path); + auto validPathInfo = (std::shared_ptr)std::make_shared(*this, narinfo_str, narinfo_path); + return (*callbackPtr)(std::move(validPathInfo)); + } catch (SysError &) { + debug("LocalCacheStore.queryPathInfoUncached error storePath: %s", printStorePath(path)); + return (*callbackPtr)({}); + } + } catch (...) { + debug("LocalCacheStore.queryPathInfoUncached error storePath: %s", printStorePath(path)); + return callbackPtr->rethrow(); + } +} + +// Unimplemented methods +std::optional LocalCacheStore::queryPathFromHashPart(const std::string & hashPart) +{ unsupported("queryPathFromHashPart"); } +void LocalCacheStore::addToStore(const ValidPathInfo & info, Source & source, + RepairFlag repair, CheckSigsFlag checkSigs) +{ unsupported("addToStore"); } +StorePath LocalCacheStore::addTextToStore( + std::string_view name, + std::string_view s, + const StorePathSet & references, + RepairFlag repair) +{ unsupported("addTextToStore"); } +void LocalCacheStore::queryRealisationUncached(const DrvOutput & drvOutput, + Callback> callback) noexcept +{ unsupported("queryRealisationUncached"); } +std::optional LocalCacheStore::isTrustedClient() +{ unsupported("isTrustedClient"); } +void LocalCacheStore::addIndirectRoot(const Path & path) +{ unsupported("addIndirectRoot"); } +Roots LocalCacheStore::findRoots(bool censor) +{ unsupported("findRoots"); } +void LocalCacheStore::collectGarbage(const GCOptions & options, GCResults & results) +{ unsupported("colelctGarbage"); } +void LocalCacheStore::addBuildLog(const StorePath & path, std::string_view log) +{ unsupported("addBuildLog"); } + +static RegisterStoreImplementation regLocalCacheStore; +} diff --git a/src/libstore/local-cache-store.hh b/src/libstore/local-cache-store.hh new file mode 100644 index 000000000000..fed447141a39 --- /dev/null +++ b/src/libstore/local-cache-store.hh @@ -0,0 +1,77 @@ +#include "local-store.hh" + +namespace nix { + +/** + * Configuration for `LocalCacheStore`. + */ +struct LocalCacheStoreConfig : virtual LocalFSStoreConfig +{ + LocalCacheStoreConfig(const StringMap & params) + : StoreConfig(params) + , LocalFSStoreConfig(params) + { } + + const std::string name() override { return "Experimental Local Cache Store"; } + + std::string doc() override + { + return + "" + // FIXME write docs + //#include "local-cache-store.md" + ; + } + +}; + +/** + * Variation of local store that uses a using overlayfs for the store dir. + */ +class LocalCacheStore : public virtual LocalCacheStoreConfig, public virtual LocalFSStore +{ + +public: + LocalCacheStore(const Params & params); + + LocalCacheStore(std::string scheme, std::string path, const Params & params); + + static std::set uriSchemes() + { return { "local-cache" }; } + + std::string getUri() override + { + return "local-cache"; + } + +private: + // Overridden methods… + + void narFromPath(const StorePath & path, Sink & sink) override; + + void queryPathInfoUncached(const StorePath & path, + Callback> callback) noexcept override; + + std::optional queryPathFromHashPart(const std::string & hashPart); + + void addToStore(const ValidPathInfo & info, Source & source, + RepairFlag repair, CheckSigsFlag checkSigs); + + StorePath addTextToStore( + std::string_view name, + std::string_view s, + const StorePathSet & references, + RepairFlag repair); + + void queryRealisationUncached(const DrvOutput & drvOutput, + Callback> callback) noexcept; + + std::optional isTrustedClient(); + void addIndirectRoot(const Path & path); + Roots findRoots(bool censor); + void collectGarbage(const GCOptions & options, GCResults & results); + void addBuildLog(const StorePath & path, std::string_view log); + +}; + +} diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 1863a08763ee..a3b062611ae1 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -12,6 +12,7 @@ #include "callback.hh" #include "remote-store.hh" #include "local-overlay-store.hh" +#include "local-cache-store.hh" #include #include @@ -1447,6 +1448,8 @@ std::shared_ptr openFromNonUri(const std::string & uri, const Store::Para auto store = std::make_shared(params); experimentalFeatureSettings.require(store->experimentalFeature()); return store; + } else if (uri == "local-cache") { + return std::make_shared(params); } else if (isNonUriPath(uri)) { Store::Params params2 = params; params2["root"] = absPath(uri); diff --git a/test.sh b/test.sh new file mode 100755 index 000000000000..3222d774d84e --- /dev/null +++ b/test.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -xeuo pipefail + +flakes="--extra-experimental-features nix-command --extra-experimental-features flakes" + +make -j $NIX_BUILD_CORES + +sudo umount /tmp/nix/store +#trap 'sudo umount /tmp/nix/store' EXIT + +sudo rm -rf /tmp/nix +sudo rm -rf /tmp/nix-upper +sudo rm -rf /tmp/nix-work +mkdir -p /tmp/nix/store +mkdir -p /tmp/nix-upper +mkdir -p /tmp/nix-work + +sudo mount -t overlay overlay \ + -o lowerdir="/var/lib/ersa/nix/store" \ + -o upperdir="/tmp/nix-upper" \ + -o workdir="/tmp/nix-work" \ + "/tmp/nix/store" \ + +./outputs/out/bin/nix build -vvvv -L --builders '' --max-jobs 0 --show-trace --extra-experimental-features 'nix-command flakes' --store 'local-overlay?root=/tmp&lower-store=local-cache:%3Froot=%2Fvar%2Flib%2Fersa&upper-layer=/tmp/nix-upper' 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' + +# sudo umount /tmp/nix/store + +# sudo mount -t overlay overlay \ +# -o lowerdir="/nix/store" \ +# -o upperdir="/tmp/nix-upper" \ +# -o workdir="/tmp/nix-work" \ +# "/tmp/nix/store" \ + +# ./outputs/out/bin/nix build -L --extra-experimental-features 'nix-command flakes' --store 'local-overlay?root=/tmp&lower-store=&upper-layer=/tmp/nix-upper' 'nixpkgs#hello' From 3e0a3db4b8c11117fe1111bad163be14ee4cb89a Mon Sep 17 00:00:00 2001 From: Ryan Mulligan Date: Thu, 8 Jun 2023 11:27:52 -0700 Subject: [PATCH 2/3] more self-contained test --- test.sh | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/test.sh b/test.sh index 3222d774d84e..17a8c01c773b 100755 --- a/test.sh +++ b/test.sh @@ -5,23 +5,46 @@ flakes="--extra-experimental-features nix-command --extra-experimental-features make -j $NIX_BUILD_CORES -sudo umount /tmp/nix/store +sudo umount /tmp/nix/store || true #trap 'sudo umount /tmp/nix/store' EXIT sudo rm -rf /tmp/nix sudo rm -rf /tmp/nix-upper sudo rm -rf /tmp/nix-work +sudo rm -rf /tmp/nix-lower mkdir -p /tmp/nix/store mkdir -p /tmp/nix-upper mkdir -p /tmp/nix-work +mkdir -p /tmp/nix-lower/nix/store + +export NIX_CONFIG="extra-experimental-features = nix-command flakes" + +nix build 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' + +helloOutPath=$(nix eval --raw 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello.outPath') + +cp -r --parents "${helloOutPath}" /tmp/nix-lower/ +curl https://cache.nixos.org/2g3jazymqbjw9c390c3b7vw8xq3r8iny.narinfo -o /tmp/nix-lower/nix/store/2g3jazymqbjw9c390c3b7vw8xq3r8iny.narinfo + +ls -la /tmp/nix-lower/nix/store/ + sudo mount -t overlay overlay \ - -o lowerdir="/var/lib/ersa/nix/store" \ + -o lowerdir="/tmp/nix-lower/nix/store" \ -o upperdir="/tmp/nix-upper" \ -o workdir="/tmp/nix-work" \ "/tmp/nix/store" \ -./outputs/out/bin/nix build -vvvv -L --builders '' --max-jobs 0 --show-trace --extra-experimental-features 'nix-command flakes' --store 'local-overlay?root=/tmp&lower-store=local-cache:%3Froot=%2Fvar%2Flib%2Fersa&upper-layer=/tmp/nix-upper' 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' +./outputs/out/bin/nix build -vvvv -L --builders '' --max-jobs 0 --show-trace --store 'local-overlay?root=/tmp&lower-store=local-cache:%3Froot=%2Ftmp%2Fnix-lower&upper-layer=/tmp/nix-upper' 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' + +# ersa version +# sudo mount -t overlay overlay \ +# -o lowerdir="/var/lib/ersa/nix/store" \ +# -o upperdir="/tmp/nix-upper" \ +# -o workdir="/tmp/nix-work" \ +# "/tmp/nix/store" \ +#./outputs/out/bin/nix build -vvvv -L --builders '' --max-jobs 0 --show-trace --store 'local-overlay?root=/tmp&lower-store=local-cache:%3Froot=%2Fvar%2Flib%2Fersa&upper-layer=/tmp/nix-upper' 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' + # sudo umount /tmp/nix/store From f715a59c11ef6fa691c1b23af1e588e8229365c4 Mon Sep 17 00:00:00 2001 From: Ryan Mulligan Date: Thu, 8 Jun 2023 15:31:06 -0700 Subject: [PATCH 3/3] sudo --- src/libstore/local-cache-store.cc | 2 +- test.sh | 54 +++++++++++++++---------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/libstore/local-cache-store.cc b/src/libstore/local-cache-store.cc index d10b1596ec85..660c00ea1111 100644 --- a/src/libstore/local-cache-store.cc +++ b/src/libstore/local-cache-store.cc @@ -43,7 +43,7 @@ void LocalCacheStore::queryPathInfoUncached( { debug("LocalCacheStore.queryPathInfoUncached storePath: %s", printStorePath(path)); auto narinfo_path = std::string{path.hashPart()} + ".narinfo"; - auto real_narinfo_path = this->rootDir + "/nix/store/" + narinfo_path; + auto real_narinfo_path = this->realStoreDir.get() + narinfo_path; debug("LocalCacheStore.queryPathInfoUncached: %s", narinfo_path); try { auto narinfo_str = nix::readFile(real_narinfo_path); diff --git a/test.sh b/test.sh index 17a8c01c773b..24aae04e9124 100755 --- a/test.sh +++ b/test.sh @@ -19,39 +19,37 @@ mkdir -p /tmp/nix-lower/nix/store export NIX_CONFIG="extra-experimental-features = nix-command flakes" -nix build 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' - -helloOutPath=$(nix eval --raw 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello.outPath') - -cp -r --parents "${helloOutPath}" /tmp/nix-lower/ -curl https://cache.nixos.org/2g3jazymqbjw9c390c3b7vw8xq3r8iny.narinfo -o /tmp/nix-lower/nix/store/2g3jazymqbjw9c390c3b7vw8xq3r8iny.narinfo +# static lower dir +# +# nix build 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' +# +# helloOutPath=$(nix eval --raw 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello.outPath') +# +# cp -r --parents "${helloOutPath}" /tmp/nix-lower/ +# curl https://cache.nixos.org/2g3jazymqbjw9c390c3b7vw8xq3r8iny.narinfo -o /tmp/nix-lower/nix/store/2g3jazymqbjw9c390c3b7vw8xq3r8iny.narinfo +# +# ls -la /tmp/nix-lower/nix/store/ +# +# sudo mount -t overlay overlay \ +# -o lowerdir="/tmp/nix-lower/nix/store" \ +# -o upperdir="/tmp/nix-upper" \ +# -o workdir="/tmp/nix-work" \ +# "/tmp/nix/store" -ls -la /tmp/nix-lower/nix/store/ +# ./outputs/out/bin/nix build -vvvv -L --builders '' --max-jobs 0 --show-trace --store 'local-overlay?root=/tmp&lower-store=local-cache:%3Froot=%2Ftmp%2Fnix-lower&upper-layer=/tmp/nix-upper' 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' +# ersa version sudo mount -t overlay overlay \ - -o lowerdir="/tmp/nix-lower/nix/store" \ + -o lowerdir="/var/lib/ersa/nix/store" \ -o upperdir="/tmp/nix-upper" \ -o workdir="/tmp/nix-work" \ - "/tmp/nix/store" \ - -./outputs/out/bin/nix build -vvvv -L --builders '' --max-jobs 0 --show-trace --store 'local-overlay?root=/tmp&lower-store=local-cache:%3Froot=%2Ftmp%2Fnix-lower&upper-layer=/tmp/nix-upper' 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' + "/tmp/nix/store" -# ersa version -# sudo mount -t overlay overlay \ -# -o lowerdir="/var/lib/ersa/nix/store" \ -# -o upperdir="/tmp/nix-upper" \ -# -o workdir="/tmp/nix-work" \ -# "/tmp/nix/store" \ -#./outputs/out/bin/nix build -vvvv -L --builders '' --max-jobs 0 --show-trace --store 'local-overlay?root=/tmp&lower-store=local-cache:%3Froot=%2Fvar%2Flib%2Fersa&upper-layer=/tmp/nix-upper' 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello' - - -# sudo umount /tmp/nix/store - -# sudo mount -t overlay overlay \ -# -o lowerdir="/nix/store" \ -# -o upperdir="/tmp/nix-upper" \ -# -o workdir="/tmp/nix-work" \ -# "/tmp/nix/store" \ +outPath=$(sudo -E ./outputs/out/bin/nix eval --raw -vvvv -L --show-trace --store 'local-overlay?root=/tmp&lower-store=local-cache:%3Froot=%2Fvar%2Flib%2Fersa&upper-layer=/tmp/nix-upper' 'github:nixos/nixpkgs/af21c31b2a1ec5d361ed8050edd0303c31306397#hello.outPath') -# ./outputs/out/bin/nix build -L --extra-experimental-features 'nix-command flakes' --store 'local-overlay?root=/tmp&lower-store=&upper-layer=/tmp/nix-upper' 'nixpkgs#hello' +if [ "$outPath" = "/nix/store/2g3jazymqbjw9c390c3b7vw8xq3r8iny-hello-2.12.1" ]; then + echo "succeess" +else + echo "failure" +fi