diff options
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/binary-cache-store.cc | 35 | ||||
-rw-r--r-- | src/libstore/binary-cache-store.hh | 3 | ||||
-rw-r--r-- | src/libstore/build.cc | 6 | ||||
-rw-r--r-- | src/libstore/crypto.cc | 11 | ||||
-rw-r--r-- | src/libstore/crypto.hh | 12 | ||||
-rw-r--r-- | src/libstore/http-binary-cache-store.cc | 76 | ||||
-rw-r--r-- | src/libstore/local-binary-cache-store.cc | 24 | ||||
-rw-r--r-- | src/libstore/local-store.cc | 8 | ||||
-rw-r--r-- | src/libstore/store-api.hh | 4 |
9 files changed, 142 insertions, 37 deletions
diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 02e73d2ce1fa..5ded16d028b0 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -14,21 +14,18 @@ namespace nix { BinaryCacheStore::BinaryCacheStore(std::shared_ptr<Store> localStore, - const Path & secretKeyFile, const Path & publicKeyFile) + const Path & secretKeyFile) : localStore(localStore) { - if (secretKeyFile != "") + if (secretKeyFile != "") { secretKey = std::unique_ptr<SecretKey>(new SecretKey(readFile(secretKeyFile))); - - if (publicKeyFile != "") { publicKeys = std::unique_ptr<PublicKeys>(new PublicKeys); - auto key = PublicKey(readFile(publicKeyFile)); - publicKeys->emplace(key.name, key); + publicKeys->emplace(secretKey->name, secretKey->toPublicKey()); } StringSink sink; sink << narVersionMagic1; - narMagic = sink.s; + narMagic = *sink.s; } void BinaryCacheStore::init() @@ -200,14 +197,16 @@ Paths BinaryCacheStore::importPaths(bool requireSignature, Source & source, struct TeeSource : Source { Source & readSource; - std::string data; - TeeSource(Source & readSource) : readSource(readSource) + ref<std::string> data; + TeeSource(Source & readSource) + : readSource(readSource) + , data(make_ref<std::string>()) { } size_t read(unsigned char * data, size_t len) { size_t n = readSource.read(data, len); - this->data.append((char *) data, n); + this->data->append((char *) data, n); return n; } }; @@ -257,7 +256,7 @@ Path BinaryCacheStore::addToStore(const string & name, const Path & srcPath, Hash h; if (recursive) { dumpPath(srcPath, sink, filter); - h = hashString(hashAlgo, sink.s); + h = hashString(hashAlgo, *sink.s); } else { auto s = readFile(srcPath); dumpString(s, sink); @@ -268,7 +267,7 @@ Path BinaryCacheStore::addToStore(const string & name, const Path & srcPath, info.path = makeFixedOutputPath(recursive, hashAlgo, h, name); if (repair || !isValidPath(info.path)) - addToCache(info, sink.s); + addToCache(info, *sink.s); return info.path; } @@ -283,7 +282,7 @@ Path BinaryCacheStore::addTextToStore(const string & name, const string & s, if (repair || !isValidPath(info.path)) { StringSink sink; dumpString(s, sink); - addToCache(info, sink.s); + addToCache(info, *sink.s); } return info.path; @@ -313,7 +312,7 @@ void BinaryCacheStore::buildPaths(const PathSet & paths, BuildMode buildMode) StringSink sink; dumpPath(storePath, sink); - addToCache(info, sink.s); + addToCache(info, *sink.s); } } @@ -352,8 +351,7 @@ struct BinaryCacheStoreAccessor : public FSAccessor StringSink sink; store->exportPath(storePath, false, sink); - // FIXME: gratuitous string copying. - auto accessor = makeNarAccessor(make_ref<std::string>(sink.s)); + auto accessor = makeNarAccessor(sink.s); nars.emplace(storePath, accessor); return {accessor, restPath}; } @@ -412,12 +410,11 @@ Path BinaryCacheStore::importPath(Source & source, std::shared_ptr<FSAccessor> a bool haveSignature = readInt(source) == 1; assert(!haveSignature); - addToCache(info, tee.data); + addToCache(info, *tee.data); auto accessor_ = std::dynamic_pointer_cast<BinaryCacheStoreAccessor>(accessor); if (accessor_) - // FIXME: more gratuitous string copying - accessor_->nars.emplace(info.path, makeNarAccessor(make_ref<std::string>(tee.data))); + accessor_->nars.emplace(info.path, makeNarAccessor(tee.data)); return info.path; } diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index 6feb84cd2b10..c99556f33692 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -31,8 +31,7 @@ private: protected: - BinaryCacheStore(std::shared_ptr<Store> localStore, - const Path & secretKeyFile, const Path & publicKeyFile); + BinaryCacheStore(std::shared_ptr<Store> localStore, const Path & secretKeyFile); [[noreturn]] void notImpl(); diff --git a/src/libstore/build.cc b/src/libstore/build.cc index 7d124f6f0ee0..ed4e0f659da3 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -2009,7 +2009,7 @@ void DerivationGoal::startBuilder() throw SysError(format("linking ‘%1%’ to ‘%2%’") % p % i); StringSink sink; dumpPath(i, sink); - StringSource source(sink.s); + StringSource source(*sink.s); restorePath(p, source); } } @@ -2666,8 +2666,8 @@ void DerivationGoal::registerOutputs() StringSink sink; dumpPath(actualPath, sink); deletePath(actualPath); - sink.s = rewriteHashes(sink.s, rewritesFromTmp); - StringSource source(sink.s); + sink.s = make_ref<std::string>(rewriteHashes(*sink.s, rewritesFromTmp)); + StringSource source(*sink.s); restorePath(actualPath, source); rewritten = true; diff --git a/src/libstore/crypto.cc b/src/libstore/crypto.cc index c1b57e51d9b4..53e94e1f5997 100644 --- a/src/libstore/crypto.cc +++ b/src/libstore/crypto.cc @@ -55,6 +55,17 @@ std::string SecretKey::signDetached(const std::string & data) const #endif } +PublicKey SecretKey::toPublicKey() const +{ +#if HAVE_SODIUM + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + crypto_sign_ed25519_sk_to_pk(pk, (unsigned char *) key.data()); + return PublicKey(name, std::string((char *) pk, crypto_sign_PUBLICKEYBYTES)); +#else + noSodium(); +#endif +} + PublicKey::PublicKey(const string & s) : Key(s) { diff --git a/src/libstore/crypto.hh b/src/libstore/crypto.hh index a1489e753649..33b79cb2e8fe 100644 --- a/src/libstore/crypto.hh +++ b/src/libstore/crypto.hh @@ -15,19 +15,31 @@ struct Key ‘<name>:<key-in-base64>’. */ Key(const std::string & s); +protected: + Key(const std::string & name, const std::string & key) + : name(name), key(key) { } }; +struct PublicKey; + struct SecretKey : Key { SecretKey(const std::string & s); /* Return a detached signature of the given string. */ std::string signDetached(const std::string & s) const; + + PublicKey toPublicKey() const; }; struct PublicKey : Key { PublicKey(const std::string & data); + +private: + PublicKey(const std::string & name, const std::string & key) + : Key(name, key) { } + friend class SecretKey; }; typedef std::map<std::string, PublicKey> PublicKeys; diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc new file mode 100644 index 000000000000..9614d0b4cf35 --- /dev/null +++ b/src/libstore/http-binary-cache-store.cc @@ -0,0 +1,76 @@ +#include "binary-cache-store.hh" +#include "download.hh" +#include "globals.hh" + +namespace nix { + +class HttpBinaryCacheStore : public BinaryCacheStore +{ +private: + + Path cacheUri; + + ref<Downloader> downloader; + +public: + + HttpBinaryCacheStore(std::shared_ptr<Store> localStore, + const Path & secretKeyFile, const Path & _cacheUri) + : BinaryCacheStore(localStore, secretKeyFile) + , cacheUri(_cacheUri) + , downloader(makeDownloader()) + { + if (cacheUri.back() == '/') + cacheUri.pop_back(); + } + + void init() override + { + // FIXME: do this lazily? + if (!fileExists("nix-cache-info")) + throw Error(format("‘%s’ does not appear to be a binary cache") % cacheUri); + } + +protected: + + bool fileExists(const std::string & path) override + { + try { + DownloadOptions options; + options.showProgress = DownloadOptions::no; + options.head = true; + downloader->download(cacheUri + "/" + path, options); + return true; + } catch (DownloadError & e) { + if (e.error == Downloader::NotFound) + return false; + throw; + } + } + + void upsertFile(const std::string & path, const std::string & data) + { + throw Error("uploading to an HTTP binary cache is not supported"); + } + + std::string getFile(const std::string & path) override + { + DownloadOptions options; + options.showProgress = DownloadOptions::no; + return downloader->download(cacheUri + "/" + path, options).data; + } + +}; + +static RegisterStoreImplementation regStore([](const std::string & uri) -> std::shared_ptr<Store> { + if (std::string(uri, 0, 7) != "http://" && + std::string(uri, 0, 8) != "https://") return 0; + auto store = std::make_shared<HttpBinaryCacheStore>(std::shared_ptr<Store>(0), + settings.get("binary-cache-secret-key-file", string("")), + uri); + store->init(); + return store; +}); + +} + diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index a10c9d1069d5..efd6d47254f2 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -1,4 +1,5 @@ #include "binary-cache-store.hh" +#include "globals.hh" namespace nix { @@ -11,8 +12,7 @@ private: public: LocalBinaryCacheStore(std::shared_ptr<Store> localStore, - const Path & secretKeyFile, const Path & publicKeyFile, - const Path & binaryCacheDir); + const Path & secretKeyFile, const Path & binaryCacheDir); void init() override; @@ -27,9 +27,8 @@ protected: }; LocalBinaryCacheStore::LocalBinaryCacheStore(std::shared_ptr<Store> localStore, - const Path & secretKeyFile, const Path & publicKeyFile, - const Path & binaryCacheDir) - : BinaryCacheStore(localStore, secretKeyFile, publicKeyFile) + const Path & secretKeyFile, const Path & binaryCacheDir) + : BinaryCacheStore(localStore, secretKeyFile) , binaryCacheDir(binaryCacheDir) { } @@ -65,13 +64,20 @@ std::string LocalBinaryCacheStore::getFile(const std::string & path) return readFile(binaryCacheDir + "/" + path); } +ref<Store> openLocalBinaryCacheStore(std::shared_ptr<Store> localStore, + const Path & secretKeyFile, const Path & binaryCacheDir) +{ + auto store = make_ref<LocalBinaryCacheStore>( + localStore, secretKeyFile, binaryCacheDir); + store->init(); + return store; +} + static RegisterStoreImplementation regStore([](const std::string & uri) -> std::shared_ptr<Store> { if (std::string(uri, 0, 7) != "file://") return 0; - auto store = std::make_shared<LocalBinaryCacheStore>(std::shared_ptr<Store>(0), - "", "", // FIXME: allow the signing key to be set + return openLocalBinaryCacheStore(std::shared_ptr<Store>(0), + settings.get("binary-cache-secret-key-file", string("")), std::string(uri, 7)); - store->init(); - return store; }); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 9a570668128e..8a2b7bb9164e 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1415,9 +1415,9 @@ Path LocalStore::addToStore(const string & name, const Path & _srcPath, if (recursive) dumpPath(srcPath, sink, filter); else - sink.s = readFile(srcPath); + sink.s = make_ref<std::string>(readFile(srcPath)); - return addToStoreFromDump(sink.s, name, recursive, hashAlgo, repair); + return addToStoreFromDump(*sink.s, name, recursive, hashAlgo, repair); } @@ -1442,14 +1442,14 @@ Path LocalStore::addTextToStore(const string & name, const string & s, StringSink sink; dumpString(s, sink); - auto hash = hashString(htSHA256, sink.s); + auto hash = hashString(htSHA256, *sink.s); optimisePath(dstPath); ValidPathInfo info; info.path = dstPath; info.narHash = hash; - info.narSize = sink.s.size(); + info.narSize = sink.s->size(); info.references = references; registerValidPath(info); } diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 97e834ed2bd8..adec0fb788c8 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -453,6 +453,10 @@ ref<Store> openStoreAt(const std::string & uri); ref<Store> openStore(); +ref<Store> openLocalBinaryCacheStore(std::shared_ptr<Store> localStore, + const Path & secretKeyFile, const Path & binaryCacheDir); + + /* Store implementation registration. */ typedef std::function<std::shared_ptr<Store>(const std::string & uri)> OpenStore; |