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-daemon/local.mk \
|
||||
src/nix-collect-garbage/local.mk \
|
||||
src/download-via-ssh/local.mk \
|
||||
src/nix-prefetch-url/local.mk \
|
||||
perl/local.mk \
|
||||
scripts/local.mk \
|
||||
|
@ -22,6 +21,7 @@ makefiles = \
|
|||
misc/emacs/local.mk \
|
||||
doc/manual/local.mk \
|
||||
tests/local.mk
|
||||
#src/download-via-ssh/local.mk \
|
||||
|
||||
GLOBAL_CXXFLAGS += -std=c++11 -g -Wall
|
||||
|
||||
|
|
|
@ -161,8 +161,7 @@ SV * topoSortPaths(...)
|
|||
SV * followLinksToStorePath(char * path)
|
||||
CODE:
|
||||
try {
|
||||
store();
|
||||
RETVAL = newSVpv(followLinksToStorePath(path).c_str(), 0);
|
||||
RETVAL = newSVpv(store()->followLinksToStorePath(path).c_str(), 0);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
|
@ -289,7 +288,7 @@ SV * makeFixedOutputPath(int recursive, char * algo, char * hash, char * name)
|
|||
PPCODE:
|
||||
try {
|
||||
HashType ht = parseHashType(algo);
|
||||
Path path = makeFixedOutputPath(recursive, ht,
|
||||
Path path = store()->makeFixedOutputPath(recursive, ht,
|
||||
parseHash16or32(ht, hash), name);
|
||||
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
|
|
|
@ -341,7 +341,7 @@ Path EvalState::checkSourcePath(const Path & path_)
|
|||
/* To support import-from-derivation, allow access to anything in
|
||||
the store. FIXME: only allow access to paths that have been
|
||||
constructed by this evaluation. */
|
||||
if (isInStore(path)) return path;
|
||||
if (store->isInStore(path)) return path;
|
||||
|
||||
#if 0
|
||||
/* Hack to support the chroot dependencies of corepkgs (see
|
||||
|
@ -1517,7 +1517,7 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path)
|
|||
dstPath = srcToStore[path];
|
||||
else {
|
||||
dstPath = settings.readOnlyMode
|
||||
? computeStorePathForPath(checkSourcePath(path)).first
|
||||
? store->computeStorePathForPath(checkSourcePath(path)).first
|
||||
: store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair);
|
||||
srcToStore[path] = dstPath;
|
||||
printMsg(lvlChatty, format("copied source ‘%1%’ -> ‘%2%’")
|
||||
|
|
|
@ -50,7 +50,7 @@ void EvalState::realiseContext(const PathSet & context)
|
|||
for (auto & i : context) {
|
||||
std::pair<string, string> decoded = decodeContext(i);
|
||||
Path ctx = decoded.first;
|
||||
assert(isStorePath(ctx));
|
||||
assert(store->isStorePath(ctx));
|
||||
if (!store->isValidPath(ctx))
|
||||
throw InvalidPathError(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);
|
||||
|
||||
if (isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) {
|
||||
if (state.store->isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) {
|
||||
Derivation drv = readDerivation(path);
|
||||
Value & w = *state.allocValue();
|
||||
state.mkAttrs(w, 3 + drv.outputs.size());
|
||||
|
@ -624,7 +624,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * *
|
|||
outputHash = printHash(h);
|
||||
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.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)
|
||||
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;
|
||||
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
|
||||
directly in the store. The latter condition is necessary so
|
||||
e.g. nix-push does the right thing. */
|
||||
if (!isStorePath(path)) path = canonPath(path, true);
|
||||
if (!isInStore(path))
|
||||
if (!state.store->isStorePath(path)) path = canonPath(path, true);
|
||||
if (!state.store->isInStore(path))
|
||||
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)
|
||||
state.store->ensurePath(path2);
|
||||
context.insert(path2);
|
||||
|
@ -897,7 +897,7 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu
|
|||
}
|
||||
|
||||
Path storePath = settings.readOnlyMode
|
||||
? computeStorePathForText(name, contents, refs)
|
||||
? state.store->computeStorePathForText(name, contents, refs)
|
||||
: state.store->addTextToStore(name, contents, refs, state.repair);
|
||||
|
||||
/* 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 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);
|
||||
|
||||
mkString(v, dstPath, {dstPath});
|
||||
|
@ -1765,7 +1765,7 @@ void EvalState::createBaseEnv()
|
|||
mkString(v, nixVersion);
|
||||
addConstant("__nixVersion", v);
|
||||
|
||||
mkString(v, settings.nixStore);
|
||||
mkString(v, store->storeDir);
|
||||
addConstant("__storeDir", v);
|
||||
|
||||
/* Language version. This should be increased every time a new
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
|
||||
namespace nix {
|
||||
|
||||
BinaryCacheStore::BinaryCacheStore(const StoreParams & params)
|
||||
: compression(get(params, "compression", "xz"))
|
||||
BinaryCacheStore::BinaryCacheStore(const Params & params)
|
||||
: Store(params)
|
||||
, compression(get(params, "compression", "xz"))
|
||||
{
|
||||
auto secretKeyFile = get(params, "secret-key", "");
|
||||
if (secretKeyFile != "")
|
||||
|
@ -32,7 +33,7 @@ void BinaryCacheStore::init()
|
|||
|
||||
auto cacheInfo = getFile(cacheInfoFile);
|
||||
if (!cacheInfo) {
|
||||
upsertFile(cacheInfoFile, "StoreDir: " + settings.nixStore + "\n");
|
||||
upsertFile(cacheInfoFile, "StoreDir: " + storeDir + "\n");
|
||||
} else {
|
||||
for (auto & line : tokenizeString<Strings>(*cacheInfo, "\n")) {
|
||||
size_t colon = line.find(':');
|
||||
|
@ -40,9 +41,9 @@ void BinaryCacheStore::init()
|
|||
auto name = line.substr(0, colon);
|
||||
auto value = trim(line.substr(colon + 1, std::string::npos));
|
||||
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’")
|
||||
% getUri() % value % settings.nixStore);
|
||||
% getUri() % value % storeDir);
|
||||
} else if (name == "WantMassQuery") {
|
||||
wantMassQuery_ = value == "1";
|
||||
} else if (name == "Priority") {
|
||||
|
@ -181,7 +182,7 @@ std::shared_ptr<ValidPathInfo> BinaryCacheStore::queryPathInfoUncached(const Pat
|
|||
auto data = getFile(narInfoFile);
|
||||
if (!data) return 0;
|
||||
|
||||
auto narInfo = make_ref<NarInfo>(*data, narInfoFile);
|
||||
auto narInfo = make_ref<NarInfo>(*this, *data, narInfoFile);
|
||||
|
||||
stats.narInfoRead++;
|
||||
|
||||
|
@ -249,7 +250,7 @@ struct BinaryCacheStoreAccessor : public FSAccessor
|
|||
{
|
||||
auto path = canonPath(path_);
|
||||
|
||||
auto storePath = toStorePath(path);
|
||||
auto storePath = store->toStorePath(path);
|
||||
std::string restPath = std::string(path, storePath.size());
|
||||
|
||||
if (!store->isValidPath(storePath))
|
||||
|
|
|
@ -21,7 +21,7 @@ private:
|
|||
|
||||
protected:
|
||||
|
||||
BinaryCacheStore(const StoreParams & params);
|
||||
BinaryCacheStore(const Params & params);
|
||||
|
||||
[[noreturn]] void notImpl();
|
||||
|
||||
|
|
|
@ -1442,7 +1442,7 @@ void DerivationGoal::buildDone()
|
|||
#if HAVE_STATVFS
|
||||
unsigned long long required = 8ULL * 1024 * 1024; // FIXME: make configurable
|
||||
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)
|
||||
diskFull = true;
|
||||
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.,
|
||||
the compiler or linker might only want to accept paths to files
|
||||
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. */
|
||||
env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str();
|
||||
|
@ -1784,10 +1784,10 @@ void DerivationGoal::startBuilder()
|
|||
|
||||
/* Check that the store path is valid. */
|
||||
Path storePath = *i++;
|
||||
if (!isInStore(storePath))
|
||||
if (!worker.store.isInStore(storePath))
|
||||
throw BuildError(format("‘exportReferencesGraph’ contains a non-store path ‘%1%’")
|
||||
% storePath);
|
||||
storePath = toStorePath(storePath);
|
||||
storePath = worker.store.toStorePath(storePath);
|
||||
if (!worker.store.isValidPath(storePath))
|
||||
throw BuildError(format("‘exportReferencesGraph’ contains an invalid path ‘%1%’")
|
||||
% storePath);
|
||||
|
@ -1838,7 +1838,7 @@ void DerivationGoal::startBuilder()
|
|||
|
||||
string defaultChrootDirs;
|
||||
#if __linux__
|
||||
if (isInStore(BASH_PATH))
|
||||
if (worker.store.isInStore(BASH_PATH))
|
||||
defaultChrootDirs = "/bin/sh=" BASH_PATH;
|
||||
#endif
|
||||
|
||||
|
@ -1867,8 +1867,8 @@ void DerivationGoal::startBuilder()
|
|||
/* Add the closure of store paths to the chroot. */
|
||||
PathSet closure;
|
||||
for (auto & i : dirsInChroot)
|
||||
if (isInStore(i.second))
|
||||
worker.store.computeFSClosure(toStorePath(i.second), closure);
|
||||
if (worker.store.isInStore(i.second))
|
||||
worker.store.computeFSClosure(worker.store.toStorePath(i.second), closure);
|
||||
for (auto & i : closure)
|
||||
dirsInChroot[i] = i;
|
||||
|
||||
|
@ -1953,7 +1953,7 @@ void DerivationGoal::startBuilder()
|
|||
can be bind-mounted). !!! As an extra security
|
||||
precaution, make the fake Nix store only writable by the
|
||||
build user. */
|
||||
Path chrootStoreDir = chrootRootDir + settings.nixStore;
|
||||
Path chrootStoreDir = chrootRootDir + worker.store.storeDir;
|
||||
createDirs(chrootStoreDir);
|
||||
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
|
||||
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) {
|
||||
ancestry.insert(cur);
|
||||
cur = dirOf(cur);
|
||||
|
@ -2532,12 +2532,12 @@ void DerivationGoal::runChild()
|
|||
/* Parse a list of reference specifiers. Each element must either be
|
||||
a store path, or the symbolic name of the output of the derivation
|
||||
(such as `out'). */
|
||||
PathSet parseReferenceSpecifiers(const BasicDerivation & drv, string attr)
|
||||
PathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv, string attr)
|
||||
{
|
||||
PathSet result;
|
||||
Paths paths = tokenizeString<Paths>(attr);
|
||||
for (auto & i : paths) {
|
||||
if (isStorePath(i))
|
||||
if (store.isStorePath(i))
|
||||
result.insert(i);
|
||||
else if (drv.outputs.find(i) != drv.outputs.end())
|
||||
result.insert(drv.outputs.find(i)->second.path);
|
||||
|
@ -2660,7 +2660,7 @@ void DerivationGoal::registerOutputs()
|
|||
the derivation to its content-addressed location. */
|
||||
Hash h2 = recursive ? hashPath(ht, actualPath).first : hashFile(ht, actualPath);
|
||||
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%’")
|
||||
% dest % printHashType(ht) % printHash16or32(h2));
|
||||
if (worker.store.isValidPath(dest))
|
||||
|
@ -2733,7 +2733,7 @@ void DerivationGoal::registerOutputs()
|
|||
auto checkRefs = [&](const string & attrName, bool allowed, bool recursive) {
|
||||
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;
|
||||
if (recursive) {
|
||||
|
@ -2965,9 +2965,9 @@ PathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash)
|
|||
|
||||
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);
|
||||
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);
|
||||
assert(path.size() == p.size());
|
||||
rewritesToTmp[h1] = h2;
|
||||
|
|
|
@ -26,7 +26,6 @@ void builtinFetchurl(const BasicDerivation & drv)
|
|||
if (out == drv.env.end()) throw Error("attribute ‘url’ missing");
|
||||
|
||||
Path storePath = out->second;
|
||||
assertStorePath(storePath);
|
||||
|
||||
auto unpack = drv.env.find("unpack");
|
||||
if (unpack != drv.env.end() && unpack->second == "1") {
|
||||
|
|
|
@ -81,7 +81,7 @@ Path writeDerivation(ref<Store> store,
|
|||
string suffix = name + drvExtension;
|
||||
string contents = drv.unparse();
|
||||
return settings.readOnlyMode
|
||||
? computeStorePathForText(suffix, contents, references)
|
||||
? store->computeStorePathForText(suffix, contents, references)
|
||||
: 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();
|
||||
auto nr = readInt(in);
|
||||
|
@ -344,11 +344,11 @@ Source & operator >> (Source & in, BasicDerivation & drv)
|
|||
auto name = readString(in);
|
||||
DerivationOutput o;
|
||||
in >> o.path >> o.hashAlgo >> o.hash;
|
||||
assertStorePath(o.path);
|
||||
store.assertStorePath(o.path);
|
||||
drv.outputs[name] = o;
|
||||
}
|
||||
|
||||
drv.inputSrcs = readStorePaths<PathSet>(in);
|
||||
drv.inputSrcs = readStorePaths<PathSet>(store, in);
|
||||
in >> drv.platform >> drv.builder;
|
||||
drv.args = readStrings<Strings>(in);
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ bool wantOutput(const string & output, const std::set<string> & wanted);
|
|||
struct Source;
|
||||
struct Sink;
|
||||
|
||||
Source & operator >> (Source & in, BasicDerivation & drv);
|
||||
Source & readDerivation(Source & in, Store & store, 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;
|
||||
|
||||
info.path = readStorePath(source);
|
||||
info.path = readStorePath(*this, source);
|
||||
|
||||
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);
|
||||
if (info.deriver != "") assertStorePath(info.deriver);
|
||||
|
|
|
@ -204,7 +204,7 @@ typedef std::shared_ptr<AutoCloseFD> FDPtr;
|
|||
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
|
||||
files. */
|
||||
|
@ -251,7 +251,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds)
|
|||
while ((end = contents.find((char) 0, pos)) != string::npos) {
|
||||
Path root(contents, pos, end - pos);
|
||||
debug(format("got temporary root ‘%1%’") % root);
|
||||
assertStorePath(root);
|
||||
store.assertStorePath(root);
|
||||
tempRoots.insert(root);
|
||||
pos = end + 1;
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
|||
}
|
||||
|
||||
else if (type == DT_REG) {
|
||||
Path storePath = settings.nixStore + "/" + baseNameOf(path);
|
||||
Path storePath = storeDir + "/" + baseNameOf(path);
|
||||
if (isStorePath(storePath) && isValidPath(storePath))
|
||||
roots[path] = storePath;
|
||||
}
|
||||
|
@ -594,7 +594,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
|||
{
|
||||
GCState state(results);
|
||||
state.options = options;
|
||||
state.trashDir = settings.nixStore + "/trash";
|
||||
state.trashDir = storeDir + "/trash";
|
||||
state.gcKeepOutputs = settings.gcKeepOutputs;
|
||||
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
|
||||
can be added to the set of temporary roots. */
|
||||
FDs fds;
|
||||
readTempRoots(state.tempRoots, fds);
|
||||
readTempRoots(*this, state.tempRoots, fds);
|
||||
state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
|
||||
|
||||
/* After this point the set of roots or temporary roots cannot
|
||||
|
@ -675,8 +675,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
|||
|
||||
try {
|
||||
|
||||
AutoCloseDir dir = opendir(settings.nixStore.c_str());
|
||||
if (!dir) throw SysError(format("opening directory ‘%1%’") % settings.nixStore);
|
||||
AutoCloseDir dir = opendir(storeDir.c_str());
|
||||
if (!dir) throw SysError(format("opening directory ‘%1%’") % storeDir);
|
||||
|
||||
/* Read the store and immediately delete all paths that
|
||||
aren't valid. When using --max-freed etc., deleting
|
||||
|
@ -690,7 +690,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
|||
checkInterrupt();
|
||||
string name = dirent->d_name;
|
||||
if (name == "." || name == "..") continue;
|
||||
Path path = settings.nixStore + "/" + name;
|
||||
Path path = storeDir + "/" + name;
|
||||
if (isStorePath(path) && isValidPath(path))
|
||||
entries.push_back(path);
|
||||
else
|
||||
|
|
|
@ -18,7 +18,7 @@ private:
|
|||
public:
|
||||
|
||||
HttpBinaryCacheStore(
|
||||
const StoreParams & params, const Path & _cacheUri)
|
||||
const Params & params, const Path & _cacheUri)
|
||||
: BinaryCacheStore(params)
|
||||
, cacheUri(_cacheUri)
|
||||
, downloaders(
|
||||
|
@ -45,7 +45,7 @@ public:
|
|||
} catch (UploadToHTTP &) {
|
||||
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([](
|
||||
const std::string & uri, const StoreParams & params)
|
||||
const std::string & uri, const Store::Params & params)
|
||||
-> std::shared_ptr<Store>
|
||||
{
|
||||
if (std::string(uri, 0, 7) != "http://" &&
|
||||
|
|
|
@ -13,7 +13,7 @@ private:
|
|||
public:
|
||||
|
||||
LocalBinaryCacheStore(
|
||||
const StoreParams & params, const Path & binaryCacheDir)
|
||||
const Params & params, const Path & binaryCacheDir)
|
||||
: BinaryCacheStore(params)
|
||||
, binaryCacheDir(binaryCacheDir)
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ protected:
|
|||
if (entry.name.size() != 40 ||
|
||||
!hasSuffix(entry.name, ".narinfo"))
|
||||
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;
|
||||
|
@ -59,7 +59,7 @@ void LocalBinaryCacheStore::init()
|
|||
BinaryCacheStore::init();
|
||||
|
||||
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)
|
||||
|
@ -93,7 +93,7 @@ std::shared_ptr<std::string> LocalBinaryCacheStore::getFile(const std::string &
|
|||
}
|
||||
|
||||
static RegisterStoreImplementation regStore([](
|
||||
const std::string & uri, const StoreParams & params)
|
||||
const std::string & uri, const Store::Params & params)
|
||||
-> std::shared_ptr<Store>
|
||||
{
|
||||
if (std::string(uri, 0, 7) != "file://") return 0;
|
||||
|
|
|
@ -12,7 +12,7 @@ struct LocalStoreAccessor : public FSAccessor
|
|||
|
||||
void assertStore(const Path & path)
|
||||
{
|
||||
Path storePath = toStorePath(path);
|
||||
Path storePath = store->toStorePath(path);
|
||||
if (!store->isValidPath(storePath))
|
||||
throw Error(format("path ‘%1%’ is not a valid store path") % storePath);
|
||||
}
|
||||
|
|
|
@ -36,26 +36,9 @@
|
|||
namespace nix {
|
||||
|
||||
|
||||
void checkStoreNotSymlink()
|
||||
{
|
||||
if (getEnv("NIX_IGNORE_SYMLINK_STORE") == "1") return;
|
||||
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")
|
||||
LocalStore::LocalStore(const Params & params)
|
||||
: LocalFSStore(params)
|
||||
, linksDir(storeDir + "/.links")
|
||||
, reservedPath(settings.nixDBPath + "/reserved")
|
||||
, schemaPath(settings.nixDBPath + "/schema")
|
||||
, 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. */
|
||||
createDirs(settings.nixStore);
|
||||
createDirs(storeDir);
|
||||
makeStoreWritable();
|
||||
createDirs(linksDir);
|
||||
Path profilesDir = settings.nixStateDir + "/profiles";
|
||||
|
@ -99,19 +82,33 @@ LocalStore::LocalStore()
|
|||
% settings.buildUsersGroup);
|
||||
else {
|
||||
struct stat st;
|
||||
if (stat(settings.nixStore.c_str(), &st))
|
||||
throw SysError(format("getting attributes of path ‘%1%’") % settings.nixStore);
|
||||
if (stat(storeDir.c_str(), &st))
|
||||
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 (chown(settings.nixStore.c_str(), 0, gr->gr_gid) == -1)
|
||||
throw SysError(format("changing ownership of path ‘%1%’") % settings.nixStore);
|
||||
if (chmod(settings.nixStore.c_str(), perm) == -1)
|
||||
throw SysError(format("changing permissions on path ‘%1%’") % settings.nixStore);
|
||||
if (chown(storeDir.c_str(), 0, gr->gr_gid) == -1)
|
||||
throw SysError(format("changing ownership of path ‘%1%’") % storeDir);
|
||||
if (chmod(storeDir.c_str(), perm) == -1)
|
||||
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
|
||||
this prevents the garbage collector from running when it's most
|
||||
|
@ -351,15 +348,15 @@ void LocalStore::makeStoreWritable()
|
|||
if (getuid() != 0) return;
|
||||
/* Check if /nix/store is on a read-only mount. */
|
||||
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");
|
||||
|
||||
if (stat.f_flag & ST_RDONLY) {
|
||||
if (unshare(CLONE_NEWNS) == -1)
|
||||
throw SysError("setting up a private mount namespace");
|
||||
|
||||
if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
||||
throw SysError(format("remounting %1% writable") % settings.nixStore);
|
||||
if (mount(0, storeDir.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1)
|
||||
throw SysError(format("remounting %1% writable") % storeDir);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -771,7 +768,7 @@ Path LocalStore::queryPathFromHashPart(const string & hashPart)
|
|||
{
|
||||
if (hashPart.size() != storePathHashLen) throw Error("invalid hash part");
|
||||
|
||||
Path prefix = settings.nixStore + "/" + hashPart;
|
||||
Path prefix = storeDir + "/" + hashPart;
|
||||
|
||||
return retrySQLite<Path>([&]() {
|
||||
auto state(_state.lock());
|
||||
|
@ -1071,7 +1068,7 @@ Path LocalStore::createTempDirInStore()
|
|||
/* There is a slight possibility that `tmpDir' gets deleted by
|
||||
the GC between createTempDir() and addTempRoot(), so repeat
|
||||
until `tmpDir' exists. */
|
||||
tmpDir = createTempDir(settings.nixStore);
|
||||
tmpDir = createTempDir(storeDir);
|
||||
addTempRoot(tmpDir);
|
||||
} while (!pathExists(tmpDir));
|
||||
return tmpDir;
|
||||
|
@ -1111,7 +1108,7 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
|
|||
AutoCloseFD fdGCLock = openGCLock(ltWrite);
|
||||
|
||||
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. */
|
||||
printMsg(lvlInfo, "checking path existence...");
|
||||
|
@ -1275,7 +1272,7 @@ void LocalStore::upgradeStore7()
|
|||
{
|
||||
if (getuid() != 0) return;
|
||||
printMsg(lvlError, "removing immutable bits from the Nix store (this may take a while)...");
|
||||
makeMutable(settings.nixStore);
|
||||
makeMutable(storeDir);
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
@ -85,7 +85,7 @@ public:
|
|||
|
||||
/* Initialise the local store, upgrading the schema if
|
||||
necessary. */
|
||||
LocalStore();
|
||||
LocalStore(const Params & params);
|
||||
|
||||
~LocalStore();
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "nar-info-disk-cache.hh"
|
||||
#include "sync.hh"
|
||||
#include "sqlite.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
|
@ -54,11 +53,17 @@ public:
|
|||
/* How long negative lookups are valid. */
|
||||
const int ttlNegative = 3600;
|
||||
|
||||
struct Cache
|
||||
{
|
||||
int id;
|
||||
Path storeDir;
|
||||
};
|
||||
|
||||
struct State
|
||||
{
|
||||
SQLite db;
|
||||
SQLiteStmt insertCache, queryCache, insertNAR, queryNAR, insertNARExistence, queryNARExistence;
|
||||
std::map<std::string, int> caches;
|
||||
std::map<std::string, Cache> caches;
|
||||
};
|
||||
|
||||
Sync<State> _state;
|
||||
|
@ -106,22 +111,22 @@ public:
|
|||
"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);
|
||||
if (i == state.caches.end()) abort();
|
||||
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());
|
||||
|
||||
// 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);
|
||||
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
|
||||
|
@ -134,7 +139,7 @@ public:
|
|||
auto queryCache(state->queryCache.use()(uri));
|
||||
|
||||
if (queryCache.next()) {
|
||||
state->caches[uri] = queryCache.getInt(0);
|
||||
state->caches[uri] = Cache{(int) queryCache.getInt(0), queryCache.getStr(1)};
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -146,9 +151,9 @@ public:
|
|||
{
|
||||
auto state(_state.lock());
|
||||
|
||||
auto queryNAR(state->queryNAR.use()
|
||||
(uriToInt(*state, uri))
|
||||
(hashPart));
|
||||
auto & cache(getCache(*state, uri));
|
||||
|
||||
auto queryNAR(state->queryNAR.use()(cache.id)(hashPart));
|
||||
|
||||
if (!queryNAR.next())
|
||||
// FIXME: check NARExistence
|
||||
|
@ -159,7 +164,7 @@ public:
|
|||
// FIXME: implement TTL.
|
||||
|
||||
auto namePart = queryNAR.getStr(2);
|
||||
narInfo->path = settings.nixStore + "/" +
|
||||
narInfo->path = cache.storeDir + "/" +
|
||||
hashPart + (namePart.empty() ? "" : "-" + namePart);
|
||||
narInfo->url = queryNAR.getStr(3);
|
||||
narInfo->compression = queryNAR.getStr(4);
|
||||
|
@ -169,9 +174,9 @@ public:
|
|||
narInfo->narHash = parseHash(queryNAR.getStr(7));
|
||||
narInfo->narSize = queryNAR.getInt(8);
|
||||
for (auto & r : tokenizeString<Strings>(queryNAR.getStr(9), " "))
|
||||
narInfo->references.insert(settings.nixStore + "/" + r);
|
||||
narInfo->references.insert(cache.storeDir + "/" + r);
|
||||
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), " "))
|
||||
narInfo->sigs.insert(sig);
|
||||
|
||||
|
@ -184,6 +189,8 @@ public:
|
|||
{
|
||||
auto state(_state.lock());
|
||||
|
||||
auto & cache(getCache(*state, uri));
|
||||
|
||||
if (info) {
|
||||
|
||||
auto narInfo = std::dynamic_pointer_cast<NarInfo>(info);
|
||||
|
@ -191,7 +198,7 @@ public:
|
|||
assert(hashPart == storePathToHash(info->path));
|
||||
|
||||
state->insertNAR.use()
|
||||
(uriToInt(*state, uri))
|
||||
(cache.id)
|
||||
(hashPart)
|
||||
(storePathToName(info->path))
|
||||
(narInfo ? narInfo->url : "", narInfo != 0)
|
||||
|
|
|
@ -10,7 +10,8 @@ class NarInfoDiskCache
|
|||
public:
|
||||
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;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
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 = [&]() {
|
||||
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);
|
||||
|
||||
if (name == "StorePath") {
|
||||
if (!isStorePath(value)) corrupt();
|
||||
if (!store.isStorePath(value)) corrupt();
|
||||
path = value;
|
||||
}
|
||||
else if (name == "URL")
|
||||
|
@ -53,14 +53,14 @@ NarInfo::NarInfo(const std::string & s, const std::string & whence)
|
|||
auto refs = tokenizeString<Strings>(value, " ");
|
||||
if (!references.empty()) corrupt();
|
||||
for (auto & r : refs) {
|
||||
auto r2 = settings.nixStore + "/" + r;
|
||||
if (!isStorePath(r2)) corrupt();
|
||||
auto r2 = store.storeDir + "/" + r;
|
||||
if (!store.isStorePath(r2)) corrupt();
|
||||
references.insert(r2);
|
||||
}
|
||||
}
|
||||
else if (name == "Deriver") {
|
||||
auto p = settings.nixStore + "/" + value;
|
||||
if (!isStorePath(p)) corrupt();
|
||||
auto p = store.storeDir + "/" + value;
|
||||
if (!store.isStorePath(p)) corrupt();
|
||||
deriver = p;
|
||||
}
|
||||
else if (name == "System")
|
||||
|
|
|
@ -16,7 +16,7 @@ struct NarInfo : ValidPathInfo
|
|||
|
||||
NarInfo() { }
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -184,7 +184,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa
|
|||
MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : "");
|
||||
|
||||
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 (errno == EMLINK) {
|
||||
|
|
|
@ -21,26 +21,27 @@
|
|||
namespace nix {
|
||||
|
||||
|
||||
Path readStorePath(Source & from)
|
||||
Path readStorePath(Store & store, Source & from)
|
||||
{
|
||||
Path path = readString(from);
|
||||
assertStorePath(path);
|
||||
store.assertStorePath(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
template<class T> T readStorePaths(Source & from)
|
||||
template<class T> T readStorePaths(Store & store, Source & from)
|
||||
{
|
||||
T paths = readStrings<T>(from);
|
||||
for (auto & i : paths) assertStorePath(i);
|
||||
for (auto & i : paths) store.assertStorePath(i);
|
||||
return paths;
|
||||
}
|
||||
|
||||
template PathSet readStorePaths(Source & from);
|
||||
template PathSet readStorePaths(Store & store, Source & from);
|
||||
|
||||
|
||||
RemoteStore::RemoteStore(size_t maxConnections)
|
||||
: connections(make_ref<Pool<Connection>>(
|
||||
RemoteStore::RemoteStore(const Params & params, size_t maxConnections)
|
||||
: LocalFSStore(params)
|
||||
, connections(make_ref<Pool<Connection>>(
|
||||
maxConnections,
|
||||
[this]() { return openConnection(); },
|
||||
[](const ref<Connection> & r) { return r->to.good() && r->from.good(); }
|
||||
|
@ -168,7 +169,7 @@ PathSet RemoteStore::queryValidPaths(const PathSet & paths)
|
|||
} else {
|
||||
conn->to << wopQueryValidPaths << paths;
|
||||
conn->processStderr();
|
||||
return readStorePaths<PathSet>(conn->from);
|
||||
return readStorePaths<PathSet>(*this, conn->from);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,7 +179,7 @@ PathSet RemoteStore::queryAllValidPaths()
|
|||
auto conn(connections->get());
|
||||
conn->to << wopQueryAllValidPaths;
|
||||
conn->processStderr();
|
||||
return readStorePaths<PathSet>(conn->from);
|
||||
return readStorePaths<PathSet>(*this, conn->from);
|
||||
}
|
||||
|
||||
|
||||
|
@ -196,7 +197,7 @@ PathSet RemoteStore::querySubstitutablePaths(const PathSet & paths)
|
|||
} else {
|
||||
conn->to << wopQuerySubstitutablePaths << paths;
|
||||
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;
|
||||
info.deriver = readString(conn->from);
|
||||
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.narSize = GET_PROTOCOL_MINOR(conn->daemonVersion) >= 7 ? readLongLong(conn->from) : 0;
|
||||
infos[i] = info;
|
||||
|
@ -232,11 +233,11 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths,
|
|||
conn->processStderr();
|
||||
unsigned int count = readInt(conn->from);
|
||||
for (unsigned int n = 0; n < count; n++) {
|
||||
Path path = readStorePath(conn->from);
|
||||
Path path = readStorePath(*this, conn->from);
|
||||
SubstitutablePathInfo & info(infos[path]);
|
||||
info.deriver = readString(conn->from);
|
||||
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.narSize = readLongLong(conn->from);
|
||||
}
|
||||
|
@ -266,7 +267,7 @@ std::shared_ptr<ValidPathInfo> RemoteStore::queryPathInfoUncached(const Path & p
|
|||
info->deriver = readString(conn->from);
|
||||
if (info->deriver != "") assertStorePath(info->deriver);
|
||||
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->narSize = readLongLong(conn->from);
|
||||
if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 16) {
|
||||
|
@ -283,7 +284,7 @@ void RemoteStore::queryReferrers(const Path & path,
|
|||
auto conn(connections->get());
|
||||
conn->to << wopQueryReferrers << path;
|
||||
conn->processStderr();
|
||||
PathSet referrers2 = readStorePaths<PathSet>(conn->from);
|
||||
PathSet referrers2 = readStorePaths<PathSet>(*this, conn->from);
|
||||
referrers.insert(referrers2.begin(), referrers2.end());
|
||||
}
|
||||
|
||||
|
@ -293,7 +294,7 @@ PathSet RemoteStore::queryValidDerivers(const Path & path)
|
|||
auto conn(connections->get());
|
||||
conn->to << wopQueryValidDerivers << path;
|
||||
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());
|
||||
conn->to << wopQueryDerivationOutputs << path;
|
||||
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;
|
||||
}
|
||||
|
||||
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->processStderr();
|
||||
return readStorePath(conn->from);
|
||||
return readStorePath(*this, conn->from);
|
||||
}
|
||||
|
||||
|
||||
|
@ -465,7 +466,7 @@ Roots RemoteStore::findRoots()
|
|||
Roots result;
|
||||
while (count--) {
|
||||
Path link = readString(conn->from);
|
||||
Path target = readStorePath(conn->from);
|
||||
Path target = readStorePath(*this, conn->from);
|
||||
result[link] = target;
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -22,7 +22,7 @@ class RemoteStore : public LocalFSStore
|
|||
{
|
||||
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. */
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
|||
Stats stats;
|
||||
|
||||
S3BinaryCacheStoreImpl(
|
||||
const StoreParams & params, const std::string & bucketName)
|
||||
const Params & params, const std::string & bucketName)
|
||||
: S3BinaryCacheStore(params)
|
||||
, bucketName(bucketName)
|
||||
, config(makeConfig())
|
||||
|
@ -95,7 +95,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
|||
|
||||
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) {
|
||||
auto & key = object.GetKey();
|
||||
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();
|
||||
|
@ -244,7 +244,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore
|
|||
};
|
||||
|
||||
static RegisterStoreImplementation regStore([](
|
||||
const std::string & uri, const StoreParams & params)
|
||||
const std::string & uri, const Store::Params & params)
|
||||
-> std::shared_ptr<Store>
|
||||
{
|
||||
if (std::string(uri, 0, 5) != "s3://") return 0;
|
||||
|
|
|
@ -10,7 +10,7 @@ class S3BinaryCacheStore : public BinaryCacheStore
|
|||
{
|
||||
protected:
|
||||
|
||||
S3BinaryCacheStore(const StoreParams & params)
|
||||
S3BinaryCacheStore(const Params & params)
|
||||
: BinaryCacheStore(params)
|
||||
{ }
|
||||
|
||||
|
|
|
@ -8,32 +8,32 @@
|
|||
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)
|
||||
&& path.size() >= settings.nixStore.size() + 1 + storePathHashLen
|
||||
&& path.find('/', settings.nixStore.size() + 1) == Path::npos;
|
||||
&& path.size() >= storeDir.size() + 1 + storePathHashLen
|
||||
&& path.find('/', storeDir.size() + 1) == Path::npos;
|
||||
}
|
||||
|
||||
|
||||
void assertStorePath(const Path & path)
|
||||
void Store::assertStorePath(const Path & path) const
|
||||
{
|
||||
if (!isStorePath(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))
|
||||
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)
|
||||
return path;
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
@ -63,18 +63,17 @@ Path followLinksToStorePath(const Path & path)
|
|||
|
||||
string storePathToName(const Path & path)
|
||||
{
|
||||
assertStorePath(path);
|
||||
auto l = settings.nixStore.size() + 1 + storePathHashLen;
|
||||
assert(path.size() >= l);
|
||||
return path.size() == l ? "" : string(path, l + 1);
|
||||
auto base = baseNameOf(path);
|
||||
assert(base.size() == storePathHashLen || (base.size() > storePathHashLen && base[storePathHashLen] == '-'));
|
||||
return base.size() == storePathHashLen ? "" : string(base, storePathHashLen + 1);
|
||||
}
|
||||
|
||||
|
||||
string storePathToHash(const Path & path)
|
||||
{
|
||||
assertStorePath(path);
|
||||
assert(path.size() >= settings.nixStore.size() + 1 + storePathHashLen);
|
||||
return string(path, settings.nixStore.size() + 1, storePathHashLen);
|
||||
auto base = baseNameOf(path);
|
||||
assert(base.size() >= storePathHashLen);
|
||||
return string(base, 0, storePathHashLen);
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,31 +167,31 @@ void checkStoreName(const string & name)
|
|||
*/
|
||||
|
||||
|
||||
Path makeStorePath(const string & type,
|
||||
const Hash & hash, const string & name)
|
||||
Path Store::makeStorePath(const string & type,
|
||||
const Hash & hash, const string & name) const
|
||||
{
|
||||
/* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */
|
||||
string s = type + ":sha256:" + printHash(hash) + ":"
|
||||
+ settings.nixStore + ":" + name;
|
||||
+ storeDir + ":" + name;
|
||||
|
||||
checkStoreName(name);
|
||||
|
||||
return settings.nixStore + "/"
|
||||
return storeDir + "/"
|
||||
+ printHash32(compressHash(hashString(htSHA256, s), 20))
|
||||
+ "-" + name;
|
||||
}
|
||||
|
||||
|
||||
Path makeOutputPath(const string & id,
|
||||
const Hash & hash, const string & name)
|
||||
Path Store::makeOutputPath(const string & id,
|
||||
const Hash & hash, const string & name) const
|
||||
{
|
||||
return makeStorePath("output:" + id, hash,
|
||||
name + (id == "out" ? "" : "-" + id));
|
||||
}
|
||||
|
||||
|
||||
Path makeFixedOutputPath(bool recursive,
|
||||
HashType hashAlgo, Hash hash, string name)
|
||||
Path Store::makeFixedOutputPath(bool recursive,
|
||||
HashType hashAlgo, Hash hash, string name) const
|
||||
{
|
||||
return hashAlgo == htSHA256 && recursive
|
||||
? makeStorePath("source", hash, name)
|
||||
|
@ -203,8 +202,8 @@ Path makeFixedOutputPath(bool recursive,
|
|||
}
|
||||
|
||||
|
||||
std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath,
|
||||
bool recursive, HashType hashAlgo, PathFilter & filter)
|
||||
std::pair<Path, Hash> Store::computeStorePathForPath(const Path & srcPath,
|
||||
bool recursive, HashType hashAlgo, PathFilter & filter) const
|
||||
{
|
||||
HashType ht(hashAlgo);
|
||||
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,
|
||||
const PathSet & references)
|
||||
Path Store::computeStorePathForText(const string & name, const string & s,
|
||||
const PathSet & references) const
|
||||
{
|
||||
Hash hash = hashString(htSHA256, s);
|
||||
/* 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()
|
||||
{
|
||||
return "";
|
||||
|
@ -465,7 +470,7 @@ RegisterStoreImplementation::Implementations * RegisterStoreImplementation::impl
|
|||
ref<Store> openStoreAt(const std::string & uri_)
|
||||
{
|
||||
auto uri(uri_);
|
||||
StoreParams params;
|
||||
Store::Params params;
|
||||
auto q = uri.find('?');
|
||||
if (q != std::string::npos) {
|
||||
for (auto s : tokenizeString<Strings>(uri.substr(q + 1), "&")) {
|
||||
|
@ -492,7 +497,7 @@ ref<Store> openStore()
|
|||
|
||||
|
||||
static RegisterStoreImplementation regStore([](
|
||||
const std::string & uri, const StoreParams & params)
|
||||
const std::string & uri, const Store::Params & params)
|
||||
-> std::shared_ptr<Store>
|
||||
{
|
||||
enum { mDaemon, mLocal, mAuto } mode;
|
||||
|
@ -512,8 +517,8 @@ static RegisterStoreImplementation regStore([](
|
|||
}
|
||||
|
||||
return mode == mDaemon
|
||||
? std::shared_ptr<Store>(std::make_shared<RemoteStore>())
|
||||
: std::shared_ptr<Store>(std::make_shared<LocalStore>());
|
||||
? std::shared_ptr<Store>(std::make_shared<RemoteStore>(params))
|
||||
: std::shared_ptr<Store>(std::make_shared<LocalStore>(params));
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -177,6 +177,12 @@ class NarInfoDiskCache;
|
|||
|
||||
class Store : public std::enable_shared_from_this<Store>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::map<std::string, std::string> Params;
|
||||
|
||||
const Path storeDir;
|
||||
|
||||
protected:
|
||||
|
||||
struct State
|
||||
|
@ -188,12 +194,71 @@ protected:
|
|||
|
||||
std::shared_ptr<NarInfoDiskCache> diskCache;
|
||||
|
||||
Store(const Params & params);
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Store() { }
|
||||
|
||||
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. */
|
||||
bool isValidPath(const Path & path);
|
||||
|
||||
|
@ -429,80 +494,26 @@ protected:
|
|||
|
||||
class LocalFSStore : public Store
|
||||
{
|
||||
protected:
|
||||
using Store::Store;
|
||||
public:
|
||||
void narFromPath(const Path & path, Sink & sink) 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. */
|
||||
string storePathToName(const Path & path);
|
||||
|
||||
/* Extract the hash part of the given store 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);
|
||||
|
||||
|
||||
/* 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. */
|
||||
void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
|
||||
const Path & storePath, bool repair = false);
|
||||
|
@ -542,10 +553,8 @@ std::list<ref<Store>> getDefaultSubstituters();
|
|||
|
||||
|
||||
/* Store implementation registration. */
|
||||
typedef std::map<std::string, std::string> StoreParams;
|
||||
|
||||
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
|
||||
{
|
||||
|
|
|
@ -56,8 +56,8 @@ typedef enum {
|
|||
#define STDERR_ERROR 0x63787470
|
||||
|
||||
|
||||
Path readStorePath(Source & from);
|
||||
template<class T> T readStorePaths(Source & from);
|
||||
Path readStorePath(Store & store, 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. */
|
||||
Path path = readString(from);
|
||||
startWork();
|
||||
assertStorePath(path);
|
||||
store->assertStorePath(path);
|
||||
bool result = store->isValidPath(path);
|
||||
stopWork();
|
||||
to << result;
|
||||
|
@ -184,7 +184,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopQueryValidPaths: {
|
||||
PathSet paths = readStorePaths<PathSet>(from);
|
||||
PathSet paths = readStorePaths<PathSet>(*store, from);
|
||||
startWork();
|
||||
PathSet res = store->queryValidPaths(paths);
|
||||
stopWork();
|
||||
|
@ -193,7 +193,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopHasSubstitutes: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
startWork();
|
||||
PathSet res = store->querySubstitutablePaths({path});
|
||||
stopWork();
|
||||
|
@ -202,7 +202,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopQuerySubstitutablePaths: {
|
||||
PathSet paths = readStorePaths<PathSet>(from);
|
||||
PathSet paths = readStorePaths<PathSet>(*store, from);
|
||||
startWork();
|
||||
PathSet res = store->querySubstitutablePaths(paths);
|
||||
stopWork();
|
||||
|
@ -211,7 +211,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopQueryPathHash: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
startWork();
|
||||
auto hash = store->queryPathInfo(path)->narHash;
|
||||
stopWork();
|
||||
|
@ -223,7 +223,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
case wopQueryReferrers:
|
||||
case wopQueryValidDerivers:
|
||||
case wopQueryDerivationOutputs: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
startWork();
|
||||
PathSet paths;
|
||||
if (op == wopQueryReferences)
|
||||
|
@ -239,7 +239,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopQueryDerivationOutputNames: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
startWork();
|
||||
StringSet names;
|
||||
names = store->queryDerivationOutputNames(path);
|
||||
|
@ -249,7 +249,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopQueryDeriver: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
startWork();
|
||||
auto deriver = store->queryPathInfo(path)->deriver;
|
||||
stopWork();
|
||||
|
@ -302,7 +302,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
case wopAddTextToStore: {
|
||||
string suffix = readString(from);
|
||||
string s = readString(from);
|
||||
PathSet refs = readStorePaths<PathSet>(from);
|
||||
PathSet refs = readStorePaths<PathSet>(*store, from);
|
||||
startWork();
|
||||
Path path = store->addTextToStore(suffix, s, refs);
|
||||
stopWork();
|
||||
|
@ -311,7 +311,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopExportPath: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
readInt(from); // obsolete
|
||||
startWork();
|
||||
TunnelSink sink(to);
|
||||
|
@ -331,7 +331,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopBuildPaths: {
|
||||
PathSet drvs = readStorePaths<PathSet>(from);
|
||||
PathSet drvs = readStorePaths<PathSet>(*store, from);
|
||||
BuildMode mode = bmNormal;
|
||||
if (GET_PROTOCOL_MINOR(clientVersion) >= 15) {
|
||||
mode = (BuildMode)readInt(from);
|
||||
|
@ -349,9 +349,9 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopBuildDerivation: {
|
||||
Path drvPath = readStorePath(from);
|
||||
Path drvPath = readStorePath(*store, from);
|
||||
BasicDerivation drv;
|
||||
from >> drv;
|
||||
readDerivation(from, *store, drv);
|
||||
BuildMode buildMode = (BuildMode) readInt(from);
|
||||
startWork();
|
||||
if (!trusted)
|
||||
|
@ -363,7 +363,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopEnsurePath: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
startWork();
|
||||
store->ensurePath(path);
|
||||
stopWork();
|
||||
|
@ -372,7 +372,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopAddTempRoot: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
startWork();
|
||||
store->addTempRoot(path);
|
||||
stopWork();
|
||||
|
@ -410,7 +410,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
case wopCollectGarbage: {
|
||||
GCOptions options;
|
||||
options.action = (GCOptions::GCAction) readInt(from);
|
||||
options.pathsToDelete = readStorePaths<PathSet>(from);
|
||||
options.pathsToDelete = readStorePaths<PathSet>(*store, from);
|
||||
options.ignoreLiveness = readInt(from);
|
||||
options.maxFreed = readLongLong(from);
|
||||
readInt(from); // obsolete field
|
||||
|
@ -486,7 +486,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopQuerySubstitutablePathInfos: {
|
||||
PathSet paths = readStorePaths<PathSet>(from);
|
||||
PathSet paths = readStorePaths<PathSet>(*store, from);
|
||||
startWork();
|
||||
SubstitutablePathInfos infos;
|
||||
store->querySubstitutablePathInfos(paths, infos);
|
||||
|
@ -508,7 +508,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopQueryPathInfo: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
std::shared_ptr<const ValidPathInfo> info;
|
||||
startWork();
|
||||
try {
|
||||
|
@ -553,7 +553,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
|
|||
}
|
||||
|
||||
case wopAddSignatures: {
|
||||
Path path = readStorePath(from);
|
||||
Path path = readStorePath(*store, from);
|
||||
StringSet sigs = readStrings<StringSet>(from);
|
||||
startWork();
|
||||
if (!trusted)
|
||||
|
@ -607,7 +607,7 @@ static void processConnection(bool trusted)
|
|||
#endif
|
||||
|
||||
/* Open the store. */
|
||||
auto store = make_ref<LocalStore>();
|
||||
auto store = make_ref<LocalStore>(Store::Params()); // FIXME: get params from somewhere
|
||||
|
||||
stopWork();
|
||||
to.flush();
|
||||
|
|
|
@ -387,7 +387,7 @@ static void queryInstSources(EvalState & state,
|
|||
case srcStorePaths: {
|
||||
|
||||
for (auto & i : args) {
|
||||
Path path = followLinksToStorePath(i);
|
||||
Path path = state.store->followLinksToStorePath(i);
|
||||
|
||||
string name = baseNameOf(path);
|
||||
string::size_type dash = name.find('-');
|
||||
|
@ -742,7 +742,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors,
|
|||
for (auto & j : selectors)
|
||||
/* !!! the repeated calls to followLinksToStorePath()
|
||||
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))
|
||||
{
|
||||
printMsg(lvlInfo, format("uninstalling ‘%1%’") % i.name);
|
||||
|
|
|
@ -146,7 +146,7 @@ int main(int argc, char * * argv)
|
|||
Path storePath;
|
||||
if (args.size() == 2) {
|
||||
expectedHash = parseHash16or32(ht, args[1]);
|
||||
storePath = makeFixedOutputPath(unpack, ht, expectedHash, name);
|
||||
storePath = store->makeFixedOutputPath(unpack, ht, expectedHash, name);
|
||||
if (store->isValidPath(storePath))
|
||||
hash = expectedHash;
|
||||
else
|
||||
|
@ -197,7 +197,7 @@ int main(int argc, char * * argv)
|
|||
into the Nix store. */
|
||||
storePath = store->addToStore(name, tmpFile, unpack, ht);
|
||||
|
||||
assert(storePath == makeFixedOutputPath(unpack, ht, hash, name));
|
||||
assert(storePath == store->makeFixedOutputPath(unpack, ht, hash, name));
|
||||
}
|
||||
|
||||
if (!printPath)
|
||||
|
|
|
@ -124,7 +124,7 @@ static void opRealise(Strings opFlags, Strings opArgs)
|
|||
Paths paths;
|
||||
for (auto & i : opArgs) {
|
||||
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;
|
||||
|
@ -207,7 +207,7 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs)
|
|||
string name = *i++;
|
||||
|
||||
cout << format("%1%\n") %
|
||||
makeFixedOutputPath(recursive, hashAlgo,
|
||||
store->makeFixedOutputPath(recursive, hashAlgo,
|
||||
parseHash16or32(hashAlgo, hash), name);
|
||||
}
|
||||
|
||||
|
@ -315,7 +315,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
|
||||
case qOutputs: {
|
||||
for (auto & i : opArgs) {
|
||||
i = followLinksToStorePath(i);
|
||||
i = store->followLinksToStorePath(i);
|
||||
if (forceRealise) realisePath(i);
|
||||
Derivation drv = store->derivationFromPath(i);
|
||||
for (auto & j : drv.outputs)
|
||||
|
@ -330,7 +330,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
case qReferrersClosure: {
|
||||
PathSet paths;
|
||||
for (auto & i : opArgs) {
|
||||
PathSet ps = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise);
|
||||
PathSet ps = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise);
|
||||
for (auto & j : ps) {
|
||||
if (query == qRequisites) store->computeFSClosure(j, paths, false, includeOutputs);
|
||||
else if (query == qReferences) {
|
||||
|
@ -350,7 +350,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
|
||||
case qDeriver:
|
||||
for (auto & i : opArgs) {
|
||||
Path deriver = store->queryPathInfo(followLinksToStorePath(i))->deriver;
|
||||
Path deriver = store->queryPathInfo(store->followLinksToStorePath(i))->deriver;
|
||||
cout << format("%1%\n") %
|
||||
(deriver == "" ? "unknown-deriver" : deriver);
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
|
||||
case qBinding:
|
||||
for (auto & i : opArgs) {
|
||||
Path path = useDeriver(followLinksToStorePath(i));
|
||||
Path path = useDeriver(store->followLinksToStorePath(i));
|
||||
Derivation drv = store->derivationFromPath(path);
|
||||
StringPairs::iterator j = drv.env.find(bindingName);
|
||||
if (j == drv.env.end())
|
||||
|
@ -371,7 +371,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
case qHash:
|
||||
case qSize:
|
||||
for (auto & i : opArgs) {
|
||||
PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise);
|
||||
PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise);
|
||||
for (auto & j : paths) {
|
||||
auto info = store->queryPathInfo(j);
|
||||
if (query == qHash) {
|
||||
|
@ -386,14 +386,14 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
case qTree: {
|
||||
PathSet done;
|
||||
for (auto & i : opArgs)
|
||||
printTree(followLinksToStorePath(i), "", "", done);
|
||||
printTree(store->followLinksToStorePath(i), "", "", done);
|
||||
break;
|
||||
}
|
||||
|
||||
case qGraph: {
|
||||
PathSet roots;
|
||||
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());
|
||||
}
|
||||
printDotGraph(ref<Store>(store), roots);
|
||||
|
@ -403,7 +403,7 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
case qXml: {
|
||||
PathSet roots;
|
||||
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());
|
||||
}
|
||||
printXmlGraph(ref<Store>(store), roots);
|
||||
|
@ -412,14 +412,14 @@ static void opQuery(Strings opFlags, Strings opArgs)
|
|||
|
||||
case qResolve: {
|
||||
for (auto & i : opArgs)
|
||||
cout << format("%1%\n") % followLinksToStorePath(i);
|
||||
cout << format("%1%\n") % store->followLinksToStorePath(i);
|
||||
break;
|
||||
}
|
||||
|
||||
case qRoots: {
|
||||
PathSet referrers;
|
||||
for (auto & i : opArgs) {
|
||||
PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise);
|
||||
PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise);
|
||||
for (auto & j : paths)
|
||||
store->computeFSClosure(j, referrers, true,
|
||||
settings.gcKeepOutputs, settings.gcKeepDerivations);
|
||||
|
@ -479,7 +479,7 @@ static void opReadLog(Strings opFlags, Strings opArgs)
|
|||
RunPager pager;
|
||||
|
||||
for (auto & i : opArgs) {
|
||||
Path path = useDeriver(followLinksToStorePath(i));
|
||||
Path path = useDeriver(store->followLinksToStorePath(i));
|
||||
|
||||
string baseName = baseNameOf(path);
|
||||
bool found = false;
|
||||
|
@ -599,7 +599,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs)
|
|||
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||
|
||||
for (auto & i : opArgs) {
|
||||
Path path = followLinksToStorePath(i);
|
||||
Path path = store->followLinksToStorePath(i);
|
||||
if (!store->isValidPath(path)) {
|
||||
if (printInvalid)
|
||||
cout << format("%1%\n") % path;
|
||||
|
@ -662,7 +662,7 @@ static void opDelete(Strings opFlags, Strings opArgs)
|
|||
else throw UsageError(format("unknown flag ‘%1%’") % i);
|
||||
|
||||
for (auto & i : opArgs)
|
||||
options.pathsToDelete.insert(followLinksToStorePath(i));
|
||||
options.pathsToDelete.insert(store->followLinksToStorePath(i));
|
||||
|
||||
GCResults results;
|
||||
PrintFreed freed(true, results);
|
||||
|
@ -761,7 +761,7 @@ static void opVerifyPath(Strings opFlags, Strings opArgs)
|
|||
int status = 0;
|
||||
|
||||
for (auto & i : opArgs) {
|
||||
Path path = followLinksToStorePath(i);
|
||||
Path path = store->followLinksToStorePath(i);
|
||||
printMsg(lvlTalkative, format("checking path ‘%1%’...") % path);
|
||||
auto info = store->queryPathInfo(path);
|
||||
HashSink sink(info->narHash.type);
|
||||
|
@ -787,7 +787,7 @@ static void opRepairPath(Strings opFlags, Strings opArgs)
|
|||
throw UsageError("no flags expected");
|
||||
|
||||
for (auto & i : opArgs) {
|
||||
Path path = followLinksToStorePath(i);
|
||||
Path path = store->followLinksToStorePath(i);
|
||||
ensureLocalStore()->repairPath(path);
|
||||
}
|
||||
}
|
||||
|
@ -847,7 +847,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
|||
case cmdQueryValidPaths: {
|
||||
bool lock = readInt(in);
|
||||
bool substitute = readInt(in);
|
||||
PathSet paths = readStorePaths<PathSet>(in);
|
||||
PathSet paths = readStorePaths<PathSet>(*store, in);
|
||||
if (lock && writeAllowed)
|
||||
for (auto & path : paths)
|
||||
store->addTempRoot(path);
|
||||
|
@ -879,7 +879,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
|||
}
|
||||
|
||||
case cmdQueryPathInfos: {
|
||||
PathSet paths = readStorePaths<PathSet>(in);
|
||||
PathSet paths = readStorePaths<PathSet>(*store, in);
|
||||
// !!! Maybe we want a queryPathInfos?
|
||||
for (auto & i : paths) {
|
||||
try {
|
||||
|
@ -896,7 +896,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
|||
}
|
||||
|
||||
case cmdDumpStorePath:
|
||||
dumpPath(readStorePath(in), out);
|
||||
dumpPath(readStorePath(*store, in), out);
|
||||
break;
|
||||
|
||||
case cmdImportPaths: {
|
||||
|
@ -908,7 +908,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
|||
|
||||
case cmdExportPaths: {
|
||||
readInt(in); // obsolete
|
||||
Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(in));
|
||||
Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(*store, in));
|
||||
reverse(sorted.begin(), sorted.end());
|
||||
store->exportPaths(sorted, out);
|
||||
break;
|
||||
|
@ -917,7 +917,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
|||
case cmdBuildPaths: { /* Used by build-remote.pl. */
|
||||
|
||||
if (!writeAllowed) throw Error("building paths is not allowed");
|
||||
PathSet paths = readStorePaths<PathSet>(in);
|
||||
PathSet paths = readStorePaths<PathSet>(*store, in);
|
||||
|
||||
getBuildSettings();
|
||||
|
||||
|
@ -936,9 +936,9 @@ static void opServe(Strings opFlags, Strings opArgs)
|
|||
|
||||
if (!writeAllowed) throw Error("building paths is not allowed");
|
||||
|
||||
Path drvPath = readStorePath(in); // informational only
|
||||
Path drvPath = readStorePath(*store, in); // informational only
|
||||
BasicDerivation drv;
|
||||
in >> drv;
|
||||
readDerivation(in, *store, drv);
|
||||
|
||||
getBuildSettings();
|
||||
|
||||
|
@ -952,7 +952,7 @@ static void opServe(Strings opFlags, Strings opArgs)
|
|||
|
||||
case cmdQueryClosure: {
|
||||
bool includeOutputs = readInt(in);
|
||||
PathSet paths = readStorePaths<PathSet>(in);
|
||||
PathSet paths = readStorePaths<PathSet>(*store, in);
|
||||
PathSet closure;
|
||||
for (auto & i : paths)
|
||||
store->computeFSClosure(i, closure, false, includeOutputs);
|
||||
|
|
|
@ -102,7 +102,7 @@ void StorePathsCommand::run(ref<Store> store)
|
|||
|
||||
else {
|
||||
for (auto & storePath : storePaths)
|
||||
storePath = followLinksToStorePath(storePath);
|
||||
storePath = store->followLinksToStorePath(storePath);
|
||||
|
||||
if (recursive) {
|
||||
PathSet closure;
|
||||
|
|
|
@ -17,7 +17,7 @@ UserEnvElems MixInstallables::evalInstallables(ref<Store> store)
|
|||
|
||||
if (std::string(installable, 0, 1) == "/") {
|
||||
|
||||
if (isStorePath(installable)) {
|
||||
if (store->isStorePath(installable)) {
|
||||
|
||||
if (isDerivation(installable)) {
|
||||
UserEnvElem elem;
|
||||
|
|
Loading…
Reference in a new issue