exportReferencesGraph: Export more complete info in JSON format

This writes info about every path in the closure in the same format as
‘nix path-info --json’. Thus it also includes NAR hashes and sizes.

Example:

  [
    {
      "path": "/nix/store/10h6li26i7g6z3mdpvra09yyf10mmzdr-hello-2.10",
      "narHash": "sha256:0ckdc4z20kkmpqdilx0wl6cricxv90lh85xpv2qljppcmz6vzcxl",
      "narSize": 197648,
      "references": [
        "/nix/store/10h6li26i7g6z3mdpvra09yyf10mmzdr-hello-2.10",
        "/nix/store/27binbdy296qvjycdgr1535v8872vz3z-glibc-2.24"
      ],
      "closureSize": 20939776
    },
    {
      "path": "/nix/store/27binbdy296qvjycdgr1535v8872vz3z-glibc-2.24",
      "narHash": "sha256:1nfn3m3p98y1c0kd0brp80dn9n5mycwgrk183j17rajya0h7gax3",
      "narSize": 20742128,
      "references": [
        "/nix/store/27binbdy296qvjycdgr1535v8872vz3z-glibc-2.24"
      ],
      "closureSize": 20742128
    }
  ]

Fixes #1134.
This commit is contained in:
Eelco Dolstra 2017-01-26 20:36:20 +01:00
parent 6de33a9c67
commit c2b0d8749f
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
4 changed files with 90 additions and 50 deletions

View file

@ -10,6 +10,7 @@
#include "builtins.hh"
#include "finally.hh"
#include "compression.hh"
#include "json.hh"
#include <algorithm>
#include <iostream>
@ -2273,9 +2274,18 @@ void DerivationGoal::doExportReferencesGraph()
}
}
/* Write closure info to `fileName'. */
/* Write closure info to <fileName>. */
writeFile(tmpDir + "/" + fileName,
worker.store.makeValidityRegistration(paths, false, false));
/* Write a more comprehensive JSON serialisation to
<fileName>.json. */
std::ostringstream str;
{
JSONPlaceholder jsonRoot(str, true);
worker.store.pathInfoToJSON(jsonRoot, paths, false, true);
}
writeFile(tmpDir + "/" + fileName + ".json", str.str());
}
}

View file

@ -4,6 +4,7 @@
#include "util.hh"
#include "nar-info-disk-cache.hh"
#include "thread-pool.hh"
#include "json.hh"
#include <future>
@ -439,6 +440,64 @@ string Store::makeValidityRegistration(const PathSet & paths,
}
void Store::pathInfoToJSON(JSONPlaceholder & jsonOut, const PathSet & storePaths,
bool includeImpureInfo, bool showClosureSize)
{
auto jsonList = jsonOut.list();
for (auto storePath : storePaths) {
auto info = queryPathInfo(storePath);
storePath = info->path;
auto jsonPath = jsonList.object();
jsonPath
.attr("path", storePath)
.attr("narHash", info->narHash.to_string())
.attr("narSize", info->narSize);
{
auto jsonRefs = jsonPath.list("references");
for (auto & ref : info->references)
jsonRefs.elem(ref);
}
if (info->ca != "")
jsonPath.attr("ca", info->ca);
if (showClosureSize)
jsonPath.attr("closureSize", getClosureSize(storePath));
if (!includeImpureInfo) continue;
if (info->deriver != "")
jsonPath.attr("deriver", info->deriver);
if (info->registrationTime)
jsonPath.attr("registrationTime", info->registrationTime);
if (info->ultimate)
jsonPath.attr("ultimate", info->ultimate);
if (!info->sigs.empty()) {
auto jsonSigs = jsonPath.list("signatures");
for (auto & sig : info->sigs)
jsonSigs.elem(sig);
}
}
}
unsigned long long Store::getClosureSize(const Path & storePath)
{
unsigned long long totalSize = 0;
PathSet closure;
computeFSClosure(storePath, closure, false, false);
for (auto & p : closure)
totalSize += queryPathInfo(p)->narSize;
return totalSize;
}
const Store::Stats & Store::getStats()
{
{

View file

@ -22,6 +22,7 @@ struct Derivation;
class FSAccessor;
class NarInfoDiskCache;
class Store;
class JSONPlaceholder;
/* Size of the hash part of store paths, in base-32 characters. */
@ -469,6 +470,19 @@ public:
string makeValidityRegistration(const PathSet & paths,
bool showDerivers, bool showHash);
/* Write a JSON representation of store path metadata, such as the
hash and the references. If includeImpureInfo is true,
variable elements such as the registration time are
included. If showClosureSize is true, the closure size of
each path is included. */
void pathInfoToJSON(JSONPlaceholder & jsonOut, const PathSet & storePaths,
bool includeImpureInfo, bool showClosureSize);
/* Return the size of the closure of the specified path, that is,
the sum of the size of the NAR serialisation of each path in
the closure. */
unsigned long long getClosureSize(const Path & storePath);
/* Optimise the disk space usage of the Nix store by hard-linking files
with the same contents. */
virtual void optimiseStore() = 0;

View file

@ -65,55 +65,12 @@ struct CmdPathInfo : StorePathsCommand
for (auto & storePath : storePaths)
pathLen = std::max(pathLen, storePath.size());
auto getClosureSize = [&](const Path & storePath) -> unsigned long long {
unsigned long long totalSize = 0;
PathSet closure;
store->computeFSClosure(storePath, closure, false, false);
for (auto & p : closure)
totalSize += store->queryPathInfo(p)->narSize;
return totalSize;
};
if (json) {
JSONList jsonRoot(std::cout, true);
for (auto storePath : storePaths) {
auto info = store->queryPathInfo(storePath);
storePath = info->path;
auto jsonPath = jsonRoot.object();
jsonPath
.attr("path", storePath)
.attr("narHash", info->narHash.to_string())
.attr("narSize", info->narSize);
if (showClosureSize)
jsonPath.attr("closureSize", getClosureSize(storePath));
if (info->deriver != "")
jsonPath.attr("deriver", info->deriver);
{
auto jsonRefs = jsonPath.list("references");
for (auto & ref : info->references)
jsonRefs.elem(ref);
}
if (info->registrationTime)
jsonPath.attr("registrationTime", info->registrationTime);
if (info->ultimate)
jsonPath.attr("ultimate", info->ultimate);
if (info->ca != "")
jsonPath.attr("ca", info->ca);
if (!info->sigs.empty()) {
auto jsonSigs = jsonPath.list("signatures");
for (auto & sig : info->sigs)
jsonSigs.elem(sig);
}
}
JSONPlaceholder jsonRoot(std::cout, true);
store->pathInfoToJSON(jsonRoot,
// FIXME: preserve order?
PathSet(storePaths.begin(), storePaths.end()),
true, showClosureSize);
}
else {
@ -128,7 +85,7 @@ struct CmdPathInfo : StorePathsCommand
std::cout << '\t' << std::setw(11) << info->narSize;
if (showClosureSize)
std::cout << '\t' << std::setw(11) << getClosureSize(storePath);
std::cout << '\t' << std::setw(11) << store->getClosureSize(storePath);
if (showSigs) {
std::cout << '\t';