From 61f89e954af060c8dbdcd5a4fffcf023ac555686 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 18 Oct 2022 16:42:06 +0200 Subject: [PATCH 1/2] Add command 'nix store path-from-hash-part' This exposes the Store::queryPathFromHashPart() interface in the CLI. --- src/nix/path-from-hash-part.cc | 39 ++++++++++++++++++++++++++++++++++ src/nix/path-from-hash-part.md | 20 +++++++++++++++++ tests/local.mk | 3 ++- tests/path-from-hash-part.sh | 10 +++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/nix/path-from-hash-part.cc create mode 100644 src/nix/path-from-hash-part.md create mode 100644 tests/path-from-hash-part.sh diff --git a/src/nix/path-from-hash-part.cc b/src/nix/path-from-hash-part.cc new file mode 100644 index 000000000..7f7cda8d3 --- /dev/null +++ b/src/nix/path-from-hash-part.cc @@ -0,0 +1,39 @@ +#include "command.hh" +#include "store-api.hh" + +using namespace nix; + +struct CmdPathFromHashPart : StoreCommand +{ + std::string hashPart; + + CmdPathFromHashPart() + { + expectArgs({ + .label = "hash-part", + .handler = {&hashPart}, + }); + } + + std::string description() override + { + return "get a store path from its hash part"; + } + + std::string doc() override + { + return + #include "path-from-hash-part.md" + ; + } + + void run(ref store) override + { + if (auto storePath = store->queryPathFromHashPart(hashPart)) + logger->cout(store->printStorePath(*storePath)); + else + throw Error("there is no store path corresponding to '%s'", hashPart); + } +}; + +static auto rCmdPathFromHashPart = registerCommand2({"store", "path-from-hash-part"}); diff --git a/src/nix/path-from-hash-part.md b/src/nix/path-from-hash-part.md new file mode 100644 index 000000000..788e13ab6 --- /dev/null +++ b/src/nix/path-from-hash-part.md @@ -0,0 +1,20 @@ +R""( + +# Examples + +* Return the full store path with the given hash part: + + ```console + # nix store path-from-hash-part --store https://cache.nixos.org/ 0i2jd68mp5g6h2sa5k9c85rb80sn8hi9 + /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10 + ``` + +# Description + +Given the hash part of a store path (that is, the 32 characters +following `/nix/store/`), return the full store path. This is +primarily useful in the implementation of binary caches, where a +request for a `.narinfo` file only supplies the hash part +(e.g. `https://cache.nixos.org/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9.narinfo`). + +)"" diff --git a/tests/local.mk b/tests/local.mk index 5e48ceae1..340817ec3 100644 --- a/tests/local.mk +++ b/tests/local.mk @@ -109,7 +109,8 @@ nix_tests = \ store-ping.sh \ fetchClosure.sh \ completions.sh \ - impure-derivations.sh + impure-derivations.sh \ + path-from-hash-part.sh ifeq ($(HAVE_LIBCPUID), 1) nix_tests += compute-levels.sh diff --git a/tests/path-from-hash-part.sh b/tests/path-from-hash-part.sh new file mode 100644 index 000000000..bdd104434 --- /dev/null +++ b/tests/path-from-hash-part.sh @@ -0,0 +1,10 @@ +source common.sh + +path=$(nix build --no-link --print-out-paths -f simple.nix) + +hash_part=$(basename $path) +hash_part=${hash_part:0:32} + +path2=$(nix store path-from-hash-part $hash_part) + +[[ $path = $path2 ]] From e136d57f26155a9f54dfb0ca00212b2016932104 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 18 Oct 2022 17:48:09 +0200 Subject: [PATCH 2/2] Implement BinaryCacheStore::queryPathFromHashPart() --- src/libstore/binary-cache-store.cc | 11 +++++++++++ src/libstore/binary-cache-store.hh | 3 +-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 9226c4e19..a26770c79 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -331,6 +331,17 @@ bool BinaryCacheStore::isValidPathUncached(const StorePath & storePath) return fileExists(narInfoFileFor(storePath)); } +std::optional BinaryCacheStore::queryPathFromHashPart(const std::string & hashPart) +{ + auto pseudoPath = StorePath(hashPart + "-" + MissingName); + try { + auto info = queryPathInfo(pseudoPath); + return info->path; + } catch (InvalidPath &) { + return std::nullopt; + } +} + void BinaryCacheStore::narFromPath(const StorePath & storePath, Sink & sink) { auto info = queryPathInfo(storePath).cast(); diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index ca538b3cb..8c82e2387 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -95,8 +95,7 @@ public: void queryPathInfoUncached(const StorePath & path, Callback> callback) noexcept override; - std::optional queryPathFromHashPart(const std::string & hashPart) override - { unsupported("queryPathFromHashPart"); } + std::optional queryPathFromHashPart(const std::string & hashPart) override; void addToStore(const ValidPathInfo & info, Source & narSource, RepairFlag repair, CheckSigsFlag checkSigs) override;