about summary refs log blame commit diff
path: root/third_party/nix/src/libstore/local-binary-cache-store.cc
blob: 4555de5047833d917082a851969510438fba5036 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                  

                               


                                          


               


                                                       
 
        

                                                                              
 
                       
 
                                                                      
 

                                                    
 

                                                                   
 



                                                              
                              

                                                                               
       
     
   
 

                                         
 
                                                       
                                                                               
                 
       

                                                                

     

                 

  


                                      

 



                                                                 
                                               
                                                                   
   
               

 

                                                                 

 



                                                                     

 



                                                                
                                                
                       
       




                                                                               
 
                   
#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