nix-super/src/libstore/local-fs-store.cc

123 lines
3.4 KiB
C++
Raw Normal View History

#include "archive.hh"
2023-11-01 18:09:28 +02:00
#include "source-accessor.hh"
#include "store-api.hh"
#include "local-fs-store.hh"
#include "globals.hh"
#include "compression.hh"
#include "derivations.hh"
namespace nix {
LocalFSStore::LocalFSStore(const Params & params)
: Store(params)
{
}
2023-11-01 18:09:28 +02:00
struct LocalStoreAccessor : public SourceAccessor
{
ref<LocalFSStore> store;
2023-11-01 18:09:28 +02:00
bool requireValidPath;
2023-11-01 18:09:28 +02:00
LocalStoreAccessor(ref<LocalFSStore> store, bool requireValidPath)
: store(store)
, requireValidPath(requireValidPath)
{ }
2023-11-01 18:09:28 +02:00
Path toRealPath(const CanonPath & path)
{
2023-11-01 18:09:28 +02:00
auto storePath = store->toStorePath(path.abs()).first;
if (requireValidPath && !store->isValidPath(storePath))
throw InvalidPath("path '%1%' is not a valid store path", store->printStorePath(storePath));
2023-11-01 18:09:28 +02:00
return store->getRealStoreDir() + path.abs().substr(store->storeDir.size());
}
2023-11-01 18:09:28 +02:00
std::optional<Stat> maybeLstat(const CanonPath & path) override
{
auto realPath = toRealPath(path);
2023-11-01 18:09:28 +02:00
// FIXME: use PosixSourceAccessor.
struct stat st;
2023-11-01 18:09:28 +02:00
if (::lstat(realPath.c_str(), &st)) {
if (errno == ENOENT || errno == ENOTDIR) return std::nullopt;
throw SysError("getting status of '%1%'", path);
}
if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode))
throw Error("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}};
}
2023-11-01 18:09:28 +02:00
DirEntries readDirectory(const CanonPath & path) override
{
auto realPath = toRealPath(path);
auto entries = nix::readDirectory(realPath);
2023-11-01 16:33:19 +02:00
DirEntries res;
for (auto & entry : entries)
2023-11-01 16:33:19 +02:00
res.insert_or_assign(entry.name, std::nullopt);
return res;
}
2023-11-01 18:09:28 +02:00
std::string readFile(const CanonPath & path) override
{
2023-11-01 18:09:28 +02:00
return nix::readFile(toRealPath(path));
}
2023-11-01 18:09:28 +02:00
std::string readLink(const CanonPath & path) override
{
return nix::readLink(toRealPath(path));
}
};
2023-11-01 18:09:28 +02:00
ref<SourceAccessor> LocalFSStore::getFSAccessor(bool requireValidPath)
{
return make_ref<LocalStoreAccessor>(ref<LocalFSStore>(
2023-11-01 18:09:28 +02:00
std::dynamic_pointer_cast<LocalFSStore>(shared_from_this())),
requireValidPath);
}
void LocalFSStore::narFromPath(const StorePath & path, Sink & sink)
{
2016-03-22 15:21:45 +02:00
if (!isValidPath(path))
throw Error("path '%s' is not valid", printStorePath(path));
dumpPath(getRealStoreDir() + std::string(printStorePath(path), storeDir.size()), sink);
}
const std::string LocalFSStore::drvsLogDir = "drvs";
std::optional<std::string> LocalFSStore::getBuildLogExact(const StorePath & path)
{
auto baseName = path.to_string();
for (int j = 0; j < 2; j++) {
Path logPath =
j == 0
? fmt("%s/%s/%s/%s", logDir, drvsLogDir, baseName.substr(0, 2), baseName.substr(2))
: fmt("%s/%s/%s", logDir, drvsLogDir, baseName);
Path logBz2Path = logPath + ".bz2";
if (pathExists(logPath))
return readFile(logPath);
else if (pathExists(logBz2Path)) {
try {
return decompress("bzip2", readFile(logBz2Path));
} catch (Error &) { }
}
}
return std::nullopt;
}
}