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.
This commit is contained in:
parent
96443e94a1
commit
0afeb7f51e
9 changed files with 50 additions and 83 deletions
|
@ -512,20 +512,6 @@ password <replaceable>my-password</replaceable>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
||||||
<varlistentry xml:id="conf-log-servers"><term><literal>log-servers</literal></term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
|
|
||||||
<para>A list of URL prefixes (such as
|
|
||||||
<literal>http://hydra.nixos.org/log</literal>) from which
|
|
||||||
<command>nix-store -l</command> will try to fetch build logs if
|
|
||||||
they’re not available locally.</para>
|
|
||||||
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
|
|
||||||
<varlistentry xml:id="conf-trusted-users"><term><literal>trusted-users</literal></term>
|
<varlistentry xml:id="conf-trusted-users"><term><literal>trusted-users</literal></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -1236,12 +1236,7 @@ the store path is used.</para>
|
||||||
<filename>/nix/var/log/nix/drvs</filename>. However, there is no
|
<filename>/nix/var/log/nix/drvs</filename>. However, there is no
|
||||||
guarantee that a build log is available for any particular store path.
|
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
|
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
|
a substitute, then the log is unavailable.</para>
|
||||||
locally, then <command>nix-store</command> will try to download the
|
|
||||||
log from the servers specified in the Nix option
|
|
||||||
<option>log-servers</option>. For example, if it’s set to
|
|
||||||
<literal>http://hydra.nixos.org/log</literal>, then Nix will check
|
|
||||||
<literal>http://hydra.nixos.org/log/<replaceable>base-name</replaceable></literal>.</para>
|
|
||||||
|
|
||||||
</refsection>
|
</refsection>
|
||||||
|
|
||||||
|
|
|
@ -3048,9 +3048,6 @@ void DerivationGoal::registerOutputs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string drvsLogDir = "drvs";
|
|
||||||
|
|
||||||
|
|
||||||
Path DerivationGoal::openLogFile()
|
Path DerivationGoal::openLogFile()
|
||||||
{
|
{
|
||||||
logSize = 0;
|
logSize = 0;
|
||||||
|
@ -3060,7 +3057,7 @@ Path DerivationGoal::openLogFile()
|
||||||
string baseName = baseNameOf(drvPath);
|
string baseName = baseNameOf(drvPath);
|
||||||
|
|
||||||
/* Create a log file. */
|
/* 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);
|
createDirs(dir);
|
||||||
|
|
||||||
Path logFileName = (format("%1%/%2%%3%")
|
Path logFileName = (format("%1%/%2%%3%")
|
||||||
|
|
|
@ -179,7 +179,6 @@ void Settings::update()
|
||||||
_get(envKeepDerivations, "env-keep-derivations");
|
_get(envKeepDerivations, "env-keep-derivations");
|
||||||
_get(sshSubstituterHosts, "ssh-substituter-hosts");
|
_get(sshSubstituterHosts, "ssh-substituter-hosts");
|
||||||
_get(useSshSubstituter, "use-ssh-substituter");
|
_get(useSshSubstituter, "use-ssh-substituter");
|
||||||
_get(logServers, "log-servers");
|
|
||||||
_get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
|
_get(enableImportNative, "allow-unsafe-native-code-during-evaluation");
|
||||||
_get(useCaseHack, "use-case-hack");
|
_get(useCaseHack, "use-case-hack");
|
||||||
_get(preBuildHook, "pre-build-hook");
|
_get(preBuildHook, "pre-build-hook");
|
||||||
|
|
|
@ -181,9 +181,6 @@ struct Settings {
|
||||||
/* Whether to show a stack trace if Nix evaluation fails. */
|
/* Whether to show a stack trace if Nix evaluation fails. */
|
||||||
bool showTrace;
|
bool showTrace;
|
||||||
|
|
||||||
/* A list of URL prefixes that can return Nix build logs. */
|
|
||||||
Strings logServers;
|
|
||||||
|
|
||||||
/* Whether the importNative primop should be enabled */
|
/* Whether the importNative primop should be enabled */
|
||||||
bool enableImportNative;
|
bool enableImportNative;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include "fs-accessor.hh"
|
#include "fs-accessor.hh"
|
||||||
#include "store-api.hh"
|
#include "store-api.hh"
|
||||||
#include "globals.hh"
|
#include "globals.hh"
|
||||||
|
#include "compression.hh"
|
||||||
|
#include "derivations.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -84,4 +86,37 @@ void LocalFSStore::narFromPath(const Path & path, Sink & sink)
|
||||||
dumpPath(getRealStoreDir() + std::string(path, storeDir.size()), sink);
|
dumpPath(getRealStoreDir() + std::string(path, storeDir.size()), sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const string LocalFSStore::drvsLogDir = "drvs";
|
||||||
|
|
||||||
|
std::shared_ptr<std::string> 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<std::string>(readFile(logPath));
|
||||||
|
|
||||||
|
else if (pathExists(logBz2Path))
|
||||||
|
return decompress("bzip2", readFile(logBz2Path));
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,6 @@ namespace nix {
|
||||||
const int nixSchemaVersion = 10;
|
const int nixSchemaVersion = 10;
|
||||||
|
|
||||||
|
|
||||||
extern string drvsLogDir;
|
|
||||||
|
|
||||||
|
|
||||||
struct Derivation;
|
struct Derivation;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -566,6 +566,11 @@ public:
|
||||||
if they lack a signature. */
|
if they lack a signature. */
|
||||||
virtual bool isTrusted() { return false; }
|
virtual bool isTrusted() { return false; }
|
||||||
|
|
||||||
|
/* Return the build log of the specified store path, if available,
|
||||||
|
or null otherwise. */
|
||||||
|
virtual std::shared_ptr<std::string> getBuildLog(const Path & path)
|
||||||
|
{ return nullptr; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Stats stats;
|
Stats stats;
|
||||||
|
@ -579,6 +584,7 @@ public:
|
||||||
const Path rootDir;
|
const Path rootDir;
|
||||||
const Path stateDir;
|
const Path stateDir;
|
||||||
const Path logDir;
|
const Path logDir;
|
||||||
|
const static string drvsLogDir;
|
||||||
|
|
||||||
LocalFSStore(const Params & params);
|
LocalFSStore(const Params & params);
|
||||||
|
|
||||||
|
@ -595,6 +601,8 @@ public:
|
||||||
{
|
{
|
||||||
return getRealStoreDir() + "/" + baseNameOf(storePath);
|
return getRealStoreDir() + "/" + baseNameOf(storePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<std::string> getBuildLog(const Path & path) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
#include "worker-protocol.hh"
|
#include "worker-protocol.hh"
|
||||||
#include "xmlgraph.hh"
|
#include "xmlgraph.hh"
|
||||||
#include "compression.hh"
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -482,58 +481,12 @@ static void opReadLog(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
RunPager pager;
|
RunPager pager;
|
||||||
|
|
||||||
// FIXME: move getting logs into Store.
|
|
||||||
auto store2 = std::dynamic_pointer_cast<LocalFSStore>(store);
|
|
||||||
if (!store2) throw Error(format("store ‘%s’ does not support reading logs") % store->getUri());
|
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = useDeriver(store->followLinksToStorePath(i));
|
auto path = store->followLinksToStorePath(i);
|
||||||
|
auto log = store->getBuildLog(path);
|
||||||
string baseName = baseNameOf(path);
|
if (!log)
|
||||||
bool found = false;
|
throw Error("build log of derivation ‘%s’ is not available", path);
|
||||||
|
std::cout << *log;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue