aboutsummaryrefslogtreecommitdiff
path: root/src/nix/sigs.cc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-05 15:30:22 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2016-04-05 16:39:23 +0200
commitd0f5719c2a2e5a0eea49dc072b26e7d161564bbb (patch)
tree48589fd3963b008418004a2fca383a29c347e1be /src/nix/sigs.cc
parent80da7a637559aadb6544599adc9f5807188cb9e5 (diff)
Add "nix copy-sigs" command
This imports signatures from one store into another. E.g. $ nix copy-sigs -r /run/current-system -s https://cache.nixos.org/ imported 595 signatures
Diffstat (limited to 'src/nix/sigs.cc')
-rw-r--r--src/nix/sigs.cc133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/nix/sigs.cc b/src/nix/sigs.cc
new file mode 100644
index 000000000..e3544a1fd
--- /dev/null
+++ b/src/nix/sigs.cc
@@ -0,0 +1,133 @@
+#include "affinity.hh" // FIXME
+#include "command.hh"
+#include "progress-bar.hh"
+#include "shared.hh"
+#include "store-api.hh"
+#include "thread-pool.hh"
+
+#include <atomic>
+
+using namespace nix;
+
+struct CmdCopySigs : StorePathsCommand
+{
+ Strings substituterUris;
+
+ CmdCopySigs()
+ {
+ mkFlag('s', "substituter", {"store-uri"}, "use signatures from specified store", 1,
+ [&](Strings ss) { substituterUris.push_back(ss.front()); });
+ }
+
+ std::string name() override
+ {
+ return "copy-sigs";
+ }
+
+ std::string description() override
+ {
+ return "copy path signatures from substituters (like binary caches)";
+ }
+
+ void run(ref<Store> store, Paths storePaths) override
+ {
+ restoreAffinity(); // FIXME
+
+ if (substituterUris.empty())
+ throw UsageError("you must specify at least one subtituter using ā€˜-sā€™");
+
+ // FIXME: factor out commonality with MixVerify.
+ std::vector<ref<Store>> substituters;
+ for (auto & s : substituterUris)
+ substituters.push_back(openStoreAt(s));
+
+ ProgressBar progressBar;
+
+ ThreadPool pool;
+
+ std::atomic<size_t> done{0};
+ std::atomic<size_t> added{0};
+
+ auto showProgress = [&]() {
+ return (format("[%d/%d done]") % done % storePaths.size()).str();
+ };
+
+ progressBar.updateStatus(showProgress());
+
+ auto doPath = [&](const Path & storePath) {
+ auto activity(progressBar.startActivity(format("getting signatures for ā€˜%sā€™") % storePath));
+
+ checkInterrupt();
+
+ auto info = store->queryPathInfo(storePath);
+
+ StringSet newSigs;
+
+ for (auto & store2 : substituters) {
+ if (!store2->isValidPath(storePath)) continue;
+ auto info2 = store2->queryPathInfo(storePath);
+
+ /* Don't import signatures that don't match this
+ binary. */
+ if (info.narHash != info2.narHash ||
+ info.narSize != info2.narSize ||
+ info.references != info2.references)
+ continue;
+
+ for (auto & sig : info2.sigs)
+ if (!info.sigs.count(sig))
+ newSigs.insert(sig);
+ }
+
+ if (!newSigs.empty()) {
+ store->addSignatures(storePath, newSigs);
+ added += newSigs.size();
+ }
+
+ done++;
+ progressBar.updateStatus(showProgress());
+ };
+
+ for (auto & storePath : storePaths)
+ pool.enqueue(std::bind(doPath, storePath));
+
+ pool.process();
+
+ progressBar.done();
+
+ printMsg(lvlInfo, format("imported %d signatures") % added);
+ }
+};
+
+static RegisterCommand r1(make_ref<CmdCopySigs>());
+
+struct CmdQueryPathSigs : StorePathsCommand
+{
+ CmdQueryPathSigs()
+ {
+ }
+
+ std::string name() override
+ {
+ return "query-path-sigs";
+ }
+
+ std::string description() override
+ {
+ return "print store path signatures";
+ }
+
+ void run(ref<Store> store, Paths storePaths) override
+ {
+ for (auto & storePath : storePaths) {
+ auto info = store->queryPathInfo(storePath);
+ std::cout << storePath << " ";
+ if (info.ultimate) std::cout << "ultimate ";
+ for (auto & sig : info.sigs)
+ std::cout << sig << " ";
+ std::cout << "\n";
+ }
+ }
+};
+
+static RegisterCommand r2(make_ref<CmdQueryPathSigs>());