lix/src/libstore/local-fs-store.cc
Eelco Dolstra 0afeb7f51e
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.
2017-03-15 16:48:29 +01:00

123 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "archive.hh"
#include "fs-accessor.hh"
#include "store-api.hh"
#include "globals.hh"
#include "compression.hh"
#include "derivations.hh"
namespace nix {
LocalFSStore::LocalFSStore(const Params & params)
: Store(params)
, rootDir(get(params, "root"))
, stateDir(canonPath(get(params, "state", rootDir != "" ? rootDir + "/nix/var/nix" : settings.nixStateDir)))
, logDir(canonPath(get(params, "log", rootDir != "" ? rootDir + "/nix/var/log/nix" : settings.nixLogDir)))
{
}
struct LocalStoreAccessor : public FSAccessor
{
ref<LocalFSStore> store;
LocalStoreAccessor(ref<LocalFSStore> store) : store(store) { }
Path toRealPath(const Path & path)
{
Path storePath = store->toStorePath(path);
if (!store->isValidPath(storePath))
throw InvalidPath(format("path %1% is not a valid store path") % storePath);
return store->getRealStoreDir() + std::string(path, store->storeDir.size());
}
FSAccessor::Stat stat(const Path & path) override
{
auto realPath = toRealPath(path);
struct stat st;
if (lstat(path.c_str(), &st)) {
if (errno == ENOENT || errno == ENOTDIR) return {Type::tMissing, 0, false};
throw SysError(format("getting status of %1%") % path);
}
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode))
throw Error(format("file %1% has unsupported type") % path);
return {
S_ISREG(st.st_mode) ? Type::tRegular :
S_ISLNK(st.st_mode) ? Type::tSymlink :
Type::tDirectory,
S_ISREG(st.st_mode) ? (uint64_t) st.st_size : 0,
S_ISREG(st.st_mode) && st.st_mode & S_IXUSR};
}
StringSet readDirectory(const Path & path) override
{
auto realPath = toRealPath(path);
auto entries = nix::readDirectory(path);
StringSet res;
for (auto & entry : entries)
res.insert(entry.name);
return res;
}
std::string readFile(const Path & path) override
{
return nix::readFile(toRealPath(path));
}
std::string readLink(const Path & path) override
{
return nix::readLink(toRealPath(path));
}
};
ref<FSAccessor> LocalFSStore::getFSAccessor()
{
return make_ref<LocalStoreAccessor>(ref<LocalFSStore>(std::dynamic_pointer_cast<LocalFSStore>(shared_from_this())));
}
void LocalFSStore::narFromPath(const Path & path, Sink & sink)
{
if (!isValidPath(path))
throw Error(format("path %s is not valid") % path);
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;
}
}