about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/binary-cache-store.cc2
-rw-r--r--src/libstore/binary-cache-store.hh1
-rw-r--r--src/libstore/remote-fs-accessor.cc22
-rw-r--r--src/libstore/remote-fs-accessor.hh5
4 files changed, 25 insertions, 5 deletions
diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc
index 9d497110f621..f1179f1890a0 100644
--- a/src/libstore/binary-cache-store.cc
+++ b/src/libstore/binary-cache-store.cc
@@ -319,7 +319,7 @@ Path BinaryCacheStore::addTextToStore(const string & name, const string & s,
 
 ref<FSAccessor> BinaryCacheStore::getFSAccessor()
 {
-    return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()));
+    return make_ref<RemoteFSAccessor>(ref<Store>(shared_from_this()), localNarCache);
 }
 
 std::shared_ptr<std::string> BinaryCacheStore::getBuildLog(const Path & path)
diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh
index f9c1c2cbe8a8..d3b0e0bd9332 100644
--- a/src/libstore/binary-cache-store.hh
+++ b/src/libstore/binary-cache-store.hh
@@ -18,6 +18,7 @@ public:
     const Setting<std::string> compression{this, "xz", "compression", "NAR compression method ('xz', 'bzip2', or 'none')"};
     const Setting<bool> writeNARListing{this, false, "write-nar-listing", "whether to write a JSON file listing the files in each NAR"};
     const Setting<Path> secretKeyFile{this, "", "secret-key", "path to secret key used to sign the binary cache"};
+    const Setting<Path> localNarCache{this, "", "local-nar-cache", "path to a local cache of NARs"};
 
 private:
 
diff --git a/src/libstore/remote-fs-accessor.cc b/src/libstore/remote-fs-accessor.cc
index 098151f8c0f6..da4e30b22633 100644
--- a/src/libstore/remote-fs-accessor.cc
+++ b/src/libstore/remote-fs-accessor.cc
@@ -3,10 +3,12 @@
 
 namespace nix {
 
-
-RemoteFSAccessor::RemoteFSAccessor(ref<Store> store)
+RemoteFSAccessor::RemoteFSAccessor(ref<Store> store, const Path & cacheDir)
     : store(store)
+    , cacheDir(cacheDir)
 {
+    if (cacheDir != "")
+        createDirs(cacheDir);
 }
 
 std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_)
@@ -23,7 +25,21 @@ std::pair<ref<FSAccessor>, Path> RemoteFSAccessor::fetch(const Path & path_)
     if (i != nars.end()) return {i->second, restPath};
 
     StringSink sink;
-    store->narFromPath(storePath, sink);
+
+    Path cacheFile = cacheDir != "" ? fmt("%s/%s.nar", cacheDir, storePathToHash(storePath)) : "";
+
+    try {
+        if (cacheFile != "")
+            *sink.s = nix::readFile(cacheFile);
+    } catch (SysError &) { }
+
+    if (sink.s->empty()) {
+        store->narFromPath(storePath, sink);
+
+        if (cacheFile != "")
+            /* FIXME: do this asynchronously. */
+            writeFile(cacheFile, *sink.s);
+    }
 
     auto accessor = makeNarAccessor(sink.s);
     nars.emplace(storePath, accessor);
diff --git a/src/libstore/remote-fs-accessor.hh b/src/libstore/remote-fs-accessor.hh
index df8b7b16291e..d359ecc9c871 100644
--- a/src/libstore/remote-fs-accessor.hh
+++ b/src/libstore/remote-fs-accessor.hh
@@ -12,13 +12,16 @@ class RemoteFSAccessor : public FSAccessor
 
     std::map<Path, ref<FSAccessor>> nars;
 
+    Path cacheDir;
+
     std::pair<ref<FSAccessor>, Path> fetch(const Path & path_);
 
     friend class BinaryCacheStore;
 
 public:
 
-    RemoteFSAccessor(ref<Store> store);
+    RemoteFSAccessor(ref<Store> store,
+        const /* FIXME: use std::optional */ Path & cacheDir = "");
 
     Stat stat(const Path & path) override;