diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 93caba67e..68af85bf1 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -73,6 +73,23 @@ Path BinaryCacheStore::narInfoFileFor(const Path & storePath) return storePathToHash(storePath) + ".narinfo"; } +void BinaryCacheStore::writeNarInfo(ref narInfo) +{ + auto narInfoFile = narInfoFileFor(narInfo->path); + + upsertFile(narInfoFile, narInfo->to_string(), "text/x-nix-narinfo"); + + auto hashPart = storePathToHash(narInfo->path); + + { + auto state_(state.lock()); + state_->pathInfoCache.upsert(hashPart, std::shared_ptr(narInfo)); + } + + if (diskCache) + diskCache->upsertNarInfo(getUri(), hashPart, std::shared_ptr(narInfo)); +} + void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref & nar, RepairFlag repair, CheckSigsFlag checkSigs, std::shared_ptr accessor) { @@ -89,8 +106,6 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const refcompare(0, narMagic.size(), narMagic) == 0); auto narInfo = make_ref(info); @@ -168,17 +183,7 @@ void BinaryCacheStore::addToStore(const ValidPathInfo & info, const refsign(*secretKey); - upsertFile(narInfoFile, narInfo->to_string(), "text/x-nix-narinfo"); - - auto hashPart = storePathToHash(narInfo->path); - - { - auto state_(state.lock()); - state_->pathInfoCache.upsert(hashPart, std::shared_ptr(narInfo)); - } - - if (diskCache) - diskCache->upsertNarInfo(getUri(), hashPart, std::shared_ptr(narInfo)); + writeNarInfo(narInfo); stats.narInfoWrite++; } @@ -293,6 +298,22 @@ ref BinaryCacheStore::getFSAccessor() return make_ref(ref(shared_from_this()), localNarCache); } +void BinaryCacheStore::addSignatures(const Path & storePath, const StringSet & sigs) +{ + /* Note: this is inherently racy since there is no locking on + binary caches. In particular, with S3 this unreliable, even + when addSignatures() is called sequentially on a path, because + S3 might return an outdated cached version. */ + + auto narInfo = make_ref((NarInfo &) *queryPathInfo(storePath)); + + narInfo->sigs.insert(sigs.begin(), sigs.end()); + + auto narInfoFile = narInfoFileFor(narInfo->path); + + writeNarInfo(narInfo); +} + std::shared_ptr BinaryCacheStore::getBuildLog(const Path & path) { Path drvPath; diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index d3b0e0bd9..8492ff600 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -59,6 +59,8 @@ private: std::string narInfoFileFor(const Path & storePath); + void writeNarInfo(ref narInfo); + public: bool isValidPathUncached(const Path & path) override; @@ -119,8 +121,7 @@ public: ref getFSAccessor() override; - void addSignatures(const Path & storePath, const StringSet & sigs) override - { unsupported(); } + void addSignatures(const Path & storePath, const StringSet & sigs) override; std::shared_ptr getBuildLog(const Path & path) override; diff --git a/tests/signing.sh b/tests/signing.sh index c3638012e..bef27ac7a 100644 --- a/tests/signing.sh +++ b/tests/signing.sh @@ -60,3 +60,9 @@ info=$(nix path-info --store file://$cacheDir --json $outPath2) (! [[ $info =~ '"ultimate":true' ]]) [[ $info =~ 'cache1.example.org' ]] (! [[ $info =~ 'cache2.example.org' ]]) + +# Verify that adding a signature to a path in a binary cache works. +nix sign-paths --store file://$cacheDir --key-file $TEST_ROOT/sk2 $outPath2 +info=$(nix path-info --store file://$cacheDir --json $outPath2) +[[ $info =~ 'cache1.example.org' ]] +[[ $info =~ 'cache2.example.org' ]]