aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/realisation.cc
diff options
context:
space:
mode:
authorregnat <rg@regnat.ovh>2020-10-08 17:36:51 +0200
committerregnat <rg@regnat.ovh>2020-12-11 20:41:32 +0100
commit58cdab64acd4807f73768fb32acdde39b501799f (patch)
tree6e68a9f51e1a43d59d4e56ba58c0de6149662f7f /src/libstore/realisation.cc
parent9c143c411b2190a05907416266b0022e5b17dd02 (diff)
Store metadata about drv outputs realisations
For each known realisation, store: - its output - its output path This comes with a set of needed changes: - New `realisations` module declaring the types needed for describing these mappings - New `Store::registerDrvOutput` method registering all the needed informations about a derivation output (also replaces `LocalStore::linkDeriverToPath`) - new `Store::queryRealisation` method to retrieve the informations for a derivations This introcudes some redundancy on the remote-store side between `wopQueryDerivationOutputMap` and `wopQueryRealisation`. However we might need to keep both (regardless of backwards compat) because we sometimes need to get some infos for all the outputs of a derivation (where `wopQueryDerivationOutputMap` is handy), but all the stores can't implement it − because listing all the outputs of a derivation isn't really possible for binary caches where the server doesn't allow to list a directory.
Diffstat (limited to 'src/libstore/realisation.cc')
-rw-r--r--src/libstore/realisation.cc72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/libstore/realisation.cc b/src/libstore/realisation.cc
new file mode 100644
index 000000000..fcc1a3825
--- /dev/null
+++ b/src/libstore/realisation.cc
@@ -0,0 +1,72 @@
+#include "realisation.hh"
+#include "store-api.hh"
+
+namespace nix {
+
+MakeError(InvalidDerivationOutputId, Error);
+
+DrvOutput DrvOutput::parse(const std::string &strRep) {
+ const auto &[rawPath, outputs] = parsePathWithOutputs(strRep);
+ if (outputs.size() != 1)
+ throw InvalidDerivationOutputId("Invalid derivation output id %s", strRep);
+
+ return DrvOutput{
+ .drvPath = StorePath(rawPath),
+ .outputName = *outputs.begin(),
+ };
+}
+
+std::string DrvOutput::to_string() const {
+ return std::string(drvPath.to_string()) + "!" + outputName;
+}
+
+std::string Realisation::to_string() const {
+ std::string res;
+
+ res += "Id: " + id.to_string() + '\n';
+ res += "OutPath: " + std::string(outPath.to_string()) + '\n';
+
+ return res;
+}
+
+Realisation Realisation::parse(const std::string & s, const std::string & whence)
+{
+ // XXX: Copy-pasted from NarInfo::NarInfo. Should be factored out
+ auto corrupt = [&]() {
+ return Error("Drv output info file '%1%' is corrupt", whence);
+ };
+
+ std::optional<DrvOutput> id;
+ std::optional<StorePath> outPath;
+
+ size_t pos = 0;
+ while (pos < s.size()) {
+
+ size_t colon = s.find(':', pos);
+ if (colon == std::string::npos) throw corrupt();
+
+ std::string name(s, pos, colon - pos);
+
+ size_t eol = s.find('\n', colon + 2);
+ if (eol == std::string::npos) throw corrupt();
+
+ std::string value(s, colon + 2, eol - colon - 2);
+
+ if (name == "Id")
+ id = DrvOutput::parse(value);
+
+ if (name == "OutPath")
+ outPath = StorePath(value);
+
+ pos = eol + 1;
+ }
+
+ if (!outPath) corrupt();
+ if (!id) corrupt();
+ return Realisation {
+ .id = *id,
+ .outPath = *outPath,
+ };
+}
+
+} // namespace nix