From 0afeb7f51e3465c7c27bc5a83017e9ffde8c6725 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Mar 2017 12:07:50 +0100 Subject: [PATCH] Store: Add a method for getting build logs This allows various Store implementations to provide different ways to get build logs. For example, BinaryCacheStore can get the build logs from the binary cache. Also, remove the log-servers option since we can use substituters for this. --- doc/manual/command-ref/conf-file.xml | 14 ------- doc/manual/command-ref/nix-store.xml | 7 +--- src/libstore/build.cc | 5 +-- src/libstore/globals.cc | 1 - src/libstore/globals.hh | 3 -- src/libstore/local-fs-store.cc | 35 +++++++++++++++++ src/libstore/local-store.hh | 3 -- src/libstore/store-api.hh | 8 ++++ src/nix-store/nix-store.cc | 57 +++------------------------- 9 files changed, 50 insertions(+), 83 deletions(-) diff --git a/doc/manual/command-ref/conf-file.xml b/doc/manual/command-ref/conf-file.xml index 36b70f0c4..3bd133918 100644 --- a/doc/manual/command-ref/conf-file.xml +++ b/doc/manual/command-ref/conf-file.xml @@ -512,20 +512,6 @@ password my-password - log-servers - - - - A list of URL prefixes (such as - http://hydra.nixos.org/log) from which - nix-store -l will try to fetch build logs if - they’re not available locally. - - - - - - trusted-users diff --git a/doc/manual/command-ref/nix-store.xml b/doc/manual/command-ref/nix-store.xml index 0f6172def..fb017b741 100644 --- a/doc/manual/command-ref/nix-store.xml +++ b/doc/manual/command-ref/nix-store.xml @@ -1236,12 +1236,7 @@ the store path is used. /nix/var/log/nix/drvs. However, there is no guarantee that a build log is available for any particular store path. For instance, if the path was downloaded as a pre-built binary through -a substitute, then the log is unavailable. If the log is not available -locally, then nix-store will try to download the -log from the servers specified in the Nix option -. For example, if it’s set to -http://hydra.nixos.org/log, then Nix will check -http://hydra.nixos.org/log/base-name. +a substitute, then the log is unavailable. diff --git a/src/libstore/build.cc b/src/libstore/build.cc index fd1f5dc3a..2b0f8e592 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -3048,9 +3048,6 @@ void DerivationGoal::registerOutputs() } -string drvsLogDir = "drvs"; - - Path DerivationGoal::openLogFile() { logSize = 0; @@ -3060,7 +3057,7 @@ Path DerivationGoal::openLogFile() string baseName = baseNameOf(drvPath); /* Create a log file. */ - Path dir = (format("%1%/%2%/%3%/") % worker.store.logDir % drvsLogDir % string(baseName, 0, 2)).str(); + Path dir = (format("%1%/%2%/%3%/") % worker.store.logDir % worker.store.drvsLogDir % string(baseName, 0, 2)).str(); createDirs(dir); Path logFileName = (format("%1%/%2%%3%") diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index df537a512..012b3d5b8 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -179,7 +179,6 @@ void Settings::update() _get(envKeepDerivations, "env-keep-derivations"); _get(sshSubstituterHosts, "ssh-substituter-hosts"); _get(useSshSubstituter, "use-ssh-substituter"); - _get(logServers, "log-servers"); _get(enableImportNative, "allow-unsafe-native-code-during-evaluation"); _get(useCaseHack, "use-case-hack"); _get(preBuildHook, "pre-build-hook"); diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 7a9a9f6c0..462721681 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -181,9 +181,6 @@ struct Settings { /* Whether to show a stack trace if Nix evaluation fails. */ bool showTrace; - /* A list of URL prefixes that can return Nix build logs. */ - Strings logServers; - /* Whether the importNative primop should be enabled */ bool enableImportNative; diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc index 4571a2211..c5da73dba 100644 --- a/src/libstore/local-fs-store.cc +++ b/src/libstore/local-fs-store.cc @@ -2,6 +2,8 @@ #include "fs-accessor.hh" #include "store-api.hh" #include "globals.hh" +#include "compression.hh" +#include "derivations.hh" namespace nix { @@ -84,4 +86,37 @@ void LocalFSStore::narFromPath(const Path & path, Sink & sink) dumpPath(getRealStoreDir() + std::string(path, storeDir.size()), sink); } +const string LocalFSStore::drvsLogDir = "drvs"; + +std::shared_ptr LocalFSStore::getBuildLog(const Path & path_) +{ + auto path(path_); + + assertStorePath(path); + + if (!isDerivation(path)) { + path = queryPathInfo(path)->deriver; + if (path == "") return nullptr; + } + + string baseName = baseNameOf(path); + + for (int j = 0; j < 2; j++) { + + Path logPath = + j == 0 + ? (format("%1%/%2%/%3%/%4%") % logDir % drvsLogDir % string(baseName, 0, 2) % string(baseName, 2)).str() + : (format("%1%/%2%/%3%") % logDir % drvsLogDir % baseName).str(); + Path logBz2Path = logPath + ".bz2"; + + if (pathExists(logPath)) + return std::make_shared(readFile(logPath)); + + else if (pathExists(logBz2Path)) + return decompress("bzip2", readFile(logBz2Path)); + } + + return nullptr; +} + } diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 511209d84..49a0d7e0d 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -21,9 +21,6 @@ namespace nix { const int nixSchemaVersion = 10; -extern string drvsLogDir; - - struct Derivation; diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 481d0b799..3aea30c28 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -566,6 +566,11 @@ public: if they lack a signature. */ virtual bool isTrusted() { return false; } + /* Return the build log of the specified store path, if available, + or null otherwise. */ + virtual std::shared_ptr getBuildLog(const Path & path) + { return nullptr; } + protected: Stats stats; @@ -579,6 +584,7 @@ public: const Path rootDir; const Path stateDir; const Path logDir; + const static string drvsLogDir; LocalFSStore(const Params & params); @@ -595,6 +601,8 @@ public: { return getRealStoreDir() + "/" + baseNameOf(storePath); } + + std::shared_ptr getBuildLog(const Path & path) override; }; diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 950c2a7c9..024fa4168 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -9,7 +9,6 @@ #include "util.hh" #include "worker-protocol.hh" #include "xmlgraph.hh" -#include "compression.hh" #include #include @@ -482,58 +481,12 @@ static void opReadLog(Strings opFlags, Strings opArgs) RunPager pager; - // FIXME: move getting logs into Store. - auto store2 = std::dynamic_pointer_cast(store); - if (!store2) throw Error(format("store ‘%s’ does not support reading logs") % store->getUri()); - for (auto & i : opArgs) { - Path path = useDeriver(store->followLinksToStorePath(i)); - - string baseName = baseNameOf(path); - bool found = false; - - for (int j = 0; j < 2; j++) { - - Path logPath = - j == 0 - ? (format("%1%/%2%/%3%/%4%") % store2->logDir % drvsLogDir % string(baseName, 0, 2) % string(baseName, 2)).str() - : (format("%1%/%2%/%3%") % store2->logDir % drvsLogDir % baseName).str(); - Path logBz2Path = logPath + ".bz2"; - - if (pathExists(logPath)) { - /* !!! Make this run in O(1) memory. */ - string log = readFile(logPath); - writeFull(STDOUT_FILENO, log); - found = true; - break; - } - - else if (pathExists(logBz2Path)) { - std::cout << *decompress("bzip2", readFile(logBz2Path)); - found = true; - break; - } - } - - if (!found) { - for (auto & i : settings.logServers) { - string prefix = i; - if (!prefix.empty() && prefix.back() != '/') prefix += '/'; - string url = prefix + baseName; - try { - string log = runProgram(CURL, true, {"--fail", "--location", "--silent", "--", url}); - std::cout << "(using build log from " << url << ")" << std::endl; - std::cout << log; - found = true; - break; - } catch (ExecError & e) { - /* Ignore errors from curl. FIXME: actually, might be - nice to print a warning on HTTP status != 404. */ - } - } - } - - if (!found) throw Error(format("build log of derivation ‘%1%’ is not available") % path); + auto path = store->followLinksToStorePath(i); + auto log = store->getBuildLog(path); + if (!log) + throw Error("build log of derivation ‘%s’ is not available", path); + std::cout << *log; } }