#include "local-binary-cache-store.hh" #include "binary-cache-store.hh" #include "globals.hh" #include "nar-info-disk-cache.hh" #include namespace nix { struct LocalBinaryCacheStoreConfig : virtual BinaryCacheStoreConfig { using BinaryCacheStoreConfig::BinaryCacheStoreConfig; const std::string name() override { return "Local Binary Cache Store"; } std::string doc() override { return #include "local-binary-cache-store.md" ; } }; class LocalBinaryCacheStore : public virtual LocalBinaryCacheStoreConfig, public virtual BinaryCacheStore { private: Path binaryCacheDir; public: LocalBinaryCacheStore( const std::string scheme, const Path & binaryCacheDir, const Params & params) : StoreConfig(params) , BinaryCacheStoreConfig(params) , LocalBinaryCacheStoreConfig(params) , Store(params) , BinaryCacheStore(params) , binaryCacheDir(binaryCacheDir) { } void init() override; std::string getUri() override { return "file://" + binaryCacheDir; } static std::set uriSchemes(); protected: bool fileExists(const std::string & path) override; void upsertFile(const std::string & path, std::shared_ptr> istream, const std::string & mimeType) override { auto path2 = binaryCacheDir + "/" + path; static std::atomic counter{0}; Path tmp = fmt("%s.tmp.%d.%d", path2, getpid(), ++counter); AutoDelete del(tmp, false); StreamToSourceAdapter source(istream); writeFile(tmp, source); renameFile(tmp, path2); del.cancel(); } box_ptr getFile(const std::string & path) override { try { return make_box_ptr(readFileSource(binaryCacheDir + "/" + path)); } catch (SysError & e) { if (e.errNo == ENOENT) throw NoSuchBinaryCacheFile("file '%s' does not exist in binary cache", path); throw; } } StorePathSet queryAllValidPaths() override { StorePathSet paths; for (auto & entry : readDirectory(binaryCacheDir)) { if (entry.name.size() != 40 || !entry.name.ends_with(".narinfo")) continue; paths.insert(parseStorePath( storeDir + "/" + entry.name.substr(0, entry.name.size() - 8) + "-" + MissingName)); } return paths; } std::optional isTrustedClient() override { return Trusted; } }; void LocalBinaryCacheStore::init() { createDirs(binaryCacheDir + "/nar"); createDirs(binaryCacheDir + "/" + realisationsPrefix); if (writeDebugInfo) createDirs(binaryCacheDir + "/debuginfo"); createDirs(binaryCacheDir + "/log"); BinaryCacheStore::init(); } bool LocalBinaryCacheStore::fileExists(const std::string & path) { return pathExists(binaryCacheDir + "/" + path); } std::set LocalBinaryCacheStore::uriSchemes() { if (getEnv("_NIX_FORCE_HTTP") == "1") return {}; else return {"file"}; } void registerLocalBinaryCacheStore() { StoreImplementations::add(); } }