#include <utility> #include <absl/strings/match.h> #include "libstore/binary-cache-store.hh" #include "libstore/globals.hh" #include "libstore/nar-info-disk-cache.hh" namespace nix { class LocalBinaryCacheStore : public BinaryCacheStore { private: Path binaryCacheDir; public: LocalBinaryCacheStore(const Params& params, Path binaryCacheDir) : BinaryCacheStore(params), binaryCacheDir(std::move(binaryCacheDir)) {} void init() override; std::string getUri() override { return "file://" + binaryCacheDir; } protected: bool fileExists(const std::string& path) override; void upsertFile(const std::string& path, const std::string& data, const std::string& mimeType) override; void getFile(const std::string& path, Sink& sink) override { try { readFile(binaryCacheDir + "/" + path, sink); } catch (SysError& e) { if (e.errNo == ENOENT) { throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache", path); } } } PathSet queryAllValidPaths() override { PathSet paths; for (auto& entry : readDirectory(binaryCacheDir)) { if (entry.name.size() != 40 || !absl::EndsWith(entry.name, ".narinfo")) { continue; } paths.insert(storeDir + "/" + entry.name.substr(0, entry.name.size() - 8)); } return paths; } }; void LocalBinaryCacheStore::init() { createDirs(binaryCacheDir + "/nar"); BinaryCacheStore::init(); } static void atomicWrite(const Path& path, const std::string& s) { Path tmp = path + ".tmp." + std::to_string(getpid()); AutoDelete del(tmp, false); writeFile(tmp, s); if (rename(tmp.c_str(), path.c_str()) != 0) { throw SysError(format("renaming '%1%' to '%2%'") % tmp % path); } del.cancel(); } bool LocalBinaryCacheStore::fileExists(const std::string& path) { return pathExists(binaryCacheDir + "/" + path); } void LocalBinaryCacheStore::upsertFile(const std::string& path, const std::string& data, const std::string& mimeType) { atomicWrite(binaryCacheDir + "/" + path, data); } static RegisterStoreImplementation regStore( [](const std::string& uri, const Store::Params& params) -> std::shared_ptr<Store> { if (getEnv("_NIX_FORCE_HTTP_BINARY_CACHE_STORE") == "1" || std::string(uri, 0, 7) != "file://") { return nullptr; } auto store = std::make_shared<LocalBinaryCacheStore>(params, std::string(uri, 7)); store->init(); return store; }); } // namespace nix