about summary refs log tree commit diff
path: root/third_party/nix/src/libstore/local-binary-cache-store.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/nix/src/libstore/local-binary-cache-store.cc')
-rw-r--r--third_party/nix/src/libstore/local-binary-cache-store.cc103
1 files changed, 103 insertions, 0 deletions
diff --git a/third_party/nix/src/libstore/local-binary-cache-store.cc b/third_party/nix/src/libstore/local-binary-cache-store.cc
new file mode 100644
index 0000000000..b7001795be
--- /dev/null
+++ b/third_party/nix/src/libstore/local-binary-cache-store.cc
@@ -0,0 +1,103 @@
+#include "binary-cache-store.hh"
+#include "globals.hh"
+#include "nar-info-disk-cache.hh"
+
+namespace nix {
+
+class LocalBinaryCacheStore : public BinaryCacheStore
+{
+private:
+
+    Path binaryCacheDir;
+
+public:
+
+    LocalBinaryCacheStore(
+        const Params & params, const Path & binaryCacheDir)
+        : BinaryCacheStore(params)
+        , binaryCacheDir(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 ||
+                !hasSuffix(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()))
+        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 0;
+    auto store = std::make_shared<LocalBinaryCacheStore>(params, std::string(uri, 7));
+    store->init();
+    return store;
+});
+
+}