mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-26 07:46:21 +02:00
Make the store directory a member variable of Store
This commit is contained in:
parent
1b5b654fe2
commit
7850d3d279
35 changed files with 315 additions and 296 deletions
2
Makefile
2
Makefile
|
@ -11,7 +11,6 @@ makefiles = \
|
||||||
src/nix-env/local.mk \
|
src/nix-env/local.mk \
|
||||||
src/nix-daemon/local.mk \
|
src/nix-daemon/local.mk \
|
||||||
src/nix-collect-garbage/local.mk \
|
src/nix-collect-garbage/local.mk \
|
||||||
src/download-via-ssh/local.mk \
|
|
||||||
src/nix-prefetch-url/local.mk \
|
src/nix-prefetch-url/local.mk \
|
||||||
perl/local.mk \
|
perl/local.mk \
|
||||||
scripts/local.mk \
|
scripts/local.mk \
|
||||||
|
@ -22,6 +21,7 @@ makefiles = \
|
||||||
misc/emacs/local.mk \
|
misc/emacs/local.mk \
|
||||||
doc/manual/local.mk \
|
doc/manual/local.mk \
|
||||||
tests/local.mk
|
tests/local.mk
|
||||||
|
#src/download-via-ssh/local.mk \
|
||||||
|
|
||||||
GLOBAL_CXXFLAGS += -std=c++11 -g -Wall
|
GLOBAL_CXXFLAGS += -std=c++11 -g -Wall
|
||||||
|
|
||||||
|
|
|
@ -161,8 +161,7 @@ SV * topoSortPaths(...)
|
||||||
SV * followLinksToStorePath(char * path)
|
SV * followLinksToStorePath(char * path)
|
||||||
CODE:
|
CODE:
|
||||||
try {
|
try {
|
||||||
store();
|
RETVAL = newSVpv(store()->followLinksToStorePath(path).c_str(), 0);
|
||||||
RETVAL = newSVpv(followLinksToStorePath(path).c_str(), 0);
|
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
croak("%s", e.what());
|
croak("%s", e.what());
|
||||||
}
|
}
|
||||||
|
@ -289,7 +288,7 @@ SV * makeFixedOutputPath(int recursive, char * algo, char * hash, char * name)
|
||||||
PPCODE:
|
PPCODE:
|
||||||
try {
|
try {
|
||||||
HashType ht = parseHashType(algo);
|
HashType ht = parseHashType(algo);
|
||||||
Path path = makeFixedOutputPath(recursive, ht,
|
Path path = store()->makeFixedOutputPath(recursive, ht,
|
||||||
parseHash16or32(ht, hash), name);
|
parseHash16or32(ht, hash), name);
|
||||||
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
|
|
|
@ -341,7 +341,7 @@ Path EvalState::checkSourcePath(const Path & path_)
|
||||||
/* To support import-from-derivation, allow access to anything in
|
/* To support import-from-derivation, allow access to anything in
|
||||||
the store. FIXME: only allow access to paths that have been
|
the store. FIXME: only allow access to paths that have been
|
||||||
constructed by this evaluation. */
|
constructed by this evaluation. */
|
||||||
if (isInStore(path)) return path;
|
if (store->isInStore(path)) return path;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Hack to support the chroot dependencies of corepkgs (see
|
/* Hack to support the chroot dependencies of corepkgs (see
|
||||||
|
@ -1517,7 +1517,7 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
||||||
dstPath = srcToStore[path];
|
dstPath = srcToStore[path];
|
||||||
else {
|
else {
|
||||||
dstPath = settings.readOnlyMode
|
dstPath = settings.readOnlyMode
|
||||||
? computeStorePathForPath(checkSourcePath(path)).first
|
? store->computeStorePathForPath(checkSourcePath(path)).first
|
||||||
: store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair);
|
: store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair);
|
||||||
srcToStore[path] = dstPath;
|
srcToStore[path] = dstPath;
|
||||||
printMsg(lvlChatty, format("copied source ‘%1%’ -> ‘%2%’")
|
printMsg(lvlChatty, format("copied source ‘%1%’ -> ‘%2%’")
|
||||||
|
|
|
@ -50,7 +50,7 @@ void EvalState::realiseContext(const PathSet & context)
|
||||||
for (auto & i : context) {
|
for (auto & i : context) {
|
||||||
std::pair<string, string> decoded = decodeContext(i);
|
std::pair<string, string> decoded = decodeContext(i);
|
||||||
Path ctx = decoded.first;
|
Path ctx = decoded.first;
|
||||||
assert(isStorePath(ctx));
|
assert(store->isStorePath(ctx));
|
||||||
if (!store->isValidPath(ctx))
|
if (!store->isValidPath(ctx))
|
||||||
throw InvalidPathError(ctx);
|
throw InvalidPathError(ctx);
|
||||||
if (!decoded.second.empty() && nix::isDerivation(ctx))
|
if (!decoded.second.empty() && nix::isDerivation(ctx))
|
||||||
|
@ -82,7 +82,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args
|
||||||
|
|
||||||
path = state.checkSourcePath(path);
|
path = state.checkSourcePath(path);
|
||||||
|
|
||||||
if (isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) {
|
if (state.store->isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) {
|
||||||
Derivation drv = readDerivation(path);
|
Derivation drv = readDerivation(path);
|
||||||
Value & w = *state.allocValue();
|
Value & w = *state.allocValue();
|
||||||
state.mkAttrs(w, 3 + drv.outputs.size());
|
state.mkAttrs(w, 3 + drv.outputs.size());
|
||||||
|
@ -624,7 +624,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
outputHash = printHash(h);
|
outputHash = printHash(h);
|
||||||
if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
|
if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo;
|
||||||
|
|
||||||
Path outPath = makeFixedOutputPath(outputHashRecursive, ht, h, drvName);
|
Path outPath = state.store->makeFixedOutputPath(outputHashRecursive, ht, h, drvName);
|
||||||
drv.env["out"] = outPath;
|
drv.env["out"] = outPath;
|
||||||
drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash);
|
drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash);
|
||||||
}
|
}
|
||||||
|
@ -646,7 +646,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
||||||
|
|
||||||
for (auto & i : drv.outputs)
|
for (auto & i : drv.outputs)
|
||||||
if (i.second.path == "") {
|
if (i.second.path == "") {
|
||||||
Path outPath = makeOutputPath(i.first, h, drvName);
|
Path outPath = state.store->makeOutputPath(i.first, h, drvName);
|
||||||
drv.env[i.first] = outPath;
|
drv.env[i.first] = outPath;
|
||||||
i.second.path = outPath;
|
i.second.path = outPath;
|
||||||
}
|
}
|
||||||
|
@ -702,10 +702,10 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V
|
||||||
/* Resolve symlinks in ‘path’, unless ‘path’ itself is a symlink
|
/* Resolve symlinks in ‘path’, unless ‘path’ itself is a symlink
|
||||||
directly in the store. The latter condition is necessary so
|
directly in the store. The latter condition is necessary so
|
||||||
e.g. nix-push does the right thing. */
|
e.g. nix-push does the right thing. */
|
||||||
if (!isStorePath(path)) path = canonPath(path, true);
|
if (!state.store->isStorePath(path)) path = canonPath(path, true);
|
||||||
if (!isInStore(path))
|
if (!state.store->isInStore(path))
|
||||||
throw EvalError(format("path ‘%1%’ is not in the Nix store, at %2%") % path % pos);
|
throw EvalError(format("path ‘%1%’ is not in the Nix store, at %2%") % path % pos);
|
||||||
Path path2 = toStorePath(path);
|
Path path2 = state.store->toStorePath(path);
|
||||||
if (!settings.readOnlyMode)
|
if (!settings.readOnlyMode)
|
||||||
state.store->ensurePath(path2);
|
state.store->ensurePath(path2);
|
||||||
context.insert(path2);
|
context.insert(path2);
|
||||||
|
@ -897,7 +897,7 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu
|
||||||
}
|
}
|
||||||
|
|
||||||
Path storePath = settings.readOnlyMode
|
Path storePath = settings.readOnlyMode
|
||||||
? computeStorePathForText(name, contents, refs)
|
? state.store->computeStorePathForText(name, contents, refs)
|
||||||
: state.store->addTextToStore(name, contents, refs, state.repair);
|
: state.store->addTextToStore(name, contents, refs, state.repair);
|
||||||
|
|
||||||
/* Note: we don't need to add `context' to the context of the
|
/* Note: we don't need to add `context' to the context of the
|
||||||
|
@ -963,7 +963,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args
|
||||||
path = state.checkSourcePath(path);
|
path = state.checkSourcePath(path);
|
||||||
|
|
||||||
Path dstPath = settings.readOnlyMode
|
Path dstPath = settings.readOnlyMode
|
||||||
? computeStorePathForPath(path, true, htSHA256, filter).first
|
? state.store->computeStorePathForPath(path, true, htSHA256, filter).first
|
||||||
: state.store->addToStore(baseNameOf(path), path, true, htSHA256, filter, state.repair);
|
: state.store->addToStore(baseNameOf(path), path, true, htSHA256, filter, state.repair);
|
||||||
|
|
||||||
mkString(v, dstPath, {dstPath});
|
mkString(v, dstPath, {dstPath});
|
||||||
|
@ -1765,7 +1765,7 @@ void EvalState::createBaseEnv()
|
||||||
mkString(v, nixVersion);
|
mkString(v, nixVersion);
|
||||||
addConstant("__nixVersion", v);
|
addConstant("__nixVersion", v);
|
||||||
|
|
||||||
mkString(v, settings.nixStore);
|
mkString(v, store->storeDir);
|
||||||
addConstant("__storeDir", v);
|
addConstant("__storeDir", v);
|
||||||
|
|
||||||
/* Language version. This should be increased every time a new
|
/* Language version. This should be increased every time a new
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
BinaryCacheStore::BinaryCacheStore(const StoreParams & params)
|
BinaryCacheStore::BinaryCacheStore(const Params & params)
|
||||||
: compression(get(params, "compression", "xz"))
|
: Store(params)
|
||||||
|
, compression(get(params, "compression", "xz"))
|
||||||
{
|
{
|
||||||
auto secretKeyFile = get(params, "secret-key", "");
|
auto secretKeyFile = get(params, "secret-key", "");
|
||||||
if (secretKeyFile != "")
|
if (secretKeyFile != "")
|
||||||
|
@ -32,7 +33,7 @@ void BinaryCacheStore::init()
|
||||||
|
|
||||||
auto cacheInfo = getFile(cacheInfoFile);
|
auto cacheInfo = getFile(cacheInfoFile);
|
||||||
if (!cacheInfo) {
|
if (!cacheInfo) {
|
||||||
upsertFile(cacheInfoFile, "StoreDir: " + settings.nixStore + "\n");
|
upsertFile(cacheInfoFile, "StoreDir: " + storeDir + "\n");
|
||||||
} else {
|
} else {
|
||||||
for (auto & line : tokenizeString<Strings>(*cacheInfo, "\n")) {
|
for (auto & line : tokenizeString<Strings>(*cacheInfo, "\n")) {
|
||||||
size_t colon = line.find(':');
|
size_t colon = line.find(':');
|
||||||
|
@ -40,9 +41,9 @@ void BinaryCacheStore::init()
|
||||||
auto name = line.substr(0, colon);
|
auto name = line.substr(0, colon);
|
||||||
auto value = trim(line.substr(colon + 1, std::string::npos));
|
auto value = trim(line.substr(colon + 1, std::string::npos));
|
||||||
if (name == "StoreDir") {
|
if (name == "StoreDir") {
|
||||||
if (value != settings.nixStore)
|
if (value != storeDir)
|
||||||
throw Error(format("binary cache ‘%s’ is for Nix stores with prefix ‘%s’, not ‘%s’")
|
throw Error(format("binary cache ‘%s’ is for Nix stores with prefix ‘%s’, not ‘%s’")
|
||||||
% getUri() % value % settings.nixStore);
|
% getUri() % value % storeDir);
|
||||||
} else if (name == "WantMassQuery") {
|
} else if (name == "WantMassQuery") {
|
||||||
wantMassQuery_ = value == "1";
|
wantMassQuery_ = value == "1";
|
||||||
} else if (name == "Priority") {
|
} else if (name == "Priority") {
|
||||||
|
@ -181,7 +182,7 @@ std::shared_ptr<ValidPathInfo> BinaryCacheStore::queryPathInfoUncached(const Pat
|
||||||
auto data = getFile(narInfoFile);
|
auto data = getFile(narInfoFile);
|
||||||
if (!data) return 0;
|
if (!data) return 0;
|
||||||
|
|
||||||
auto narInfo = make_ref<NarInfo>(*data, narInfoFile);
|
auto narInfo = make_ref<NarInfo>(*this, *data, narInfoFile);
|
||||||
|
|
||||||
stats.narInfoRead++;
|
stats.narInfoRead++;
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ struct BinaryCacheStoreAccessor : public FSAccessor
|
||||||
{
|
{
|
||||||
auto path = canonPath(path_);
|
auto path = canonPath(path_);
|
||||||
|
|
||||||
auto storePath = toStorePath(path);
|
auto storePath = store->toStorePath(path);
|
||||||
std::string restPath = std::string(path, storePath.size());
|
std::string restPath = std::string(path, storePath.size());
|
||||||
|
|
||||||
if (!store->isValidPath(storePath))
|
if (!store->isValidPath(storePath))
|
||||||
|
|
|
@ -21,7 +21,7 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
BinaryCacheStore(const StoreParams & params);
|
BinaryCacheStore(const Params & params);
|
||||||
|
|
||||||
[[noreturn]] void notImpl();
|
[[noreturn]] void notImpl();
|
||||||
|
|
||||||
|
|
|
@ -1442,7 +1442,7 @@ void DerivationGoal::buildDone()
|
||||||
#if HAVE_STATVFS
|
#if HAVE_STATVFS
|
||||||
unsigned long long required = 8ULL * 1024 * 1024; // FIXME: make configurable
|
unsigned long long required = 8ULL * 1024 * 1024; // FIXME: make configurable
|
||||||
struct statvfs st;
|
struct statvfs st;
|
||||||
if (statvfs(settings.nixStore.c_str(), &st) == 0 &&
|
if (statvfs(worker.store.storeDir.c_str(), &st) == 0 &&
|
||||||
(unsigned long long) st.f_bavail * st.f_bsize < required)
|
(unsigned long long) st.f_bavail * st.f_bsize < required)
|
||||||
diskFull = true;
|
diskFull = true;
|
||||||
if (statvfs(tmpDir.c_str(), &st) == 0 &&
|
if (statvfs(tmpDir.c_str(), &st) == 0 &&
|
||||||
|
@ -1701,7 +1701,7 @@ void DerivationGoal::startBuilder()
|
||||||
shouldn't care, but this is useful for purity checking (e.g.,
|
shouldn't care, but this is useful for purity checking (e.g.,
|
||||||
the compiler or linker might only want to accept paths to files
|
the compiler or linker might only want to accept paths to files
|
||||||
in the store or in the build directory). */
|
in the store or in the build directory). */
|
||||||
env["NIX_STORE"] = settings.nixStore;
|
env["NIX_STORE"] = worker.store.storeDir;
|
||||||
|
|
||||||
/* The maximum number of cores to utilize for parallel building. */
|
/* The maximum number of cores to utilize for parallel building. */
|
||||||
env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
|
env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
|
||||||
|
@ -1784,10 +1784,10 @@ void DerivationGoal::startBuilder()
|
||||||
|
|
||||||
/* Check that the store path is valid. */
|
/* Check that the store path is valid. */
|
||||||
Path storePath = *i++;
|
Path storePath = *i++;
|
||||||
if (!isInStore(storePath))
|
if (!worker.store.isInStore(storePath))
|
||||||
throw BuildError(format("‘exportReferencesGraph’ contains a non-store path ‘%1%’")
|
throw BuildError(format("‘exportReferencesGraph’ contains a non-store path ‘%1%’")
|
||||||
% storePath);
|
% storePath);
|
||||||
storePath = toStorePath(storePath);
|
storePath = worker.store.toStorePath(storePath);
|
||||||
if (!worker.store.isValidPath(storePath))
|
if (!worker.store.isValidPath(storePath))
|
||||||
throw BuildError(format("‘exportReferencesGraph’ contains an invalid path ‘%1%’")
|
throw BuildError(format("‘exportReferencesGraph’ contains an invalid path ‘%1%’")
|
||||||
% storePath);
|
% storePath);
|
||||||
|
@ -1838,7 +1838,7 @@ void DerivationGoal::startBuilder()
|
||||||
|
|
||||||
string defaultChrootDirs;
|
string defaultChrootDirs;
|
||||||
#if __linux__
|
#if __linux__
|
||||||
if (isInStore(BASH_PATH))
|
if (worker.store.isInStore(BASH_PATH))
|
||||||
defaultChrootDirs = "/bin/sh=" BASH_PATH;
|
defaultChrootDirs = "/bin/sh=" BASH_PATH;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1867,8 +1867,8 @@ void DerivationGoal::startBuilder()
|
||||||
/* Add the closure of store paths to the chroot. */
|
/* Add the closure of store paths to the chroot. */
|
||||||
PathSet closure;
|
PathSet closure;
|
||||||
for (auto & i : dirsInChroot)
|
for (auto & i : dirsInChroot)
|
||||||
if (isInStore(i.second))
|
if (worker.store.isInStore(i.second))
|
||||||
worker.store.computeFSClosure(toStorePath(i.second), closure);
|
worker.store.computeFSClosure(worker.store.toStorePath(i.second), closure);
|
||||||
for (auto & i : closure)
|
for (auto & i : closure)
|
||||||
dirsInChroot[i] = i;
|
dirsInChroot[i] = i;
|
||||||
|
|
||||||
|
@ -1953,7 +1953,7 @@ void DerivationGoal::startBuilder()
|
||||||
can be bind-mounted). !!! As an extra security
|
can be bind-mounted). !!! As an extra security
|
||||||
precaution, make the fake Nix store only writable by the
|
precaution, make the fake Nix store only writable by the
|
||||||
build user. */
|
build user. */
|
||||||
Path chrootStoreDir = chrootRootDir + settings.nixStore;
|
Path chrootStoreDir = chrootRootDir + worker.store.storeDir;
|
||||||
createDirs(chrootStoreDir);
|
createDirs(chrootStoreDir);
|
||||||
chmod_(chrootStoreDir, 01775);
|
chmod_(chrootStoreDir, 01775);
|
||||||
|
|
||||||
|
@ -2408,7 +2408,7 @@ void DerivationGoal::runChild()
|
||||||
|
|
||||||
/* And we want the store in there regardless of how empty dirsInChroot. We include the innermost
|
/* And we want the store in there regardless of how empty dirsInChroot. We include the innermost
|
||||||
path component this time, since it's typically /nix/store and we care about that. */
|
path component this time, since it's typically /nix/store and we care about that. */
|
||||||
Path cur = settings.nixStore;
|
Path cur = worker.store.storeDir;
|
||||||
while (cur.compare("/") != 0) {
|
while (cur.compare("/") != 0) {
|
||||||
ancestry.insert(cur);
|
ancestry.insert(cur);
|
||||||
cur = dirOf(cur);
|
cur = dirOf(cur);
|
||||||
|
@ -2532,12 +2532,12 @@ void DerivationGoal::runChild()
|
||||||
/* Parse a list of reference specifiers. Each element must either be
|
/* Parse a list of reference specifiers. Each element must either be
|
||||||
a store path, or the symbolic name of the output of the derivation
|
a store path, or the symbolic name of the output of the derivation
|
||||||
(such as `out'). */
|
(such as `out'). */
|
||||||
PathSet parseReferenceSpecifiers(const BasicDerivation & drv, string attr)
|
PathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv, string attr)
|
||||||
{
|
{
|
||||||
PathSet result;
|
PathSet result;
|
||||||
Paths paths = tokenizeString<Paths>(attr);
|
Paths paths = tokenizeString<Paths>(attr);
|
||||||
for (auto & i : paths) {
|
for (auto & i : paths) {
|
||||||
if (isStorePath(i))
|
if (store.isStorePath(i))
|
||||||
result.insert(i);
|
result.insert(i);
|
||||||
else if (drv.outputs.find(i) != drv.outputs.end())
|
else if (drv.outputs.find(i) != drv.outputs.end())
|
||||||
result.insert(drv.outputs.find(i)->second.path);
|
result.insert(drv.outputs.find(i)->second.path);
|
||||||
|
@ -2660,7 +2660,7 @@ void DerivationGoal::registerOutputs()
|
||||||
the derivation to its content-addressed location. */
|
the derivation to its content-addressed location. */
|
||||||
Hash h2 = recursive ? hashPath(ht, actualPath).first : hashFile(ht, actualPath);
|
Hash h2 = recursive ? hashPath(ht, actualPath).first : hashFile(ht, actualPath);
|
||||||
if (buildMode == bmHash) {
|
if (buildMode == bmHash) {
|
||||||
Path dest = makeFixedOutputPath(recursive, ht, h2, drv->env["name"]);
|
Path dest = worker.store.makeFixedOutputPath(recursive, ht, h2, drv->env["name"]);
|
||||||
printMsg(lvlError, format("build produced path ‘%1%’ with %2% hash ‘%3%’")
|
printMsg(lvlError, format("build produced path ‘%1%’ with %2% hash ‘%3%’")
|
||||||
% dest % printHashType(ht) % printHash16or32(h2));
|
% dest % printHashType(ht) % printHash16or32(h2));
|
||||||
if (worker.store.isValidPath(dest))
|
if (worker.store.isValidPath(dest))
|
||||||
|
@ -2733,7 +2733,7 @@ void DerivationGoal::registerOutputs()
|
||||||
auto checkRefs = [&](const string & attrName, bool allowed, bool recursive) {
|
auto checkRefs = [&](const string & attrName, bool allowed, bool recursive) {
|
||||||
if (drv->env.find(attrName) == drv->env.end()) return;
|
if (drv->env.find(attrName) == drv->env.end()) return;
|
||||||
|
|
||||||
PathSet spec = parseReferenceSpecifiers(*drv, get(drv->env, attrName));
|
PathSet spec = parseReferenceSpecifiers(worker.store, *drv, get(drv->env, attrName));
|
||||||
|
|
||||||
PathSet used;
|
PathSet used;
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
|
@ -2965,9 +2965,9 @@ PathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash)
|
||||||
|
|
||||||
Path DerivationGoal::addHashRewrite(const Path & path)
|
Path DerivationGoal::addHashRewrite(const Path & path)
|
||||||
{
|
{
|
||||||
string h1 = string(path, settings.nixStore.size() + 1, 32);
|
string h1 = string(path, worker.store.storeDir.size() + 1, 32);
|
||||||
string h2 = string(printHash32(hashString(htSHA256, "rewrite:" + drvPath + ":" + path)), 0, 32);
|
string h2 = string(printHash32(hashString(htSHA256, "rewrite:" + drvPath + ":" + path)), 0, 32);
|
||||||
Path p = settings.nixStore + "/" + h2 + string(path, settings.nixStore.size() + 33);
|
Path p = worker.store.storeDir + "/" + h2 + string(path, worker.store.storeDir.size() + 33);
|
||||||
deletePath(p);
|
deletePath(p);
|
||||||
assert(path.size() == p.size());
|
assert(path.size() == p.size());
|
||||||
rewritesToTmp[h1] = h2;
|
rewritesToTmp[h1] = h2;
|
||||||
|
|
|
@ -26,7 +26,6 @@ void builtinFetchurl(const BasicDerivation & drv)
|
||||||
if (out == drv.env.end()) throw Error("attribute ‘url’ missing");
|
if (out == drv.env.end()) throw Error("attribute ‘url’ missing");
|
||||||
|
|
||||||
Path storePath = out->second;
|
Path storePath = out->second;
|
||||||
assertStorePath(storePath);
|
|
||||||
|
|
||||||
auto unpack = drv.env.find("unpack");
|
auto unpack = drv.env.find("unpack");
|
||||||
if (unpack != drv.env.end() && unpack->second == "1") {
|
if (unpack != drv.env.end() && unpack->second == "1") {
|
||||||
|
|
|
@ -81,7 +81,7 @@ Path writeDerivation(ref<Store> store,
|
||||||
string suffix = name + drvExtension;
|
string suffix = name + drvExtension;
|
||||||
string contents = drv.unparse();
|
string contents = drv.unparse();
|
||||||
return settings.readOnlyMode
|
return settings.readOnlyMode
|
||||||
? computeStorePathForText(suffix, contents, references)
|
? store->computeStorePathForText(suffix, contents, references)
|
||||||
: store->addTextToStore(suffix, contents, references, repair);
|
: store->addTextToStore(suffix, contents, references, repair);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ PathSet BasicDerivation::outputPaths() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Source & operator >> (Source & in, BasicDerivation & drv)
|
Source & readDerivation(Source & in, Store & store, BasicDerivation & drv)
|
||||||
{
|
{
|
||||||
drv.outputs.clear();
|
drv.outputs.clear();
|
||||||
auto nr = readInt(in);
|
auto nr = readInt(in);
|
||||||
|
@ -344,11 +344,11 @@ Source & operator >> (Source & in, BasicDerivation & drv)
|
||||||
auto name = readString(in);
|
auto name = readString(in);
|
||||||
DerivationOutput o;
|
DerivationOutput o;
|
||||||
in >> o.path >> o.hashAlgo >> o.hash;
|
in >> o.path >> o.hashAlgo >> o.hash;
|
||||||
assertStorePath(o.path);
|
store.assertStorePath(o.path);
|
||||||
drv.outputs[name] = o;
|
drv.outputs[name] = o;
|
||||||
}
|
}
|
||||||
|
|
||||||
drv.inputSrcs = readStorePaths<PathSet>(in);
|
drv.inputSrcs = readStorePaths<PathSet>(store, in);
|
||||||
in >> drv.platform >> drv.builder;
|
in >> drv.platform >> drv.builder;
|
||||||
drv.args = readStrings<Strings>(in);
|
drv.args = readStrings<Strings>(in);
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ bool wantOutput(const string & output, const std::set<string> & wanted);
|
||||||
struct Source;
|
struct Source;
|
||||||
struct Sink;
|
struct Sink;
|
||||||
|
|
||||||
Source & operator >> (Source & in, BasicDerivation & drv);
|
Source & readDerivation(Source & in, Store & store, BasicDerivation & drv);
|
||||||
Sink & operator << (Sink & out, const BasicDerivation & drv);
|
Sink & operator << (Sink & out, const BasicDerivation & drv);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,11 +101,11 @@ Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor,
|
||||||
|
|
||||||
ValidPathInfo info;
|
ValidPathInfo info;
|
||||||
|
|
||||||
info.path = readStorePath(source);
|
info.path = readStorePath(*this, source);
|
||||||
|
|
||||||
Activity act(*logger, lvlInfo, format("importing path ‘%s’") % info.path);
|
Activity act(*logger, lvlInfo, format("importing path ‘%s’") % info.path);
|
||||||
|
|
||||||
info.references = readStorePaths<PathSet>(source);
|
info.references = readStorePaths<PathSet>(*this, source);
|
||||||
|
|
||||||
info.deriver = readString(source);
|
info.deriver = readString(source);
|
||||||
if (info.deriver != "") assertStorePath(info.deriver);
|
if (info.deriver != "") assertStorePath(info.deriver);
|
||||||
|
|
|
@ -204,7 +204,7 @@ typedef std::shared_ptr<AutoCloseFD> FDPtr;
|
||||||
typedef list<FDPtr> FDs;
|
typedef list<FDPtr> FDs;
|
||||||
|
|
||||||
|
|
||||||
static void readTempRoots(PathSet & tempRoots, FDs & fds)
|
static void readTempRoots(Store & store, PathSet & tempRoots, FDs & fds)
|
||||||
{
|
{
|
||||||
/* Read the `temproots' directory for per-process temporary root
|
/* Read the `temproots' directory for per-process temporary root
|
||||||
files. */
|
files. */
|
||||||
|
@ -251,7 +251,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||||
while ((end = contents.find((char) 0, pos)) != string::npos) {
|
while ((end = contents.find((char) 0, pos)) != string::npos) {
|
||||||
Path root(contents, pos, end - pos);
|
Path root(contents, pos, end - pos);
|
||||||
debug(format("got temporary root ‘%1%’") % root);
|
debug(format("got temporary root ‘%1%’") % root);
|
||||||
assertStorePath(root);
|
store.assertStorePath(root);
|
||||||
tempRoots.insert(root);
|
tempRoots.insert(root);
|
||||||
pos = end + 1;
|
pos = end + 1;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (type == DT_REG) {
|
else if (type == DT_REG) {
|
||||||
Path storePath = settings.nixStore + "/" + baseNameOf(path);
|
Path storePath = storeDir + "/" + baseNameOf(path);
|
||||||
if (isStorePath(storePath) && isValidPath(storePath))
|
if (isStorePath(storePath) && isValidPath(storePath))
|
||||||
roots[path] = storePath;
|
roots[path] = storePath;
|
||||||
}
|
}
|
||||||
|
@ -594,7 +594,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
{
|
{
|
||||||
GCState state(results);
|
GCState state(results);
|
||||||
state.options = options;
|
state.options = options;
|
||||||
state.trashDir = settings.nixStore + "/trash";
|
state.trashDir = storeDir + "/trash";
|
||||||
state.gcKeepOutputs = settings.gcKeepOutputs;
|
state.gcKeepOutputs = settings.gcKeepOutputs;
|
||||||
state.gcKeepDerivations = settings.gcKeepDerivations;
|
state.gcKeepDerivations = settings.gcKeepDerivations;
|
||||||
|
|
||||||
|
@ -635,7 +635,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
per-process temporary root files. So after this point no paths
|
per-process temporary root files. So after this point no paths
|
||||||
can be added to the set of temporary roots. */
|
can be added to the set of temporary roots. */
|
||||||
FDs fds;
|
FDs fds;
|
||||||
readTempRoots(state.tempRoots, fds);
|
readTempRoots(*this, state.tempRoots, fds);
|
||||||
state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
|
state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
|
||||||
|
|
||||||
/* After this point the set of roots or temporary roots cannot
|
/* After this point the set of roots or temporary roots cannot
|
||||||
|
@ -675,8 +675,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
AutoCloseDir dir = opendir(settings.nixStore.c_str());
|
AutoCloseDir dir = opendir(storeDir.c_str());
|
||||||
if (!dir) throw SysError(format("opening directory ‘%1%’") % settings.nixStore);
|
if (!dir) throw SysError(format("opening directory ‘%1%’") % storeDir);
|
||||||
|
|
||||||
/* Read the store and immediately delete all paths that
|
/* Read the store and immediately delete all paths that
|
||||||
aren't valid. When using --max-freed etc., deleting
|
aren't valid. When using --max-freed etc., deleting
|
||||||
|
@ -690,7 +690,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
string name = dirent->d_name;
|
string name = dirent->d_name;
|
||||||
if (name == "." || name == "..") continue;
|
if (name == "." || name == "..") continue;
|
||||||
Path path = settings.nixStore + "/" + name;
|
Path path = storeDir + "/" + name;
|
||||||
if (isStorePath(path) && isValidPath(path))
|
if (isStorePath(path) && isValidPath(path))
|
||||||
entries.push_back(path);
|
entries.push_back(path);
|
||||||
else
|
else
|
||||||
|
|
|
@ -18,7 +18,7 @@ private:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HttpBinaryCacheStore(
|
HttpBinaryCacheStore(
|
||||||
const StoreParams & params, const Path & _cacheUri)
|
const Params & params, const Path & _cacheUri)
|
||||||
: BinaryCacheStore(params)
|
: BinaryCacheStore(params)
|
||||||
, cacheUri(_cacheUri)
|
, cacheUri(_cacheUri)
|
||||||
, downloaders(
|
, downloaders(
|
||||||
|
@ -45,7 +45,7 @@ public:
|
||||||
} catch (UploadToHTTP &) {
|
} catch (UploadToHTTP &) {
|
||||||
throw Error(format("‘%s’ does not appear to be a binary cache") % cacheUri);
|
throw Error(format("‘%s’ does not appear to be a binary cache") % cacheUri);
|
||||||
}
|
}
|
||||||
diskCache->createCache(cacheUri, wantMassQuery_, priority);
|
diskCache->createCache(cacheUri, storeDir, wantMassQuery_, priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
static RegisterStoreImplementation regStore([](
|
static RegisterStoreImplementation regStore([](
|
||||||
const std::string & uri, const StoreParams & params)
|
const std::string & uri, const Store::Params & params)
|
||||||
-> std::shared_ptr<Store>
|
-> std::shared_ptr<Store>
|
||||||
{
|
{
|
||||||
if (std::string(uri, 0, 7) != "http://" &&
|
if (std::string(uri, 0, 7) != "http://" &&
|
||||||
|
|
|
@ -13,7 +13,7 @@ private:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LocalBinaryCacheStore(
|
LocalBinaryCacheStore(
|
||||||
const StoreParams & params, const Path & binaryCacheDir)
|
const Params & params, const Path & binaryCacheDir)
|
||||||
: BinaryCacheStore(params)
|
: BinaryCacheStore(params)
|
||||||
, binaryCacheDir(binaryCacheDir)
|
, binaryCacheDir(binaryCacheDir)
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@ protected:
|
||||||
if (entry.name.size() != 40 ||
|
if (entry.name.size() != 40 ||
|
||||||
!hasSuffix(entry.name, ".narinfo"))
|
!hasSuffix(entry.name, ".narinfo"))
|
||||||
continue;
|
continue;
|
||||||
paths.insert(settings.nixStore + "/" + entry.name.substr(0, entry.name.size() - 8));
|
paths.insert(storeDir + "/" + entry.name.substr(0, entry.name.size() - 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
return paths;
|
return paths;
|
||||||
|
@ -59,7 +59,7 @@ void LocalBinaryCacheStore::init()
|
||||||
BinaryCacheStore::init();
|
BinaryCacheStore::init();
|
||||||
|
|
||||||
if (diskCache && !diskCache->cacheExists(getUri()))
|
if (diskCache && !diskCache->cacheExists(getUri()))
|
||||||
diskCache->createCache(getUri(), wantMassQuery_, priority);
|
diskCache->createCache(getUri(), storeDir, wantMassQuery_, priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void atomicWrite(const Path & path, const std::string & s)
|
static void atomicWrite(const Path & path, const std::string & s)
|
||||||
|
@ -93,7 +93,7 @@ std::shared_ptr<std::string> LocalBinaryCacheStore::getFile(const std::string &
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterStoreImplementation regStore([](
|
static RegisterStoreImplementation regStore([](
|
||||||
const std::string & uri, const StoreParams & params)
|
const std::string & uri, const Store::Params & params)
|
||||||
-> std::shared_ptr<Store>
|
-> std::shared_ptr<Store>
|
||||||
{
|
{
|
||||||
if (std::string(uri, 0, 7) != "file://") return 0;
|
if (std::string(uri, 0, 7) != "file://") return 0;
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct LocalStoreAccessor : public FSAccessor
|
||||||
|
|
||||||
void assertStore(const Path & path)
|
void assertStore(const Path & path)
|
||||||
{
|
{
|
||||||
Path storePath = toStorePath(path);
|
Path storePath = store->toStorePath(path);
|
||||||
if (!store->isValidPath(storePath))
|
if (!store->isValidPath(storePath))
|
||||||
throw Error(format("path ‘%1%’ is not a valid store path") % storePath);
|
throw Error(format("path ‘%1%’ is not a valid store path") % storePath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,26 +36,9 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
void checkStoreNotSymlink()
|
LocalStore::LocalStore(const Params & params)
|
||||||
{
|
: LocalFSStore(params)
|
||||||
if (getEnv("NIX_IGNORE_SYMLINK_STORE") == "1") return;
|
, linksDir(storeDir + "/.links")
|
||||||
Path path = settings.nixStore;
|
|
||||||
struct stat st;
|
|
||||||
while (path != "/") {
|
|
||||||
if (lstat(path.c_str(), &st))
|
|
||||||
throw SysError(format("getting status of ‘%1%’") % path);
|
|
||||||
if (S_ISLNK(st.st_mode))
|
|
||||||
throw Error(format(
|
|
||||||
"the path ‘%1%’ is a symlink; "
|
|
||||||
"this is not allowed for the Nix store and its parent directories")
|
|
||||||
% path);
|
|
||||||
path = dirOf(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LocalStore::LocalStore()
|
|
||||||
: linksDir(settings.nixStore + "/.links")
|
|
||||||
, reservedPath(settings.nixDBPath + "/reserved")
|
, reservedPath(settings.nixDBPath + "/reserved")
|
||||||
, schemaPath(settings.nixDBPath + "/schema")
|
, schemaPath(settings.nixDBPath + "/schema")
|
||||||
, requireSigs(settings.get("signed-binary-caches", std::string("")) != "") // FIXME: rename option
|
, requireSigs(settings.get("signed-binary-caches", std::string("")) != "") // FIXME: rename option
|
||||||
|
@ -69,7 +52,7 @@ LocalStore::LocalStore()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create missing state directories if they don't already exist. */
|
/* Create missing state directories if they don't already exist. */
|
||||||
createDirs(settings.nixStore);
|
createDirs(storeDir);
|
||||||
makeStoreWritable();
|
makeStoreWritable();
|
||||||
createDirs(linksDir);
|
createDirs(linksDir);
|
||||||
Path profilesDir = settings.nixStateDir + "/profiles";
|
Path profilesDir = settings.nixStateDir + "/profiles";
|
||||||
|
@ -99,19 +82,33 @@ LocalStore::LocalStore()
|
||||||
% settings.buildUsersGroup);
|
% settings.buildUsersGroup);
|
||||||
else {
|
else {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(settings.nixStore.c_str(), &st))
|
if (stat(storeDir.c_str(), &st))
|
||||||
throw SysError(format("getting attributes of path ‘%1%’") % settings.nixStore);
|
throw SysError(format("getting attributes of path ‘%1%’") % storeDir);
|
||||||
|
|
||||||
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) {
|
||||||
if (chown(settings.nixStore.c_str(), 0, gr->gr_gid) == -1)
|
if (chown(storeDir.c_str(), 0, gr->gr_gid) == -1)
|
||||||
throw SysError(format("changing ownership of path ‘%1%’") % settings.nixStore);
|
throw SysError(format("changing ownership of path ‘%1%’") % storeDir);
|
||||||
if (chmod(settings.nixStore.c_str(), perm) == -1)
|
if (chmod(storeDir.c_str(), perm) == -1)
|
||||||
throw SysError(format("changing permissions on path ‘%1%’") % settings.nixStore);
|
throw SysError(format("changing permissions on path ‘%1%’") % storeDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkStoreNotSymlink();
|
/* Ensure that the store and its parents are not symlinks. */
|
||||||
|
if (getEnv("NIX_IGNORE_SYMLINK_STORE") != "1") {
|
||||||
|
Path path = storeDir;
|
||||||
|
struct stat st;
|
||||||
|
while (path != "/") {
|
||||||
|
if (lstat(path.c_str(), &st))
|
||||||
|
throw SysError(format("getting status of ‘%1%’") % path);
|
||||||
|
if (S_ISLNK(st.st_mode))
|
||||||
|
throw Error(format(
|
||||||
|
"the path ‘%1%’ is a symlink; "
|
||||||
|
"this is not allowed for the Nix store and its parent directories")
|
||||||
|
% path);
|
||||||
|
path = dirOf(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We can't open a SQLite database if the disk is full. Since
|
/* We can't open a SQLite database if the disk is full. Since
|
||||||
this prevents the garbage collector from running when it's most
|
this prevents the garbage collector from running when it's most
|
||||||
|
@ -351,15 +348,15 @@ void LocalStore::makeStoreWritable()
|
||||||
if (getuid() != 0) return;
|
if (getuid() != 0) return;
|
||||||
/* Check if /nix/store is on a read-only mount. */
|
/* Check if /nix/store is on a read-only mount. */
|
||||||
struct statvfs stat;
|
struct statvfs stat;
|
||||||
if (statvfs(settings.nixStore.c_str(), &stat) != 0)
|
if (statvfs(storeDir.c_str(), &stat) != 0)
|
||||||
throw SysError("getting info about the Nix store mount point");
|
throw SysError("getting info about the Nix store mount point");
|
||||||
|
|
||||||
if (stat.f_flag & ST_RDONLY) {
|
if (stat.f_flag & ST_RDONLY) {
|
||||||
if (unshare(CLONE_NEWNS) == -1)
|
if (unshare(CLONE_NEWNS) == -1)
|
||||||
throw SysError("setting up a private mount namespace");
|
throw SysError("setting up a private mount namespace");
|
||||||
|
|
||||||
if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
if (mount(0, storeDir.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
||||||
throw SysError(format("remounting %1% writable") % settings.nixStore);
|
throw SysError(format("remounting %1% writable") % storeDir);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -771,7 +768,7 @@ Path LocalStore::queryPathFromHashPart(const string & hashPart)
|
||||||
{
|
{
|
||||||
if (hashPart.size() != storePathHashLen) throw Error("invalid hash part");
|
if (hashPart.size() != storePathHashLen) throw Error("invalid hash part");
|
||||||
|
|
||||||
Path prefix = settings.nixStore + "/" + hashPart;
|
Path prefix = storeDir + "/" + hashPart;
|
||||||
|
|
||||||
return retrySQLite<Path>([&]() {
|
return retrySQLite<Path>([&]() {
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
|
@ -1071,7 +1068,7 @@ Path LocalStore::createTempDirInStore()
|
||||||
/* There is a slight possibility that `tmpDir' gets deleted by
|
/* There is a slight possibility that `tmpDir' gets deleted by
|
||||||
the GC between createTempDir() and addTempRoot(), so repeat
|
the GC between createTempDir() and addTempRoot(), so repeat
|
||||||
until `tmpDir' exists. */
|
until `tmpDir' exists. */
|
||||||
tmpDir = createTempDir(settings.nixStore);
|
tmpDir = createTempDir(storeDir);
|
||||||
addTempRoot(tmpDir);
|
addTempRoot(tmpDir);
|
||||||
} while (!pathExists(tmpDir));
|
} while (!pathExists(tmpDir));
|
||||||
return tmpDir;
|
return tmpDir;
|
||||||
|
@ -1111,7 +1108,7 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
|
||||||
AutoCloseFD fdGCLock = openGCLock(ltWrite);
|
AutoCloseFD fdGCLock = openGCLock(ltWrite);
|
||||||
|
|
||||||
PathSet store;
|
PathSet store;
|
||||||
for (auto & i : readDirectory(settings.nixStore)) store.insert(i.name);
|
for (auto & i : readDirectory(storeDir)) store.insert(i.name);
|
||||||
|
|
||||||
/* Check whether all valid paths actually exist. */
|
/* Check whether all valid paths actually exist. */
|
||||||
printMsg(lvlInfo, "checking path existence...");
|
printMsg(lvlInfo, "checking path existence...");
|
||||||
|
@ -1275,7 +1272,7 @@ void LocalStore::upgradeStore7()
|
||||||
{
|
{
|
||||||
if (getuid() != 0) return;
|
if (getuid() != 0) return;
|
||||||
printMsg(lvlError, "removing immutable bits from the Nix store (this may take a while)...");
|
printMsg(lvlError, "removing immutable bits from the Nix store (this may take a while)...");
|
||||||
makeMutable(settings.nixStore);
|
makeMutable(storeDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -85,7 +85,7 @@ public:
|
||||||
|
|
||||||
/* Initialise the local store, upgrading the schema if
|
/* Initialise the local store, upgrading the schema if
|
||||||
necessary. */
|
necessary. */
|
||||||
LocalStore();
|
LocalStore(const Params & params);
|
||||||
|
|
||||||
~LocalStore();
|
~LocalStore();
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "nar-info-disk-cache.hh"
|
#include "nar-info-disk-cache.hh"
|
||||||
#include "sync.hh"
|
#include "sync.hh"
|
||||||
#include "sqlite.hh"
|
#include "sqlite.hh"
|
||||||
#include "globals.hh"
|
|
||||||
|
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
@ -54,11 +53,17 @@ public:
|
||||||
/* How long negative lookups are valid. */
|
/* How long negative lookups are valid. */
|
||||||
const int ttlNegative = 3600;
|
const int ttlNegative = 3600;
|
||||||
|
|
||||||
|
struct Cache
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
Path storeDir;
|
||||||
|
};
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
SQLite db;
|
SQLite db;
|
||||||
SQLiteStmt insertCache, queryCache, insertNAR, queryNAR, insertNARExistence, queryNARExistence;
|
SQLiteStmt insertCache, queryCache, insertNAR, queryNAR, insertNARExistence, queryNARExistence;
|
||||||
std::map<std::string, int> caches;
|
std::map<std::string, Cache> caches;
|
||||||
};
|
};
|
||||||
|
|
||||||
Sync<State> _state;
|
Sync<State> _state;
|
||||||
|
@ -106,22 +111,22 @@ public:
|
||||||
"select exist, timestamp from NARExistence where cache = ? and storePath = ?");
|
"select exist, timestamp from NARExistence where cache = ? and storePath = ?");
|
||||||
}
|
}
|
||||||
|
|
||||||
int uriToInt(State & state, const std::string & uri)
|
Cache & getCache(State & state, const std::string & uri)
|
||||||
{
|
{
|
||||||
auto i = state.caches.find(uri);
|
auto i = state.caches.find(uri);
|
||||||
if (i == state.caches.end()) abort();
|
if (i == state.caches.end()) abort();
|
||||||
return i->second;
|
return i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void createCache(const std::string & uri, bool wantMassQuery, int priority) override
|
void createCache(const std::string & uri, const Path & storeDir, bool wantMassQuery, int priority) override
|
||||||
{
|
{
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
|
|
||||||
// FIXME: race
|
// FIXME: race
|
||||||
|
|
||||||
state->insertCache.use()(uri)(time(0))(settings.nixStore)(wantMassQuery)(priority).exec();
|
state->insertCache.use()(uri)(time(0))(storeDir)(wantMassQuery)(priority).exec();
|
||||||
assert(sqlite3_changes(state->db) == 1);
|
assert(sqlite3_changes(state->db) == 1);
|
||||||
state->caches[uri] = sqlite3_last_insert_rowid(state->db);
|
state->caches[uri] = Cache{(int) sqlite3_last_insert_rowid(state->db), storeDir};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cacheExists(const std::string & uri) override
|
bool cacheExists(const std::string & uri) override
|
||||||
|
@ -134,7 +139,7 @@ public:
|
||||||
auto queryCache(state->queryCache.use()(uri));
|
auto queryCache(state->queryCache.use()(uri));
|
||||||
|
|
||||||
if (queryCache.next()) {
|
if (queryCache.next()) {
|
||||||
state->caches[uri] = queryCache.getInt(0);
|
state->caches[uri] = Cache{(int) queryCache.getInt(0), queryCache.getStr(1)};
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,9 +151,9 @@ public:
|
||||||
{
|
{
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
|
|
||||||
auto queryNAR(state->queryNAR.use()
|
auto & cache(getCache(*state, uri));
|
||||||
(uriToInt(*state, uri))
|
|
||||||
(hashPart));
|
auto queryNAR(state->queryNAR.use()(cache.id)(hashPart));
|
||||||
|
|
||||||
if (!queryNAR.next())
|
if (!queryNAR.next())
|
||||||
// FIXME: check NARExistence
|
// FIXME: check NARExistence
|
||||||
|
@ -159,7 +164,7 @@ public:
|
||||||
// FIXME: implement TTL.
|
// FIXME: implement TTL.
|
||||||
|
|
||||||
auto namePart = queryNAR.getStr(2);
|
auto namePart = queryNAR.getStr(2);
|
||||||
narInfo->path = settings.nixStore + "/" +
|
narInfo->path = cache.storeDir + "/" +
|
||||||
hashPart + (namePart.empty() ? "" : "-" + namePart);
|
hashPart + (namePart.empty() ? "" : "-" + namePart);
|
||||||
narInfo->url = queryNAR.getStr(3);
|
narInfo->url = queryNAR.getStr(3);
|
||||||
narInfo->compression = queryNAR.getStr(4);
|
narInfo->compression = queryNAR.getStr(4);
|
||||||
|
@ -169,9 +174,9 @@ public:
|
||||||
narInfo->narHash = parseHash(queryNAR.getStr(7));
|
narInfo->narHash = parseHash(queryNAR.getStr(7));
|
||||||
narInfo->narSize = queryNAR.getInt(8);
|
narInfo->narSize = queryNAR.getInt(8);
|
||||||
for (auto & r : tokenizeString<Strings>(queryNAR.getStr(9), " "))
|
for (auto & r : tokenizeString<Strings>(queryNAR.getStr(9), " "))
|
||||||
narInfo->references.insert(settings.nixStore + "/" + r);
|
narInfo->references.insert(cache.storeDir + "/" + r);
|
||||||
if (!queryNAR.isNull(10))
|
if (!queryNAR.isNull(10))
|
||||||
narInfo->deriver = settings.nixStore + "/" + queryNAR.getStr(10);
|
narInfo->deriver = cache.storeDir + "/" + queryNAR.getStr(10);
|
||||||
for (auto & sig : tokenizeString<Strings>(queryNAR.getStr(11), " "))
|
for (auto & sig : tokenizeString<Strings>(queryNAR.getStr(11), " "))
|
||||||
narInfo->sigs.insert(sig);
|
narInfo->sigs.insert(sig);
|
||||||
|
|
||||||
|
@ -184,6 +189,8 @@ public:
|
||||||
{
|
{
|
||||||
auto state(_state.lock());
|
auto state(_state.lock());
|
||||||
|
|
||||||
|
auto & cache(getCache(*state, uri));
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
|
|
||||||
auto narInfo = std::dynamic_pointer_cast<NarInfo>(info);
|
auto narInfo = std::dynamic_pointer_cast<NarInfo>(info);
|
||||||
|
@ -191,7 +198,7 @@ public:
|
||||||
assert(hashPart == storePathToHash(info->path));
|
assert(hashPart == storePathToHash(info->path));
|
||||||
|
|
||||||
state->insertNAR.use()
|
state->insertNAR.use()
|
||||||
(uriToInt(*state, uri))
|
(cache.id)
|
||||||
(hashPart)
|
(hashPart)
|
||||||
(storePathToName(info->path))
|
(storePathToName(info->path))
|
||||||
(narInfo ? narInfo->url : "", narInfo != 0)
|
(narInfo ? narInfo->url : "", narInfo != 0)
|
||||||
|
|
|
@ -10,7 +10,8 @@ class NarInfoDiskCache
|
||||||
public:
|
public:
|
||||||
typedef enum { oValid, oInvalid, oUnknown } Outcome;
|
typedef enum { oValid, oInvalid, oUnknown } Outcome;
|
||||||
|
|
||||||
virtual void createCache(const std::string & uri, bool wantMassQuery, int priority) = 0;
|
virtual void createCache(const std::string & uri, const Path & storeDir,
|
||||||
|
bool wantMassQuery, int priority) = 0;
|
||||||
|
|
||||||
virtual bool cacheExists(const std::string & uri) = 0;
|
virtual bool cacheExists(const std::string & uri) = 0;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
NarInfo::NarInfo(const std::string & s, const std::string & whence)
|
NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence)
|
||||||
{
|
{
|
||||||
auto corrupt = [&]() {
|
auto corrupt = [&]() {
|
||||||
throw Error("NAR info file ‘%1%’ is corrupt");
|
throw Error("NAR info file ‘%1%’ is corrupt");
|
||||||
|
@ -32,7 +32,7 @@ NarInfo::NarInfo(const std::string & s, const std::string & whence)
|
||||||
std::string value(s, colon + 2, eol - colon - 2);
|
std::string value(s, colon + 2, eol - colon - 2);
|
||||||
|
|
||||||
if (name == "StorePath") {
|
if (name == "StorePath") {
|
||||||
if (!isStorePath(value)) corrupt();
|
if (!store.isStorePath(value)) corrupt();
|
||||||
path = value;
|
path = value;
|
||||||
}
|
}
|
||||||
else if (name == "URL")
|
else if (name == "URL")
|
||||||
|
@ -53,14 +53,14 @@ NarInfo::NarInfo(const std::string & s, const std::string & whence)
|
||||||
auto refs = tokenizeString<Strings>(value, " ");
|
auto refs = tokenizeString<Strings>(value, " ");
|
||||||
if (!references.empty()) corrupt();
|
if (!references.empty()) corrupt();
|
||||||
for (auto & r : refs) {
|
for (auto & r : refs) {
|
||||||
auto r2 = settings.nixStore + "/" + r;
|
auto r2 = store.storeDir + "/" + r;
|
||||||
if (!isStorePath(r2)) corrupt();
|
if (!store.isStorePath(r2)) corrupt();
|
||||||
references.insert(r2);
|
references.insert(r2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (name == "Deriver") {
|
else if (name == "Deriver") {
|
||||||
auto p = settings.nixStore + "/" + value;
|
auto p = store.storeDir + "/" + value;
|
||||||
if (!isStorePath(p)) corrupt();
|
if (!store.isStorePath(p)) corrupt();
|
||||||
deriver = p;
|
deriver = p;
|
||||||
}
|
}
|
||||||
else if (name == "System")
|
else if (name == "System")
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct NarInfo : ValidPathInfo
|
||||||
|
|
||||||
NarInfo() { }
|
NarInfo() { }
|
||||||
NarInfo(const ValidPathInfo & info) : ValidPathInfo(info) { }
|
NarInfo(const ValidPathInfo & info) : ValidPathInfo(info) { }
|
||||||
NarInfo(const std::string & s, const std::string & whence);
|
NarInfo(const Store & store, const std::string & s, const std::string & whence);
|
||||||
|
|
||||||
std::string to_string() const;
|
std::string to_string() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -184,7 +184,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
||||||
MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : "");
|
MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : "");
|
||||||
|
|
||||||
Path tempLink = (format("%1%/.tmp-link-%2%-%3%")
|
Path tempLink = (format("%1%/.tmp-link-%2%-%3%")
|
||||||
% settings.nixStore % getpid() % rand()).str();
|
% storeDir % getpid() % rand()).str();
|
||||||
|
|
||||||
if (link(linkPath.c_str(), tempLink.c_str()) == -1) {
|
if (link(linkPath.c_str(), tempLink.c_str()) == -1) {
|
||||||
if (errno == EMLINK) {
|
if (errno == EMLINK) {
|
||||||
|
|
|
@ -21,26 +21,27 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
Path readStorePath(Source & from)
|
Path readStorePath(Store & store, Source & from)
|
||||||
{
|
{
|
||||||
Path path = readString(from);
|
Path path = readString(from);
|
||||||
assertStorePath(path);
|
store.assertStorePath(path);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class T> T readStorePaths(Source & from)
|
template<class T> T readStorePaths(Store & store, Source & from)
|
||||||
{
|
{
|
||||||
T paths = readStrings<T>(from);
|
T paths = readStrings<T>(from);
|
||||||
for (auto & i : paths) assertStorePath(i);
|
for (auto & i : paths) store.assertStorePath(i);
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
template PathSet readStorePaths(Source & from);
|
template PathSet readStorePaths(Store & store, Source & from);
|
||||||
|
|
||||||
|
|
||||||
RemoteStore::RemoteStore(size_t maxConnections)
|
RemoteStore::RemoteStore(const Params & params, size_t maxConnections)
|
||||||
: connections(make_ref<Pool<Connection>>(
|
: LocalFSStore(params)
|
||||||
|
, connections(make_ref<Pool<Connection>>(
|
||||||
maxConnections,
|
maxConnections,
|
||||||
[this]() { return openConnection(); },
|
[this]() { return openConnection(); },
|
||||||
[](const ref<Connection> & r) { return r->to.good() && r->from.good(); }
|
[](const ref<Connection> & r) { return r->to.good() && r->from.good(); }
|
||||||
|
@ -168,7 +169,7 @@ PathSet RemoteStore::queryValidPaths(const PathSet & paths)
|
||||||
} else {
|
} else {
|
||||||
conn->to << wopQueryValidPaths << paths;
|
conn->to << wopQueryValidPaths << paths;
|
||||||
conn->processStderr();
|
conn->processStderr();
|
||||||
return readStorePaths<PathSet>(conn->from);
|
return readStorePaths<PathSet>(*this, conn->from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +179,7 @@ PathSet RemoteStore::queryAllValidPaths()
|
||||||
auto conn(connections->get());
|
auto conn(connections->get());
|
||||||
conn->to << wopQueryAllValidPaths;
|
conn->to << wopQueryAllValidPaths;
|
||||||
conn->processStderr();
|
conn->processStderr();
|
||||||
return readStorePaths<PathSet>(conn->from);
|
return readStorePaths<PathSet>(*this, conn->from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -196,7 +197,7 @@ PathSet RemoteStore::querySubstitutablePaths(const PathSet & paths)
|
||||||
} else {
|
} else {
|
||||||
conn->to << wopQuerySubstitutablePaths << paths;
|
conn->to << wopQuerySubstitutablePaths << paths;
|
||||||
conn->processStderr();
|
conn->processStderr();
|
||||||
return readStorePaths<PathSet>(conn->from);
|
return readStorePaths<PathSet>(*this, conn->from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +221,7 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths,
|
||||||
if (reply == 0) continue;
|
if (reply == 0) continue;
|
||||||
info.deriver = readString(conn->from);
|
info.deriver = readString(conn->from);
|
||||||
if (info.deriver != "") assertStorePath(info.deriver);
|
if (info.deriver != "") assertStorePath(info.deriver);
|
||||||
info.references = readStorePaths<PathSet>(conn->from);
|
info.references = readStorePaths<PathSet>(*this, conn->from);
|
||||||
info.downloadSize = readLongLong(conn->from);
|
info.downloadSize = readLongLong(conn->from);
|
||||||
info.narSize = GET_PROTOCOL_MINOR(conn->daemonVersion) >= 7 ? readLongLong(conn->from) : 0;
|
info.narSize = GET_PROTOCOL_MINOR(conn->daemonVersion) >= 7 ? readLongLong(conn->from) : 0;
|
||||||
infos[i] = info;
|
infos[i] = info;
|
||||||
|
@ -232,11 +233,11 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths,
|
||||||
conn->processStderr();
|
conn->processStderr();
|
||||||
unsigned int count = readInt(conn->from);
|
unsigned int count = readInt(conn->from);
|
||||||
for (unsigned int n = 0; n < count; n++) {
|
for (unsigned int n = 0; n < count; n++) {
|
||||||
Path path = readStorePath(conn->from);
|
Path path = readStorePath(*this, conn->from);
|
||||||
SubstitutablePathInfo & info(infos[path]);
|
SubstitutablePathInfo & info(infos[path]);
|
||||||
info.deriver = readString(conn->from);
|
info.deriver = readString(conn->from);
|
||||||
if (info.deriver != "") assertStorePath(info.deriver);
|
if (info.deriver != "") assertStorePath(info.deriver);
|
||||||
info.references = readStorePaths<PathSet>(conn->from);
|
info.references = readStorePaths<PathSet>(*this, conn->from);
|
||||||
info.downloadSize = readLongLong(conn->from);
|
info.downloadSize = readLongLong(conn->from);
|
||||||
info.narSize = readLongLong(conn->from);
|
info.narSize = readLongLong(conn->from);
|
||||||
}
|
}
|
||||||
|
@ -266,7 +267,7 @@ std::shared_ptr<ValidPathInfo> RemoteStore::queryPathInfoUncached(const Path & p
|
||||||
info->deriver = readString(conn->from);
|
info->deriver = readString(conn->from);
|
||||||
if (info->deriver != "") assertStorePath(info->deriver);
|
if (info->deriver != "") assertStorePath(info->deriver);
|
||||||
info->narHash = parseHash(htSHA256, readString(conn->from));
|
info->narHash = parseHash(htSHA256, readString(conn->from));
|
||||||
info->references = readStorePaths<PathSet>(conn->from);
|
info->references = readStorePaths<PathSet>(*this, conn->from);
|
||||||
info->registrationTime = readInt(conn->from);
|
info->registrationTime = readInt(conn->from);
|
||||||
info->narSize = readLongLong(conn->from);
|
info->narSize = readLongLong(conn->from);
|
||||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 16) {
|
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 16) {
|
||||||
|
@ -283,7 +284,7 @@ void RemoteStore::queryReferrers(const Path & path,
|
||||||
auto conn(connections->get());
|
auto conn(connections->get());
|
||||||
conn->to << wopQueryReferrers << path;
|
conn->to << wopQueryReferrers << path;
|
||||||
conn->processStderr();
|
conn->processStderr();
|
||||||
PathSet referrers2 = readStorePaths<PathSet>(conn->from);
|
PathSet referrers2 = readStorePaths<PathSet>(*this, conn->from);
|
||||||
referrers.insert(referrers2.begin(), referrers2.end());
|
referrers.insert(referrers2.begin(), referrers2.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +294,7 @@ PathSet RemoteStore::queryValidDerivers(const Path & path)
|
||||||
auto conn(connections->get());
|
auto conn(connections->get());
|
||||||
conn->to << wopQueryValidDerivers << path;
|
conn->to << wopQueryValidDerivers << path;
|
||||||
conn->processStderr();
|
conn->processStderr();
|
||||||
return readStorePaths<PathSet>(conn->from);
|
return readStorePaths<PathSet>(*this, conn->from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -302,7 +303,7 @@ PathSet RemoteStore::queryDerivationOutputs(const Path & path)
|
||||||
auto conn(connections->get());
|
auto conn(connections->get());
|
||||||
conn->to << wopQueryDerivationOutputs << path;
|
conn->to << wopQueryDerivationOutputs << path;
|
||||||
conn->processStderr();
|
conn->processStderr();
|
||||||
return readStorePaths<PathSet>(conn->from);
|
return readStorePaths<PathSet>(*this, conn->from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -363,7 +364,7 @@ Path RemoteStore::addToStore(const string & name, const Path & _srcPath,
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return readStorePath(conn->from);
|
return readStorePath(*this, conn->from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -376,7 +377,7 @@ Path RemoteStore::addTextToStore(const string & name, const string & s,
|
||||||
conn->to << wopAddTextToStore << name << s << references;
|
conn->to << wopAddTextToStore << name << s << references;
|
||||||
|
|
||||||
conn->processStderr();
|
conn->processStderr();
|
||||||
return readStorePath(conn->from);
|
return readStorePath(*this, conn->from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -465,7 +466,7 @@ Roots RemoteStore::findRoots()
|
||||||
Roots result;
|
Roots result;
|
||||||
while (count--) {
|
while (count--) {
|
||||||
Path link = readString(conn->from);
|
Path link = readString(conn->from);
|
||||||
Path target = readStorePath(conn->from);
|
Path target = readStorePath(*this, conn->from);
|
||||||
result[link] = target;
|
result[link] = target;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -22,7 +22,7 @@ class RemoteStore : public LocalFSStore
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RemoteStore(size_t maxConnections = std::numeric_limits<size_t>::max());
|
RemoteStore(const Params & params, size_t maxConnections = std::numeric_limits<size_t>::max());
|
||||||
|
|
||||||
/* Implementations of abstract store API methods. */
|
/* Implementations of abstract store API methods. */
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
Stats stats;
|
Stats stats;
|
||||||
|
|
||||||
S3BinaryCacheStoreImpl(
|
S3BinaryCacheStoreImpl(
|
||||||
const StoreParams & params, const std::string & bucketName)
|
const Params & params, const std::string & bucketName)
|
||||||
: S3BinaryCacheStore(params)
|
: S3BinaryCacheStore(params)
|
||||||
, bucketName(bucketName)
|
, bucketName(bucketName)
|
||||||
, config(makeConfig())
|
, config(makeConfig())
|
||||||
|
@ -95,7 +95,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
|
|
||||||
BinaryCacheStore::init();
|
BinaryCacheStore::init();
|
||||||
|
|
||||||
diskCache->createCache(getUri(), wantMassQuery_, priority);
|
diskCache->createCache(getUri(), storeDir, wantMassQuery_, priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
for (auto object : contents) {
|
for (auto object : contents) {
|
||||||
auto & key = object.GetKey();
|
auto & key = object.GetKey();
|
||||||
if (key.size() != 40 || !hasSuffix(key, ".narinfo")) continue;
|
if (key.size() != 40 || !hasSuffix(key, ".narinfo")) continue;
|
||||||
paths.insert(settings.nixStore + "/" + key.substr(0, key.size() - 8));
|
paths.insert(storeDir + "/" + key.substr(0, key.size() - 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
marker = res.GetNextMarker();
|
marker = res.GetNextMarker();
|
||||||
|
@ -244,7 +244,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
||||||
};
|
};
|
||||||
|
|
||||||
static RegisterStoreImplementation regStore([](
|
static RegisterStoreImplementation regStore([](
|
||||||
const std::string & uri, const StoreParams & params)
|
const std::string & uri, const Store::Params & params)
|
||||||
-> std::shared_ptr<Store>
|
-> std::shared_ptr<Store>
|
||||||
{
|
{
|
||||||
if (std::string(uri, 0, 5) != "s3://") return 0;
|
if (std::string(uri, 0, 5) != "s3://") return 0;
|
||||||
|
|
|
@ -10,7 +10,7 @@ class S3BinaryCacheStore : public BinaryCacheStore
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
S3BinaryCacheStore(const StoreParams & params)
|
S3BinaryCacheStore(const Params & params)
|
||||||
: BinaryCacheStore(params)
|
: BinaryCacheStore(params)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
|
@ -8,32 +8,32 @@
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
bool isInStore(const Path & path)
|
bool Store::isInStore(const Path & path) const
|
||||||
{
|
{
|
||||||
return isInDir(path, settings.nixStore);
|
return isInDir(path, storeDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool isStorePath(const Path & path)
|
bool Store::isStorePath(const Path & path) const
|
||||||
{
|
{
|
||||||
return isInStore(path)
|
return isInStore(path)
|
||||||
&& path.size() >= settings.nixStore.size() + 1 + storePathHashLen
|
&& path.size() >= storeDir.size() + 1 + storePathHashLen
|
||||||
&& path.find('/', settings.nixStore.size() + 1) == Path::npos;
|
&& path.find('/', storeDir.size() + 1) == Path::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void assertStorePath(const Path & path)
|
void Store::assertStorePath(const Path & path) const
|
||||||
{
|
{
|
||||||
if (!isStorePath(path))
|
if (!isStorePath(path))
|
||||||
throw Error(format("path ‘%1%’ is not in the Nix store") % path);
|
throw Error(format("path ‘%1%’ is not in the Nix store") % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path toStorePath(const Path & path)
|
Path Store::toStorePath(const Path & path) const
|
||||||
{
|
{
|
||||||
if (!isInStore(path))
|
if (!isInStore(path))
|
||||||
throw Error(format("path ‘%1%’ is not in the Nix store") % path);
|
throw Error(format("path ‘%1%’ is not in the Nix store") % path);
|
||||||
Path::size_type slash = path.find('/', settings.nixStore.size() + 1);
|
Path::size_type slash = path.find('/', storeDir.size() + 1);
|
||||||
if (slash == Path::npos)
|
if (slash == Path::npos)
|
||||||
return path;
|
return path;
|
||||||
else
|
else
|
||||||
|
@ -41,7 +41,7 @@ Path toStorePath(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path followLinksToStore(const Path & _path)
|
Path Store::followLinksToStore(const Path & _path) const
|
||||||
{
|
{
|
||||||
Path path = absPath(_path);
|
Path path = absPath(_path);
|
||||||
while (!isInStore(path)) {
|
while (!isInStore(path)) {
|
||||||
|
@ -55,7 +55,7 @@ Path followLinksToStore(const Path & _path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path followLinksToStorePath(const Path & path)
|
Path Store::followLinksToStorePath(const Path & path) const
|
||||||
{
|
{
|
||||||
return toStorePath(followLinksToStore(path));
|
return toStorePath(followLinksToStore(path));
|
||||||
}
|
}
|
||||||
|
@ -63,18 +63,17 @@ Path followLinksToStorePath(const Path & path)
|
||||||
|
|
||||||
string storePathToName(const Path & path)
|
string storePathToName(const Path & path)
|
||||||
{
|
{
|
||||||
assertStorePath(path);
|
auto base = baseNameOf(path);
|
||||||
auto l = settings.nixStore.size() + 1 + storePathHashLen;
|
assert(base.size() == storePathHashLen || (base.size() > storePathHashLen && base[storePathHashLen] == '-'));
|
||||||
assert(path.size() >= l);
|
return base.size() == storePathHashLen ? "" : string(base, storePathHashLen + 1);
|
||||||
return path.size() == l ? "" : string(path, l + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string storePathToHash(const Path & path)
|
string storePathToHash(const Path & path)
|
||||||
{
|
{
|
||||||
assertStorePath(path);
|
auto base = baseNameOf(path);
|
||||||
assert(path.size() >= settings.nixStore.size() + 1 + storePathHashLen);
|
assert(base.size() >= storePathHashLen);
|
||||||
return string(path, settings.nixStore.size() + 1, storePathHashLen);
|
return string(base, 0, storePathHashLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,31 +167,31 @@ void checkStoreName(const string & name)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
Path makeStorePath(const string & type,
|
Path Store::makeStorePath(const string & type,
|
||||||
const Hash & hash, const string & name)
|
const Hash & hash, const string & name) const
|
||||||
{
|
{
|
||||||
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
|
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
|
||||||
string s = type + ":sha256:" + printHash(hash) + ":"
|
string s = type + ":sha256:" + printHash(hash) + ":"
|
||||||
+ settings.nixStore + ":" + name;
|
+ storeDir + ":" + name;
|
||||||
|
|
||||||
checkStoreName(name);
|
checkStoreName(name);
|
||||||
|
|
||||||
return settings.nixStore + "/"
|
return storeDir + "/"
|
||||||
+ printHash32(compressHash(hashString(htSHA256, s), 20))
|
+ printHash32(compressHash(hashString(htSHA256, s), 20))
|
||||||
+ "-" + name;
|
+ "-" + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path makeOutputPath(const string & id,
|
Path Store::makeOutputPath(const string & id,
|
||||||
const Hash & hash, const string & name)
|
const Hash & hash, const string & name) const
|
||||||
{
|
{
|
||||||
return makeStorePath("output:" + id, hash,
|
return makeStorePath("output:" + id, hash,
|
||||||
name + (id == "out" ? "" : "-" + id));
|
name + (id == "out" ? "" : "-" + id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path makeFixedOutputPath(bool recursive,
|
Path Store::makeFixedOutputPath(bool recursive,
|
||||||
HashType hashAlgo, Hash hash, string name)
|
HashType hashAlgo, Hash hash, string name) const
|
||||||
{
|
{
|
||||||
return hashAlgo == htSHA256 && recursive
|
return hashAlgo == htSHA256 && recursive
|
||||||
? makeStorePath("source", hash, name)
|
? makeStorePath("source", hash, name)
|
||||||
|
@ -203,8 +202,8 @@ Path makeFixedOutputPath(bool recursive,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
|
std::pair<Path, Hash> Store::computeStorePathForPath(const Path & srcPath,
|
||||||
bool recursive, HashType hashAlgo, PathFilter & filter)
|
bool recursive, HashType hashAlgo, PathFilter & filter) const
|
||||||
{
|
{
|
||||||
HashType ht(hashAlgo);
|
HashType ht(hashAlgo);
|
||||||
Hash h = recursive ? hashPath(ht, srcPath, filter).first : hashFile(ht, srcPath);
|
Hash h = recursive ? hashPath(ht, srcPath, filter).first : hashFile(ht, srcPath);
|
||||||
|
@ -214,8 +213,8 @@ std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path computeStorePathForText(const string & name, const string & s,
|
Path Store::computeStorePathForText(const string & name, const string & s,
|
||||||
const PathSet & references)
|
const PathSet & references) const
|
||||||
{
|
{
|
||||||
Hash hash = hashString(htSHA256, s);
|
Hash hash = hashString(htSHA256, s);
|
||||||
/* Stuff the references (if any) into the type. This is a bit
|
/* Stuff the references (if any) into the type. This is a bit
|
||||||
|
@ -230,6 +229,12 @@ Path computeStorePathForText(const string & name, const string & s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Store::Store(const Params & params)
|
||||||
|
: storeDir(settings.nixStore)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string Store::getUri()
|
std::string Store::getUri()
|
||||||
{
|
{
|
||||||
return "";
|
return "";
|
||||||
|
@ -465,7 +470,7 @@ RegisterStoreImplementation::Implementations * RegisterStoreImplementation::impl
|
||||||
ref<Store> openStoreAt(const std::string & uri_)
|
ref<Store> openStoreAt(const std::string & uri_)
|
||||||
{
|
{
|
||||||
auto uri(uri_);
|
auto uri(uri_);
|
||||||
StoreParams params;
|
Store::Params params;
|
||||||
auto q = uri.find('?');
|
auto q = uri.find('?');
|
||||||
if (q != std::string::npos) {
|
if (q != std::string::npos) {
|
||||||
for (auto s : tokenizeString<Strings>(uri.substr(q + 1), "&")) {
|
for (auto s : tokenizeString<Strings>(uri.substr(q + 1), "&")) {
|
||||||
|
@ -492,7 +497,7 @@ ref<Store> openStore()
|
||||||
|
|
||||||
|
|
||||||
static RegisterStoreImplementation regStore([](
|
static RegisterStoreImplementation regStore([](
|
||||||
const std::string & uri, const StoreParams & params)
|
const std::string & uri, const Store::Params & params)
|
||||||
-> std::shared_ptr<Store>
|
-> std::shared_ptr<Store>
|
||||||
{
|
{
|
||||||
enum { mDaemon, mLocal, mAuto } mode;
|
enum { mDaemon, mLocal, mAuto } mode;
|
||||||
|
@ -512,8 +517,8 @@ static RegisterStoreImplementation regStore([](
|
||||||
}
|
}
|
||||||
|
|
||||||
return mode == mDaemon
|
return mode == mDaemon
|
||||||
? std::shared_ptr<Store>(std::make_shared<RemoteStore>())
|
? std::shared_ptr<Store>(std::make_shared<RemoteStore>(params))
|
||||||
: std::shared_ptr<Store>(std::make_shared<LocalStore>());
|
: std::shared_ptr<Store>(std::make_shared<LocalStore>(params));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,12 @@ class NarInfoDiskCache;
|
||||||
|
|
||||||
class Store : public std::enable_shared_from_this<Store>
|
class Store : public std::enable_shared_from_this<Store>
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef std::map<std::string, std::string> Params;
|
||||||
|
|
||||||
|
const Path storeDir;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
|
@ -188,12 +194,71 @@ protected:
|
||||||
|
|
||||||
std::shared_ptr<NarInfoDiskCache> diskCache;
|
std::shared_ptr<NarInfoDiskCache> diskCache;
|
||||||
|
|
||||||
|
Store(const Params & params);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~Store() { }
|
virtual ~Store() { }
|
||||||
|
|
||||||
virtual std::string getUri() = 0;
|
virtual std::string getUri() = 0;
|
||||||
|
|
||||||
|
/* Return true if ‘path’ is in the Nix store (but not the Nix
|
||||||
|
store itself). */
|
||||||
|
bool isInStore(const Path & path) const;
|
||||||
|
|
||||||
|
/* Return true if ‘path’ is a store path, i.e. a direct child of
|
||||||
|
the Nix store. */
|
||||||
|
bool isStorePath(const Path & path) const;
|
||||||
|
|
||||||
|
/* Throw an exception if ‘path’ is not a store path. */
|
||||||
|
void assertStorePath(const Path & path) const;
|
||||||
|
|
||||||
|
/* Chop off the parts after the top-level store name, e.g.,
|
||||||
|
/nix/store/abcd-foo/bar => /nix/store/abcd-foo. */
|
||||||
|
Path toStorePath(const Path & path) const;
|
||||||
|
|
||||||
|
/* Follow symlinks until we end up with a path in the Nix store. */
|
||||||
|
Path followLinksToStore(const Path & path) const;
|
||||||
|
|
||||||
|
/* Same as followLinksToStore(), but apply toStorePath() to the
|
||||||
|
result. */
|
||||||
|
Path followLinksToStorePath(const Path & path) const;
|
||||||
|
|
||||||
|
/* Constructs a unique store path name. */
|
||||||
|
Path makeStorePath(const string & type,
|
||||||
|
const Hash & hash, const string & name) const;
|
||||||
|
|
||||||
|
Path makeOutputPath(const string & id,
|
||||||
|
const Hash & hash, const string & name) const;
|
||||||
|
|
||||||
|
Path makeFixedOutputPath(bool recursive,
|
||||||
|
HashType hashAlgo, Hash hash, string name) const;
|
||||||
|
|
||||||
|
/* This is the preparatory part of addToStore() and
|
||||||
|
addToStoreFixed(); it computes the store path to which srcPath
|
||||||
|
is to be copied. Returns the store path and the cryptographic
|
||||||
|
hash of the contents of srcPath. */
|
||||||
|
std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
|
||||||
|
bool recursive = true, HashType hashAlgo = htSHA256,
|
||||||
|
PathFilter & filter = defaultPathFilter) const;
|
||||||
|
|
||||||
|
/* Preparatory part of addTextToStore().
|
||||||
|
|
||||||
|
!!! Computation of the path should take the references given to
|
||||||
|
addTextToStore() into account, otherwise we have a (relatively
|
||||||
|
minor) security hole: a caller can register a source file with
|
||||||
|
bogus references. If there are too many references, the path may
|
||||||
|
not be garbage collected when it has to be (not really a problem,
|
||||||
|
the caller could create a root anyway), or it may be garbage
|
||||||
|
collected when it shouldn't be (more serious).
|
||||||
|
|
||||||
|
Hashing the references would solve this (bogus references would
|
||||||
|
simply yield a different store path, so other users wouldn't be
|
||||||
|
affected), but it has some backwards compatibility issues (the
|
||||||
|
hashing scheme changes), so I'm not doing that for now. */
|
||||||
|
Path computeStorePathForText(const string & name, const string & s,
|
||||||
|
const PathSet & references) const;
|
||||||
|
|
||||||
/* Check whether a path is valid. */
|
/* Check whether a path is valid. */
|
||||||
bool isValidPath(const Path & path);
|
bool isValidPath(const Path & path);
|
||||||
|
|
||||||
|
@ -429,80 +494,26 @@ protected:
|
||||||
|
|
||||||
class LocalFSStore : public Store
|
class LocalFSStore : public Store
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
using Store::Store;
|
||||||
public:
|
public:
|
||||||
void narFromPath(const Path & path, Sink & sink) override;
|
void narFromPath(const Path & path, Sink & sink) override;
|
||||||
ref<FSAccessor> getFSAccessor() override;
|
ref<FSAccessor> getFSAccessor() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* !!! These should be part of the store API, I guess. */
|
|
||||||
|
|
||||||
/* Throw an exception if `path' is not directly in the Nix store. */
|
|
||||||
void assertStorePath(const Path & path);
|
|
||||||
|
|
||||||
bool isInStore(const Path & path);
|
|
||||||
bool isStorePath(const Path & path);
|
|
||||||
|
|
||||||
/* Extract the name part of the given store path. */
|
/* Extract the name part of the given store path. */
|
||||||
string storePathToName(const Path & path);
|
string storePathToName(const Path & path);
|
||||||
|
|
||||||
/* Extract the hash part of the given store path. */
|
/* Extract the hash part of the given store path. */
|
||||||
string storePathToHash(const Path & path);
|
string storePathToHash(const Path & path);
|
||||||
|
|
||||||
|
/* Check whether ‘name’ is a valid store path name part, i.e. contains
|
||||||
|
only the characters [a-zA-Z0-9\+\-\.\_\?\=] and doesn't start with
|
||||||
|
a dot. */
|
||||||
void checkStoreName(const string & name);
|
void checkStoreName(const string & name);
|
||||||
|
|
||||||
|
|
||||||
/* Chop off the parts after the top-level store name, e.g.,
|
|
||||||
/nix/store/abcd-foo/bar => /nix/store/abcd-foo. */
|
|
||||||
Path toStorePath(const Path & path);
|
|
||||||
|
|
||||||
|
|
||||||
/* Follow symlinks until we end up with a path in the Nix store. */
|
|
||||||
Path followLinksToStore(const Path & path);
|
|
||||||
|
|
||||||
|
|
||||||
/* Same as followLinksToStore(), but apply toStorePath() to the
|
|
||||||
result. */
|
|
||||||
Path followLinksToStorePath(const Path & path);
|
|
||||||
|
|
||||||
|
|
||||||
/* Constructs a unique store path name. */
|
|
||||||
Path makeStorePath(const string & type,
|
|
||||||
const Hash & hash, const string & name);
|
|
||||||
|
|
||||||
Path makeOutputPath(const string & id,
|
|
||||||
const Hash & hash, const string & name);
|
|
||||||
|
|
||||||
Path makeFixedOutputPath(bool recursive,
|
|
||||||
HashType hashAlgo, Hash hash, string name);
|
|
||||||
|
|
||||||
|
|
||||||
/* This is the preparatory part of addToStore() and addToStoreFixed();
|
|
||||||
it computes the store path to which srcPath is to be copied.
|
|
||||||
Returns the store path and the cryptographic hash of the
|
|
||||||
contents of srcPath. */
|
|
||||||
std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
|
|
||||||
bool recursive = true, HashType hashAlgo = htSHA256,
|
|
||||||
PathFilter & filter = defaultPathFilter);
|
|
||||||
|
|
||||||
/* Preparatory part of addTextToStore().
|
|
||||||
|
|
||||||
!!! Computation of the path should take the references given to
|
|
||||||
addTextToStore() into account, otherwise we have a (relatively
|
|
||||||
minor) security hole: a caller can register a source file with
|
|
||||||
bogus references. If there are too many references, the path may
|
|
||||||
not be garbage collected when it has to be (not really a problem,
|
|
||||||
the caller could create a root anyway), or it may be garbage
|
|
||||||
collected when it shouldn't be (more serious).
|
|
||||||
|
|
||||||
Hashing the references would solve this (bogus references would
|
|
||||||
simply yield a different store path, so other users wouldn't be
|
|
||||||
affected), but it has some backwards compatibility issues (the
|
|
||||||
hashing scheme changes), so I'm not doing that for now. */
|
|
||||||
Path computeStorePathForText(const string & name, const string & s,
|
|
||||||
const PathSet & references);
|
|
||||||
|
|
||||||
|
|
||||||
/* Copy a path from one store to another. */
|
/* Copy a path from one store to another. */
|
||||||
void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
|
void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
|
||||||
const Path & storePath, bool repair = false);
|
const Path & storePath, bool repair = false);
|
||||||
|
@ -542,10 +553,8 @@ std::list<ref<Store>> getDefaultSubstituters();
|
||||||
|
|
||||||
|
|
||||||
/* Store implementation registration. */
|
/* Store implementation registration. */
|
||||||
typedef std::map<std::string, std::string> StoreParams;
|
|
||||||
|
|
||||||
typedef std::function<std::shared_ptr<Store>(
|
typedef std::function<std::shared_ptr<Store>(
|
||||||
const std::string & uri, const StoreParams & params)> OpenStore;
|
const std::string & uri, const Store::Params & params)> OpenStore;
|
||||||
|
|
||||||
struct RegisterStoreImplementation
|
struct RegisterStoreImplementation
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,8 +56,8 @@ typedef enum {
|
||||||
#define STDERR_ERROR 0x63787470
|
#define STDERR_ERROR 0x63787470
|
||||||
|
|
||||||
|
|
||||||
Path readStorePath(Source & from);
|
Path readStorePath(Store & store, Source & from);
|
||||||
template<class T> T readStorePaths(Source & from);
|
template<class T> T readStorePaths(Store & store, Source & from);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
connection. */
|
connection. */
|
||||||
Path path = readString(from);
|
Path path = readString(from);
|
||||||
startWork();
|
startWork();
|
||||||
assertStorePath(path);
|
store->assertStorePath(path);
|
||||||
bool result = store->isValidPath(path);
|
bool result = store->isValidPath(path);
|
||||||
stopWork();
|
stopWork();
|
||||||
to << result;
|
to << result;
|
||||||
|
@ -184,7 +184,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopQueryValidPaths: {
|
case wopQueryValidPaths: {
|
||||||
PathSet paths = readStorePaths<PathSet>(from);
|
PathSet paths = readStorePaths<PathSet>(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
PathSet res = store->queryValidPaths(paths);
|
PathSet res = store->queryValidPaths(paths);
|
||||||
stopWork();
|
stopWork();
|
||||||
|
@ -193,7 +193,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopHasSubstitutes: {
|
case wopHasSubstitutes: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
PathSet res = store->querySubstitutablePaths({path});
|
PathSet res = store->querySubstitutablePaths({path});
|
||||||
stopWork();
|
stopWork();
|
||||||
|
@ -202,7 +202,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopQuerySubstitutablePaths: {
|
case wopQuerySubstitutablePaths: {
|
||||||
PathSet paths = readStorePaths<PathSet>(from);
|
PathSet paths = readStorePaths<PathSet>(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
PathSet res = store->querySubstitutablePaths(paths);
|
PathSet res = store->querySubstitutablePaths(paths);
|
||||||
stopWork();
|
stopWork();
|
||||||
|
@ -211,7 +211,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopQueryPathHash: {
|
case wopQueryPathHash: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
auto hash = store->queryPathInfo(path)->narHash;
|
auto hash = store->queryPathInfo(path)->narHash;
|
||||||
stopWork();
|
stopWork();
|
||||||
|
@ -223,7 +223,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
case wopQueryReferrers:
|
case wopQueryReferrers:
|
||||||
case wopQueryValidDerivers:
|
case wopQueryValidDerivers:
|
||||||
case wopQueryDerivationOutputs: {
|
case wopQueryDerivationOutputs: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
PathSet paths;
|
PathSet paths;
|
||||||
if (op == wopQueryReferences)
|
if (op == wopQueryReferences)
|
||||||
|
@ -239,7 +239,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopQueryDerivationOutputNames: {
|
case wopQueryDerivationOutputNames: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
StringSet names;
|
StringSet names;
|
||||||
names = store->queryDerivationOutputNames(path);
|
names = store->queryDerivationOutputNames(path);
|
||||||
|
@ -249,7 +249,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopQueryDeriver: {
|
case wopQueryDeriver: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
auto deriver = store->queryPathInfo(path)->deriver;
|
auto deriver = store->queryPathInfo(path)->deriver;
|
||||||
stopWork();
|
stopWork();
|
||||||
|
@ -302,7 +302,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
case wopAddTextToStore: {
|
case wopAddTextToStore: {
|
||||||
string suffix = readString(from);
|
string suffix = readString(from);
|
||||||
string s = readString(from);
|
string s = readString(from);
|
||||||
PathSet refs = readStorePaths<PathSet>(from);
|
PathSet refs = readStorePaths<PathSet>(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
Path path = store->addTextToStore(suffix, s, refs);
|
Path path = store->addTextToStore(suffix, s, refs);
|
||||||
stopWork();
|
stopWork();
|
||||||
|
@ -311,7 +311,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopExportPath: {
|
case wopExportPath: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
readInt(from); // obsolete
|
readInt(from); // obsolete
|
||||||
startWork();
|
startWork();
|
||||||
TunnelSink sink(to);
|
TunnelSink sink(to);
|
||||||
|
@ -331,7 +331,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopBuildPaths: {
|
case wopBuildPaths: {
|
||||||
PathSet drvs = readStorePaths<PathSet>(from);
|
PathSet drvs = readStorePaths<PathSet>(*store, from);
|
||||||
BuildMode mode = bmNormal;
|
BuildMode mode = bmNormal;
|
||||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 15) {
|
if (GET_PROTOCOL_MINOR(clientVersion) >= 15) {
|
||||||
mode = (BuildMode)readInt(from);
|
mode = (BuildMode)readInt(from);
|
||||||
|
@ -349,9 +349,9 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopBuildDerivation: {
|
case wopBuildDerivation: {
|
||||||
Path drvPath = readStorePath(from);
|
Path drvPath = readStorePath(*store, from);
|
||||||
BasicDerivation drv;
|
BasicDerivation drv;
|
||||||
from >> drv;
|
readDerivation(from, *store, drv);
|
||||||
BuildMode buildMode = (BuildMode) readInt(from);
|
BuildMode buildMode = (BuildMode) readInt(from);
|
||||||
startWork();
|
startWork();
|
||||||
if (!trusted)
|
if (!trusted)
|
||||||
|
@ -363,7 +363,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopEnsurePath: {
|
case wopEnsurePath: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
store->ensurePath(path);
|
store->ensurePath(path);
|
||||||
stopWork();
|
stopWork();
|
||||||
|
@ -372,7 +372,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopAddTempRoot: {
|
case wopAddTempRoot: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
store->addTempRoot(path);
|
store->addTempRoot(path);
|
||||||
stopWork();
|
stopWork();
|
||||||
|
@ -410,7 +410,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
case wopCollectGarbage: {
|
case wopCollectGarbage: {
|
||||||
GCOptions options;
|
GCOptions options;
|
||||||
options.action = (GCOptions::GCAction) readInt(from);
|
options.action = (GCOptions::GCAction) readInt(from);
|
||||||
options.pathsToDelete = readStorePaths<PathSet>(from);
|
options.pathsToDelete = readStorePaths<PathSet>(*store, from);
|
||||||
options.ignoreLiveness = readInt(from);
|
options.ignoreLiveness = readInt(from);
|
||||||
options.maxFreed = readLongLong(from);
|
options.maxFreed = readLongLong(from);
|
||||||
readInt(from); // obsolete field
|
readInt(from); // obsolete field
|
||||||
|
@ -486,7 +486,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopQuerySubstitutablePathInfos: {
|
case wopQuerySubstitutablePathInfos: {
|
||||||
PathSet paths = readStorePaths<PathSet>(from);
|
PathSet paths = readStorePaths<PathSet>(*store, from);
|
||||||
startWork();
|
startWork();
|
||||||
SubstitutablePathInfos infos;
|
SubstitutablePathInfos infos;
|
||||||
store->querySubstitutablePathInfos(paths, infos);
|
store->querySubstitutablePathInfos(paths, infos);
|
||||||
|
@ -508,7 +508,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopQueryPathInfo: {
|
case wopQueryPathInfo: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
std::shared_ptr<const ValidPathInfo> info;
|
std::shared_ptr<const ValidPathInfo> info;
|
||||||
startWork();
|
startWork();
|
||||||
try {
|
try {
|
||||||
|
@ -553,7 +553,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
||||||
}
|
}
|
||||||
|
|
||||||
case wopAddSignatures: {
|
case wopAddSignatures: {
|
||||||
Path path = readStorePath(from);
|
Path path = readStorePath(*store, from);
|
||||||
StringSet sigs = readStrings<StringSet>(from);
|
StringSet sigs = readStrings<StringSet>(from);
|
||||||
startWork();
|
startWork();
|
||||||
if (!trusted)
|
if (!trusted)
|
||||||
|
@ -607,7 +607,7 @@ static void processConnection(bool trusted)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Open the store. */
|
/* Open the store. */
|
||||||
auto store = make_ref<LocalStore>();
|
auto store = make_ref<LocalStore>(Store::Params()); // FIXME: get params from somewhere
|
||||||
|
|
||||||
stopWork();
|
stopWork();
|
||||||
to.flush();
|
to.flush();
|
||||||
|
|
|
@ -387,7 +387,7 @@ static void queryInstSources(EvalState & state,
|
||||||
case srcStorePaths: {
|
case srcStorePaths: {
|
||||||
|
|
||||||
for (auto & i : args) {
|
for (auto & i : args) {
|
||||||
Path path = followLinksToStorePath(i);
|
Path path = state.store->followLinksToStorePath(i);
|
||||||
|
|
||||||
string name = baseNameOf(path);
|
string name = baseNameOf(path);
|
||||||
string::size_type dash = name.find('-');
|
string::size_type dash = name.find('-');
|
||||||
|
@ -742,7 +742,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
|
||||||
for (auto & j : selectors)
|
for (auto & j : selectors)
|
||||||
/* !!! the repeated calls to followLinksToStorePath()
|
/* !!! the repeated calls to followLinksToStorePath()
|
||||||
are expensive, should pre-compute them. */
|
are expensive, should pre-compute them. */
|
||||||
if ((isPath(j) && i.queryOutPath() == followLinksToStorePath(j))
|
if ((isPath(j) && i.queryOutPath() == globals.state->store->followLinksToStorePath(j))
|
||||||
|| DrvName(j).matches(drvName))
|
|| DrvName(j).matches(drvName))
|
||||||
{
|
{
|
||||||
printMsg(lvlInfo, format("uninstalling ‘%1%’") % i.name);
|
printMsg(lvlInfo, format("uninstalling ‘%1%’") % i.name);
|
||||||
|
|
|
@ -146,7 +146,7 @@ int main(int argc, char * * argv)
|
||||||
Path storePath;
|
Path storePath;
|
||||||
if (args.size() == 2) {
|
if (args.size() == 2) {
|
||||||
expectedHash = parseHash16or32(ht, args[1]);
|
expectedHash = parseHash16or32(ht, args[1]);
|
||||||
storePath = makeFixedOutputPath(unpack, ht, expectedHash, name);
|
storePath = store->makeFixedOutputPath(unpack, ht, expectedHash, name);
|
||||||
if (store->isValidPath(storePath))
|
if (store->isValidPath(storePath))
|
||||||
hash = expectedHash;
|
hash = expectedHash;
|
||||||
else
|
else
|
||||||
|
@ -197,7 +197,7 @@ int main(int argc, char * * argv)
|
||||||
into the Nix store. */
|
into the Nix store. */
|
||||||
storePath = store->addToStore(name, tmpFile, unpack, ht);
|
storePath = store->addToStore(name, tmpFile, unpack, ht);
|
||||||
|
|
||||||
assert(storePath == makeFixedOutputPath(unpack, ht, hash, name));
|
assert(storePath == store->makeFixedOutputPath(unpack, ht, hash, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!printPath)
|
if (!printPath)
|
||||||
|
|
|
@ -124,7 +124,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
|
||||||
Paths paths;
|
Paths paths;
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
DrvPathWithOutputs p = parseDrvPathWithOutputs(i);
|
DrvPathWithOutputs p = parseDrvPathWithOutputs(i);
|
||||||
paths.push_back(makeDrvPathWithOutputs(followLinksToStorePath(p.first), p.second));
|
paths.push_back(makeDrvPathWithOutputs(store->followLinksToStorePath(p.first), p.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long long downloadSize, narSize;
|
unsigned long long downloadSize, narSize;
|
||||||
|
@ -207,7 +207,7 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
|
||||||
string name = *i++;
|
string name = *i++;
|
||||||
|
|
||||||
cout << format("%1%\n") %
|
cout << format("%1%\n") %
|
||||||
makeFixedOutputPath(recursive, hashAlgo,
|
store->makeFixedOutputPath(recursive, hashAlgo,
|
||||||
parseHash16or32(hashAlgo, hash), name);
|
parseHash16or32(hashAlgo, hash), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
case qOutputs: {
|
case qOutputs: {
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
i = followLinksToStorePath(i);
|
i = store->followLinksToStorePath(i);
|
||||||
if (forceRealise) realisePath(i);
|
if (forceRealise) realisePath(i);
|
||||||
Derivation drv = store->derivationFromPath(i);
|
Derivation drv = store->derivationFromPath(i);
|
||||||
for (auto & j : drv.outputs)
|
for (auto & j : drv.outputs)
|
||||||
|
@ -330,7 +330,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
case qReferrersClosure: {
|
case qReferrersClosure: {
|
||||||
PathSet paths;
|
PathSet paths;
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
PathSet ps = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise);
|
PathSet ps = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise);
|
||||||
for (auto & j : ps) {
|
for (auto & j : ps) {
|
||||||
if (query == qRequisites) store->computeFSClosure(j, paths, false, includeOutputs);
|
if (query == qRequisites) store->computeFSClosure(j, paths, false, includeOutputs);
|
||||||
else if (query == qReferences) {
|
else if (query == qReferences) {
|
||||||
|
@ -350,7 +350,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
case qDeriver:
|
case qDeriver:
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path deriver = store->queryPathInfo(followLinksToStorePath(i))->deriver;
|
Path deriver = store->queryPathInfo(store->followLinksToStorePath(i))->deriver;
|
||||||
cout << format("%1%\n") %
|
cout << format("%1%\n") %
|
||||||
(deriver == "" ? "unknown-deriver" : deriver);
|
(deriver == "" ? "unknown-deriver" : deriver);
|
||||||
}
|
}
|
||||||
|
@ -358,7 +358,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
case qBinding:
|
case qBinding:
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = useDeriver(followLinksToStorePath(i));
|
Path path = useDeriver(store->followLinksToStorePath(i));
|
||||||
Derivation drv = store->derivationFromPath(path);
|
Derivation drv = store->derivationFromPath(path);
|
||||||
StringPairs::iterator j = drv.env.find(bindingName);
|
StringPairs::iterator j = drv.env.find(bindingName);
|
||||||
if (j == drv.env.end())
|
if (j == drv.env.end())
|
||||||
|
@ -371,7 +371,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
case qHash:
|
case qHash:
|
||||||
case qSize:
|
case qSize:
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise);
|
PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise);
|
||||||
for (auto & j : paths) {
|
for (auto & j : paths) {
|
||||||
auto info = store->queryPathInfo(j);
|
auto info = store->queryPathInfo(j);
|
||||||
if (query == qHash) {
|
if (query == qHash) {
|
||||||
|
@ -386,14 +386,14 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
case qTree: {
|
case qTree: {
|
||||||
PathSet done;
|
PathSet done;
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
printTree(followLinksToStorePath(i), "", "", done);
|
printTree(store->followLinksToStorePath(i), "", "", done);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case qGraph: {
|
case qGraph: {
|
||||||
PathSet roots;
|
PathSet roots;
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise);
|
PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise);
|
||||||
roots.insert(paths.begin(), paths.end());
|
roots.insert(paths.begin(), paths.end());
|
||||||
}
|
}
|
||||||
printDotGraph(ref<Store>(store), roots);
|
printDotGraph(ref<Store>(store), roots);
|
||||||
|
@ -403,7 +403,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
case qXml: {
|
case qXml: {
|
||||||
PathSet roots;
|
PathSet roots;
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise);
|
PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise);
|
||||||
roots.insert(paths.begin(), paths.end());
|
roots.insert(paths.begin(), paths.end());
|
||||||
}
|
}
|
||||||
printXmlGraph(ref<Store>(store), roots);
|
printXmlGraph(ref<Store>(store), roots);
|
||||||
|
@ -412,14 +412,14 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
case qResolve: {
|
case qResolve: {
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
cout << format("%1%\n") % followLinksToStorePath(i);
|
cout << format("%1%\n") % store->followLinksToStorePath(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case qRoots: {
|
case qRoots: {
|
||||||
PathSet referrers;
|
PathSet referrers;
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise);
|
PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise);
|
||||||
for (auto & j : paths)
|
for (auto & j : paths)
|
||||||
store->computeFSClosure(j, referrers, true,
|
store->computeFSClosure(j, referrers, true,
|
||||||
settings.gcKeepOutputs, settings.gcKeepDerivations);
|
settings.gcKeepOutputs, settings.gcKeepDerivations);
|
||||||
|
@ -479,7 +479,7 @@ static void opReadLog(Strings opFlags, Strings opArgs)
|
||||||
RunPager pager;
|
RunPager pager;
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = useDeriver(followLinksToStorePath(i));
|
Path path = useDeriver(store->followLinksToStorePath(i));
|
||||||
|
|
||||||
string baseName = baseNameOf(path);
|
string baseName = baseNameOf(path);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@ -599,7 +599,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs)
|
||||||
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = followLinksToStorePath(i);
|
Path path = store->followLinksToStorePath(i);
|
||||||
if (!store->isValidPath(path)) {
|
if (!store->isValidPath(path)) {
|
||||||
if (printInvalid)
|
if (printInvalid)
|
||||||
cout << format("%1%\n") % path;
|
cout << format("%1%\n") % path;
|
||||||
|
@ -662,7 +662,7 @@ static void opDelete(Strings opFlags, Strings opArgs)
|
||||||
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||||
|
|
||||||
for (auto & i : opArgs)
|
for (auto & i : opArgs)
|
||||||
options.pathsToDelete.insert(followLinksToStorePath(i));
|
options.pathsToDelete.insert(store->followLinksToStorePath(i));
|
||||||
|
|
||||||
GCResults results;
|
GCResults results;
|
||||||
PrintFreed freed(true, results);
|
PrintFreed freed(true, results);
|
||||||
|
@ -761,7 +761,7 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = followLinksToStorePath(i);
|
Path path = store->followLinksToStorePath(i);
|
||||||
printMsg(lvlTalkative, format("checking path ‘%1%’...") % path);
|
printMsg(lvlTalkative, format("checking path ‘%1%’...") % path);
|
||||||
auto info = store->queryPathInfo(path);
|
auto info = store->queryPathInfo(path);
|
||||||
HashSink sink(info->narHash.type);
|
HashSink sink(info->narHash.type);
|
||||||
|
@ -787,7 +787,7 @@ static void opRepairPath(Strings opFlags, Strings opArgs)
|
||||||
throw UsageError("no flags expected");
|
throw UsageError("no flags expected");
|
||||||
|
|
||||||
for (auto & i : opArgs) {
|
for (auto & i : opArgs) {
|
||||||
Path path = followLinksToStorePath(i);
|
Path path = store->followLinksToStorePath(i);
|
||||||
ensureLocalStore()->repairPath(path);
|
ensureLocalStore()->repairPath(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -847,7 +847,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
case cmdQueryValidPaths: {
|
case cmdQueryValidPaths: {
|
||||||
bool lock = readInt(in);
|
bool lock = readInt(in);
|
||||||
bool substitute = readInt(in);
|
bool substitute = readInt(in);
|
||||||
PathSet paths = readStorePaths<PathSet>(in);
|
PathSet paths = readStorePaths<PathSet>(*store, in);
|
||||||
if (lock && writeAllowed)
|
if (lock && writeAllowed)
|
||||||
for (auto & path : paths)
|
for (auto & path : paths)
|
||||||
store->addTempRoot(path);
|
store->addTempRoot(path);
|
||||||
|
@ -879,7 +879,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
case cmdQueryPathInfos: {
|
case cmdQueryPathInfos: {
|
||||||
PathSet paths = readStorePaths<PathSet>(in);
|
PathSet paths = readStorePaths<PathSet>(*store, in);
|
||||||
// !!! Maybe we want a queryPathInfos?
|
// !!! Maybe we want a queryPathInfos?
|
||||||
for (auto & i : paths) {
|
for (auto & i : paths) {
|
||||||
try {
|
try {
|
||||||
|
@ -896,7 +896,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
case cmdDumpStorePath:
|
case cmdDumpStorePath:
|
||||||
dumpPath(readStorePath(in), out);
|
dumpPath(readStorePath(*store, in), out);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cmdImportPaths: {
|
case cmdImportPaths: {
|
||||||
|
@ -908,7 +908,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
case cmdExportPaths: {
|
case cmdExportPaths: {
|
||||||
readInt(in); // obsolete
|
readInt(in); // obsolete
|
||||||
Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(in));
|
Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(*store, in));
|
||||||
reverse(sorted.begin(), sorted.end());
|
reverse(sorted.begin(), sorted.end());
|
||||||
store->exportPaths(sorted, out);
|
store->exportPaths(sorted, out);
|
||||||
break;
|
break;
|
||||||
|
@ -917,7 +917,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
case cmdBuildPaths: { /* Used by build-remote.pl. */
|
case cmdBuildPaths: { /* Used by build-remote.pl. */
|
||||||
|
|
||||||
if (!writeAllowed) throw Error("building paths is not allowed");
|
if (!writeAllowed) throw Error("building paths is not allowed");
|
||||||
PathSet paths = readStorePaths<PathSet>(in);
|
PathSet paths = readStorePaths<PathSet>(*store, in);
|
||||||
|
|
||||||
getBuildSettings();
|
getBuildSettings();
|
||||||
|
|
||||||
|
@ -936,9 +936,9 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
if (!writeAllowed) throw Error("building paths is not allowed");
|
if (!writeAllowed) throw Error("building paths is not allowed");
|
||||||
|
|
||||||
Path drvPath = readStorePath(in); // informational only
|
Path drvPath = readStorePath(*store, in); // informational only
|
||||||
BasicDerivation drv;
|
BasicDerivation drv;
|
||||||
in >> drv;
|
readDerivation(in, *store, drv);
|
||||||
|
|
||||||
getBuildSettings();
|
getBuildSettings();
|
||||||
|
|
||||||
|
@ -952,7 +952,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
||||||
|
|
||||||
case cmdQueryClosure: {
|
case cmdQueryClosure: {
|
||||||
bool includeOutputs = readInt(in);
|
bool includeOutputs = readInt(in);
|
||||||
PathSet paths = readStorePaths<PathSet>(in);
|
PathSet paths = readStorePaths<PathSet>(*store, in);
|
||||||
PathSet closure;
|
PathSet closure;
|
||||||
for (auto & i : paths)
|
for (auto & i : paths)
|
||||||
store->computeFSClosure(i, closure, false, includeOutputs);
|
store->computeFSClosure(i, closure, false, includeOutputs);
|
||||||
|
|
|
@ -102,7 +102,7 @@ void StorePathsCommand::run(ref<Store> store)
|
||||||
|
|
||||||
else {
|
else {
|
||||||
for (auto & storePath : storePaths)
|
for (auto & storePath : storePaths)
|
||||||
storePath = followLinksToStorePath(storePath);
|
storePath = store->followLinksToStorePath(storePath);
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
PathSet closure;
|
PathSet closure;
|
||||||
|
|
|
@ -17,7 +17,7 @@ UserEnvElems MixInstallables::evalInstallables(ref<Store> store)
|
||||||
|
|
||||||
if (std::string(installable, 0, 1) == "/") {
|
if (std::string(installable, 0, 1) == "/") {
|
||||||
|
|
||||||
if (isStorePath(installable)) {
|
if (store->isStorePath(installable)) {
|
||||||
|
|
||||||
if (isDerivation(installable)) {
|
if (isDerivation(installable)) {
|
||||||
UserEnvElem elem;
|
UserEnvElem elem;
|
||||||
|
|
Loading…
Reference in a new issue