diff options
Diffstat (limited to 'src/nix-store/nix-store.cc')
-rw-r--r-- | src/nix-store/nix-store.cc | 514 |
1 files changed, 249 insertions, 265 deletions
diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 23b97ca9e5aa..0038fff036a1 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -1,14 +1,15 @@ -#include "globals.hh" -#include "misc.hh" #include "archive.hh" -#include "shared.hh" +#include "derivations.hh" #include "dotgraph.hh" -#include "xmlgraph.hh" +#include "globals.hh" #include "local-store.hh" -#include "util.hh" +#include "monitor-fd.hh" #include "serve-protocol.hh" +#include "shared.hh" +#include "util.hh" #include "worker-protocol.hh" -#include "monitor-fd.hh" +#include "xmlgraph.hh" +#include "compression.hh" #include <iostream> #include <algorithm> @@ -18,8 +19,6 @@ #include <sys/stat.h> #include <fcntl.h> -#include <bzlib.h> - #if HAVE_SODIUM #include <sodium.h> #endif @@ -37,20 +36,21 @@ static Path gcRoot; static int rootNr = 0; static bool indirectRoot = false; static bool noOutput = false; +static std::shared_ptr<Store> store; -LocalStore & ensureLocalStore() +ref<LocalStore> ensureLocalStore() { - LocalStore * store2(dynamic_cast<LocalStore *>(store.get())); + auto store2 = std::dynamic_pointer_cast<LocalStore>(store); if (!store2) throw Error("you don't have sufficient rights to use this command"); - return *store2; + return ref<LocalStore>(store2); } static Path useDeriver(Path path) { if (isDerivation(path)) return path; - Path drvPath = store->queryDeriver(path); + Path drvPath = store->queryPathInfo(path)->deriver; if (drvPath == "") throw Error(format("deriver of path ‘%1%’ is not known") % path); return drvPath; @@ -64,26 +64,26 @@ static PathSet realisePath(Path path, bool build = true) DrvPathWithOutputs p = parseDrvPathWithOutputs(path); if (isDerivation(p.first)) { - if (build) store->buildPaths(singleton<PathSet>(path)); - Derivation drv = derivationFromPath(*store, p.first); + if (build) store->buildPaths({path}); + Derivation drv = store->derivationFromPath(p.first); rootNr++; if (p.second.empty()) - foreach (DerivationOutputs::iterator, i, drv.outputs) p.second.insert(i->first); + for (auto & i : drv.outputs) p.second.insert(i.first); PathSet outputs; - foreach (StringSet::iterator, j, p.second) { - DerivationOutputs::iterator i = drv.outputs.find(*j); + for (auto & j : p.second) { + DerivationOutputs::iterator i = drv.outputs.find(j); if (i == drv.outputs.end()) - throw Error(format("derivation ‘%1%’ does not have an output named ‘%2%’") % p.first % *j); + throw Error(format("derivation ‘%1%’ does not have an output named ‘%2%’") % p.first % j); Path outPath = i->second.path; if (gcRoot == "") printGCWarning(); else { Path rootName = gcRoot; - if (rootNr > 1) rootName += "-" + int2String(rootNr); + if (rootNr > 1) rootName += "-" + std::to_string(rootNr); if (i->first != "out") rootName += "-" + i->first; - outPath = addPermRoot(*store, outPath, rootName, indirectRoot); + outPath = store->addPermRoot(outPath, rootName, indirectRoot); } outputs.insert(outPath); } @@ -98,10 +98,10 @@ static PathSet realisePath(Path path, bool build = true) else { Path rootName = gcRoot; rootNr++; - if (rootNr > 1) rootName += "-" + int2String(rootNr); - path = addPermRoot(*store, path, rootName, indirectRoot); + if (rootNr > 1) rootName += "-" + std::to_string(rootNr); + path = store->addPermRoot(path, rootName, indirectRoot); } - return singleton<PathSet>(path); + return {path}; } } @@ -113,34 +113,35 @@ static void opRealise(Strings opFlags, Strings opArgs) BuildMode buildMode = bmNormal; bool ignoreUnknown = false; - foreach (Strings::iterator, i, opFlags) - if (*i == "--dry-run") dryRun = true; - else if (*i == "--repair") buildMode = bmRepair; - else if (*i == "--check") buildMode = bmCheck; - else if (*i == "--ignore-unknown") ignoreUnknown = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + if (i == "--dry-run") dryRun = true; + else if (i == "--repair") buildMode = bmRepair; + else if (i == "--check") buildMode = bmCheck; + else if (i == "--hash") buildMode = bmHash; + else if (i == "--ignore-unknown") ignoreUnknown = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); Paths paths; - foreach (Strings::iterator, i, opArgs) { - DrvPathWithOutputs p = parseDrvPathWithOutputs(*i); + for (auto & i : opArgs) { + DrvPathWithOutputs p = parseDrvPathWithOutputs(i); paths.push_back(makeDrvPathWithOutputs(followLinksToStorePath(p.first), p.second)); } unsigned long long downloadSize, narSize; PathSet willBuild, willSubstitute, unknown; - queryMissing(*store, PathSet(paths.begin(), paths.end()), + store->queryMissing(PathSet(paths.begin(), paths.end()), willBuild, willSubstitute, unknown, downloadSize, narSize); if (ignoreUnknown) { Paths paths2; - foreach (Paths::iterator, i, paths) - if (unknown.find(*i) == unknown.end()) paths2.push_back(*i); + for (auto & i : paths) + if (unknown.find(i) == unknown.end()) paths2.push_back(i); paths = paths2; unknown = PathSet(); } if (settings.get("print-missing", true)) - printMissing(willBuild, willSubstitute, unknown, downloadSize, narSize); + printMissing(ref<Store>(store), willBuild, willSubstitute, unknown, downloadSize, narSize); if (dryRun) return; @@ -148,11 +149,11 @@ static void opRealise(Strings opFlags, Strings opArgs) store->buildPaths(PathSet(paths.begin(), paths.end()), buildMode); if (!ignoreUnknown) - foreach (Paths::iterator, i, paths) { - PathSet paths = realisePath(*i, false); + for (auto & i : paths) { + PathSet paths = realisePath(i, false); if (!noOutput) - foreach (PathSet::iterator, j, paths) - cout << format("%1%\n") % *j; + for (auto & j : paths) + cout << format("%1%\n") % j; } } @@ -173,10 +174,9 @@ static void opAddFixed(Strings opFlags, Strings opArgs) { bool recursive = false; - for (Strings::iterator i = opFlags.begin(); - i != opFlags.end(); ++i) - if (*i == "--recursive") recursive = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + if (i == "--recursive") recursive = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); if (opArgs.empty()) throw UsageError("first argument must be hash algorithm"); @@ -194,10 +194,9 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs) { bool recursive = false; - for (Strings::iterator i = opFlags.begin(); - i != opFlags.end(); ++i) - if (*i == "--recursive") recursive = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto i : opFlags) + if (i == "--recursive") recursive = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); if (opArgs.size() != 3) throw UsageError(format("‘--print-fixed-path’ requires three arguments")); @@ -217,13 +216,13 @@ static PathSet maybeUseOutputs(const Path & storePath, bool useOutput, bool forc { if (forceRealise) realisePath(storePath); if (useOutput && isDerivation(storePath)) { - Derivation drv = derivationFromPath(*store, storePath); + Derivation drv = store->derivationFromPath(storePath); PathSet outputs; - foreach (DerivationOutputs::iterator, i, drv.outputs) - outputs.insert(i->second.path); + for (auto & i : drv.outputs) + outputs.insert(i.second.path); return outputs; } - else return singleton<PathSet>(storePath); + else return {storePath}; } @@ -247,18 +246,17 @@ static void printTree(const Path & path, cout << format("%1%%2%\n") % firstPad % path; - PathSet references; - store->queryReferences(path, references); + auto references = store->queryPathInfo(path)->references; /* Topologically sort under the relation A < B iff A \in closure(B). That is, if derivation A is an (possibly indirect) input of B, then A is printed first. This has the effect of flattening the tree, preventing deeply nested structures. */ - Paths sorted = topoSortPaths(*store, references); + Paths sorted = store->topoSortPaths(references); reverse(sorted.begin(), sorted.end()); - foreach (Paths::iterator, i, sorted) { - Paths::iterator j = i; ++j; + for (auto i = sorted.begin(); i != sorted.end(); ++i) { + auto j = i; ++j; printTree(*i, tailPad + treeConn, j == sorted.end() ? tailPad + treeNull : tailPad + treeLine, done); @@ -279,34 +277,34 @@ static void opQuery(Strings opFlags, Strings opArgs) bool forceRealise = false; string bindingName; - foreach (Strings::iterator, i, opFlags) { + for (auto & i : opFlags) { QueryType prev = query; - if (*i == "--outputs") query = qOutputs; - else if (*i == "--requisites" || *i == "-R") query = qRequisites; - else if (*i == "--references") query = qReferences; - else if (*i == "--referrers" || *i == "--referers") query = qReferrers; - else if (*i == "--referrers-closure" || *i == "--referers-closure") query = qReferrersClosure; - else if (*i == "--deriver" || *i == "-d") query = qDeriver; - else if (*i == "--binding" || *i == "-b") { + if (i == "--outputs") query = qOutputs; + else if (i == "--requisites" || i == "-R") query = qRequisites; + else if (i == "--references") query = qReferences; + else if (i == "--referrers" || i == "--referers") query = qReferrers; + else if (i == "--referrers-closure" || i == "--referers-closure") query = qReferrersClosure; + else if (i == "--deriver" || i == "-d") query = qDeriver; + else if (i == "--binding" || i == "-b") { if (opArgs.size() == 0) throw UsageError("expected binding name"); bindingName = opArgs.front(); opArgs.pop_front(); query = qBinding; } - else if (*i == "--hash") query = qHash; - else if (*i == "--size") query = qSize; - else if (*i == "--tree") query = qTree; - else if (*i == "--graph") query = qGraph; - else if (*i == "--xml") query = qXml; - else if (*i == "--resolve") query = qResolve; - else if (*i == "--roots") query = qRoots; - else if (*i == "--use-output" || *i == "-u") useOutput = true; - else if (*i == "--force-realise" || *i == "--force-realize" || *i == "-f") forceRealise = true; - else if (*i == "--include-outputs") includeOutputs = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + else if (i == "--hash") query = qHash; + else if (i == "--size") query = qSize; + else if (i == "--tree") query = qTree; + else if (i == "--graph") query = qGraph; + else if (i == "--xml") query = qXml; + else if (i == "--resolve") query = qResolve; + else if (i == "--roots") query = qRoots; + else if (i == "--use-output" || i == "-u") useOutput = true; + else if (i == "--force-realise" || i == "--force-realize" || i == "-f") forceRealise = true; + else if (i == "--include-outputs") includeOutputs = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); if (prev != qDefault && prev != query) - throw UsageError(format("query type ‘%1%’ conflicts with earlier flag") % *i); + throw UsageError(format("query type ‘%1%’ conflicts with earlier flag") % i); } if (query == qDefault) query = qOutputs; @@ -316,12 +314,12 @@ static void opQuery(Strings opFlags, Strings opArgs) switch (query) { case qOutputs: { - foreach (Strings::iterator, i, opArgs) { - *i = followLinksToStorePath(*i); - if (forceRealise) realisePath(*i); - Derivation drv = derivationFromPath(*store, *i); - foreach (DerivationOutputs::iterator, j, drv.outputs) - cout << format("%1%\n") % j->second.path; + for (auto & i : opArgs) { + i = followLinksToStorePath(i); + if (forceRealise) realisePath(i); + Derivation drv = store->derivationFromPath(i); + for (auto & j : drv.outputs) + cout << format("%1%\n") % j.second.path; } break; } @@ -331,16 +329,19 @@ static void opQuery(Strings opFlags, Strings opArgs) case qReferrers: case qReferrersClosure: { PathSet paths; - foreach (Strings::iterator, i, opArgs) { - PathSet ps = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise); - foreach (PathSet::iterator, j, ps) { - if (query == qRequisites) computeFSClosure(*store, *j, paths, false, includeOutputs); - else if (query == qReferences) store->queryReferences(*j, paths); - else if (query == qReferrers) store->queryReferrers(*j, paths); - else if (query == qReferrersClosure) computeFSClosure(*store, *j, paths, true); + for (auto & i : opArgs) { + PathSet ps = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); + for (auto & j : ps) { + if (query == qRequisites) store->computeFSClosure(j, paths, false, includeOutputs); + else if (query == qReferences) { + for (auto & p : store->queryPathInfo(j)->references) + paths.insert(p); + } + else if (query == qReferrers) store->queryReferrers(j, paths); + else if (query == qReferrersClosure) store->computeFSClosure(j, paths, true); } } - Paths sorted = topoSortPaths(*store, paths); + Paths sorted = store->topoSortPaths(paths); for (Paths::reverse_iterator i = sorted.rbegin(); i != sorted.rend(); ++i) cout << format("%s\n") % *i; @@ -348,17 +349,17 @@ static void opQuery(Strings opFlags, Strings opArgs) } case qDeriver: - foreach (Strings::iterator, i, opArgs) { - Path deriver = store->queryDeriver(followLinksToStorePath(*i)); + for (auto & i : opArgs) { + Path deriver = store->queryPathInfo(followLinksToStorePath(i))->deriver; cout << format("%1%\n") % (deriver == "" ? "unknown-deriver" : deriver); } break; case qBinding: - foreach (Strings::iterator, i, opArgs) { - Path path = useDeriver(followLinksToStorePath(*i)); - Derivation drv = derivationFromPath(*store, path); + for (auto & i : opArgs) { + Path path = useDeriver(followLinksToStorePath(i)); + Derivation drv = store->derivationFromPath(path); StringPairs::iterator j = drv.env.find(bindingName); if (j == drv.env.end()) throw Error(format("derivation ‘%1%’ has no environment binding named ‘%2%’") @@ -369,64 +370,64 @@ static void opQuery(Strings opFlags, Strings opArgs) case qHash: case qSize: - foreach (Strings::iterator, i, opArgs) { - PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise); - foreach (PathSet::iterator, j, paths) { - ValidPathInfo info = store->queryPathInfo(*j); + for (auto & i : opArgs) { + PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); + for (auto & j : paths) { + auto info = store->queryPathInfo(j); if (query == qHash) { - assert(info.hash.type == htSHA256); - cout << format("sha256:%1%\n") % printHash32(info.hash); + assert(info->narHash.type == htSHA256); + cout << format("sha256:%1%\n") % printHash32(info->narHash); } else if (query == qSize) - cout << format("%1%\n") % info.narSize; + cout << format("%1%\n") % info->narSize; } } break; case qTree: { PathSet done; - foreach (Strings::iterator, i, opArgs) - printTree(followLinksToStorePath(*i), "", "", done); + for (auto & i : opArgs) + printTree(followLinksToStorePath(i), "", "", done); break; } case qGraph: { PathSet roots; - foreach (Strings::iterator, i, opArgs) { - PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise); + for (auto & i : opArgs) { + PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); roots.insert(paths.begin(), paths.end()); } - printDotGraph(roots); + printDotGraph(ref<Store>(store), roots); break; } case qXml: { PathSet roots; - foreach (Strings::iterator, i, opArgs) { - PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise); + for (auto & i : opArgs) { + PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); roots.insert(paths.begin(), paths.end()); } - printXmlGraph(roots); + printXmlGraph(ref<Store>(store), roots); break; } case qResolve: { - foreach (Strings::iterator, i, opArgs) - cout << format("%1%\n") % followLinksToStorePath(*i); + for (auto & i : opArgs) + cout << format("%1%\n") % followLinksToStorePath(i); break; } case qRoots: { PathSet referrers; - foreach (Strings::iterator, i, opArgs) { - PathSet paths = maybeUseOutputs(followLinksToStorePath(*i), useOutput, forceRealise); - foreach (PathSet::iterator, j, paths) - computeFSClosure(*store, *j, referrers, true, + for (auto & i : opArgs) { + PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); + for (auto & j : paths) + store->computeFSClosure(j, referrers, true, settings.gcKeepOutputs, settings.gcKeepDerivations); } Roots roots = store->findRoots(); - foreach (Roots::iterator, i, roots) - if (referrers.find(i->second) != referrers.end()) - cout << format("%1%\n") % i->first; + for (auto & i : roots) + if (referrers.find(i.second) != referrers.end()) + cout << format("%1%\n") % i.first; break; } @@ -439,8 +440,8 @@ static void opQuery(Strings opFlags, Strings opArgs) static string shellEscape(const string & s) { string r; - foreach (string::const_iterator, i, s) - if (*i == '\'') r += "'\\''"; else r += *i; + for (auto & i : s) + if (i == '\'') r += "'\\''"; else r += i; return r; } @@ -451,19 +452,21 @@ static void opPrintEnv(Strings opFlags, Strings opArgs) if (opArgs.size() != 1) throw UsageError("‘--print-env’ requires one derivation store path"); Path drvPath = opArgs.front(); - Derivation drv = derivationFromPath(*store, drvPath); + Derivation drv = store->derivationFromPath(drvPath); /* Print each environment variable in the derivation in a format that can be sourced by the shell. */ - foreach (StringPairs::iterator, i, drv.env) - cout << format("export %1%; %1%='%2%'\n") % i->first % shellEscape(i->second); + for (auto & i : drv.env) + cout << format("export %1%; %1%='%2%'\n") % i.first % shellEscape(i.second); /* Also output the arguments. This doesn't preserve whitespace in arguments. */ cout << "export _args; _args='"; - foreach (Strings::iterator, i, drv.args) { - if (i != drv.args.begin()) cout << ' '; - cout << shellEscape(*i); + bool first = true; + for (auto & i : drv.args) { + if (!first) cout << ' '; + first = false; + cout << shellEscape(i); } cout << "'\n"; } @@ -475,8 +478,8 @@ static void opReadLog(Strings opFlags, Strings opArgs) RunPager pager; - foreach (Strings::iterator, i, opArgs) { - Path path = useDeriver(followLinksToStorePath(*i)); + for (auto & i : opArgs) { + Path path = useDeriver(followLinksToStorePath(i)); string baseName = baseNameOf(path); bool found = false; @@ -498,21 +501,7 @@ static void opReadLog(Strings opFlags, Strings opArgs) } else if (pathExists(logBz2Path)) { - AutoCloseFD fd = open(logBz2Path.c_str(), O_RDONLY); - FILE * f = 0; - if (fd == -1 || (f = fdopen(fd.borrow(), "r")) == 0) - throw SysError(format("opening file ‘%1%’") % logBz2Path); - int err; - BZFILE * bz = BZ2_bzReadOpen(&err, f, 0, 0, 0, 0); - if (!bz) throw Error(format("cannot open bzip2 file ‘%1%’") % logBz2Path); - unsigned char buf[128 * 1024]; - do { - int n = BZ2_bzRead(&err, bz, buf, sizeof(buf)); - if (err != BZ_OK && err != BZ_STREAM_END) - throw Error(format("error reading bzip2 file ‘%1%’") % logBz2Path); - writeFull(STDOUT_FILENO, buf, n); - } while (err != BZ_STREAM_END); - BZ2_bzReadClose(&err, bz); + std::cout << *decompress("bzip2", readFile(logBz2Path)); found = true; break; } @@ -547,8 +536,8 @@ static void opDumpDB(Strings opFlags, Strings opArgs) if (!opArgs.empty()) throw UsageError("no arguments expected"); PathSet validPaths = store->queryAllValidPaths(); - foreach (PathSet::iterator, i, validPaths) - cout << store->makeValidityRegistration(singleton<PathSet>(*i), true, true); + for (auto & i : validPaths) + cout << store->makeValidityRegistration({i}, true, true); } @@ -565,14 +554,14 @@ static void registerValidity(bool reregister, bool hashGiven, bool canonicalise) canonicalisePathMetaData(info.path, -1); if (!hashGiven) { HashResult hash = hashPath(htSHA256, info.path); - info.hash = hash.first; + info.narHash = hash.first; info.narSize = hash.second; } infos.push_back(info); } } - ensureLocalStore().registerValidPaths(infos); + ensureLocalStore()->registerValidPaths(infos); } @@ -590,11 +579,10 @@ static void opRegisterValidity(Strings opFlags, Strings opArgs) bool reregister = false; // !!! maybe this should be the default bool hashGiven = false; - for (Strings::iterator i = opFlags.begin(); - i != opFlags.end(); ++i) - if (*i == "--reregister") reregister = true; - else if (*i == "--hash-given") hashGiven = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + if (i == "--reregister") reregister = true; + else if (i == "--hash-given") hashGiven = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); if (!opArgs.empty()) throw UsageError("no arguments expected"); @@ -606,15 +594,12 @@ static void opCheckValidity(Strings opFlags, Strings opArgs) { bool printInvalid = false; - for (Strings::iterator i = opFlags.begin(); - i != opFlags.end(); ++i) - if (*i == "--print-invalid") printInvalid = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + if (i == "--print-invalid") printInvalid = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); - for (Strings::iterator i = opArgs.begin(); - i != opArgs.end(); ++i) - { - Path path = followLinksToStorePath(*i); + for (auto & i : opArgs) { + Path path = followLinksToStorePath(i); if (!store->isValidPath(path)) { if (printInvalid) cout << format("%1%\n") % path; @@ -634,7 +619,7 @@ static void opGC(Strings opFlags, Strings opArgs) GCResults results; /* Do what? */ - foreach (Strings::iterator, i, opFlags) + for (auto i = opFlags.begin(); i != opFlags.end(); ++i) if (*i == "--print-roots") printRoots = true; else if (*i == "--print-live") options.action = GCOptions::gcReturnLive; else if (*i == "--print-dead") options.action = GCOptions::gcReturnDead; @@ -649,8 +634,8 @@ static void opGC(Strings opFlags, Strings opArgs) if (printRoots) { Roots roots = store->findRoots(); - foreach (Roots::iterator, i, roots) - cout << i->first << " -> " << i->second << std::endl; + for (auto & i : roots) + cout << i.first << " -> " << i.second << std::endl; } else { @@ -658,8 +643,8 @@ static void opGC(Strings opFlags, Strings opArgs) store->collectGarbage(options, results); if (options.action != GCOptions::gcDeleteDead) - foreach (PathSet::iterator, i, results.paths) - cout << *i << std::endl; + for (auto & i : results.paths) + cout << i << std::endl; } } @@ -672,12 +657,12 @@ static void opDelete(Strings opFlags, Strings opArgs) GCOptions options; options.action = GCOptions::gcDeleteSpecific; - foreach (Strings::iterator, i, opFlags) - if (*i == "--ignore-liveness") options.ignoreLiveness = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + if (i == "--ignore-liveness") options.ignoreLiveness = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); - foreach (Strings::iterator, i, opArgs) - options.pathsToDelete.insert(followLinksToStorePath(*i)); + for (auto & i : opArgs) + options.pathsToDelete.insert(followLinksToStorePath(i)); GCResults results; PrintFreed freed(true, results); @@ -712,33 +697,26 @@ static void opRestore(Strings opFlags, Strings opArgs) static void opExport(Strings opFlags, Strings opArgs) { - bool sign = false; - for (Strings::iterator i = opFlags.begin(); - i != opFlags.end(); ++i) - if (*i == "--sign") sign = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + throw UsageError(format("unknown flag ‘%1%’") % i); FdSink sink(STDOUT_FILENO); - Paths sorted = topoSortPaths(*store, PathSet(opArgs.begin(), opArgs.end())); - reverse(sorted.begin(), sorted.end()); - exportPaths(*store, sorted, sign, sink); + store->exportPaths(opArgs, sink); } static void opImport(Strings opFlags, Strings opArgs) { - bool requireSignature = false; - foreach (Strings::iterator, i, opFlags) - if (*i == "--require-signature") requireSignature = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + throw UsageError(format("unknown flag ‘%1%’") % i); if (!opArgs.empty()) throw UsageError("no arguments expected"); FdSource source(STDIN_FILENO); - Paths paths = store->importPaths(requireSignature, source); + Paths paths = store->importPaths(source, 0); - foreach (Paths::iterator, i, paths) - cout << format("%1%\n") % *i << std::flush; + for (auto & i : paths) + cout << format("%1%\n") % i << std::flush; } @@ -762,11 +740,10 @@ static void opVerify(Strings opFlags, Strings opArgs) bool checkContents = false; bool repair = false; - for (Strings::iterator i = opFlags.begin(); - i != opFlags.end(); ++i) - if (*i == "--check-contents") checkContents = true; - else if (*i == "--repair") repair = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + if (i == "--check-contents") checkContents = true; + else if (i == "--repair") repair = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); if (store->verifyStore(checkContents, repair)) { printMsg(lvlError, "warning: not all errors were fixed"); @@ -783,15 +760,17 @@ static void opVerifyPath(Strings opFlags, Strings opArgs) int status = 0; - foreach (Strings::iterator, i, opArgs) { - Path path = followLinksToStorePath(*i); + for (auto & i : opArgs) { + Path path = followLinksToStorePath(i); printMsg(lvlTalkative, format("checking path ‘%1%’...") % path); - ValidPathInfo info = store->queryPathInfo(path); - HashResult current = hashPath(info.hash.type, path); - if (current.first != info.hash) { + auto info = store->queryPathInfo(path); + HashSink sink(info->narHash.type); + store->narFromPath(path, sink); + auto current = sink.finish(); + if (current.first != info->narHash) { printMsg(lvlError, format("path ‘%1%’ was modified! expected hash ‘%2%’, got ‘%3%’") - % path % printHash(info.hash) % printHash(current.first)); + % path % printHash(info->narHash) % printHash(current.first)); status = 1; } } @@ -807,9 +786,9 @@ static void opRepairPath(Strings opFlags, Strings opArgs) if (!opFlags.empty()) throw UsageError("no flags expected"); - foreach (Strings::iterator, i, opArgs) { - Path path = followLinksToStorePath(*i); - ensureLocalStore().repairPath(path); + for (auto & i : opArgs) { + Path path = followLinksToStorePath(i); + ensureLocalStore()->repairPath(path); } } @@ -823,31 +802,13 @@ static void opOptimise(Strings opFlags, Strings opArgs) store->optimiseStore(); } -static void opQueryFailedPaths(Strings opFlags, Strings opArgs) -{ - if (!opArgs.empty() || !opFlags.empty()) - throw UsageError("no arguments expected"); - PathSet failed = store->queryFailedPaths(); - foreach (PathSet::iterator, i, failed) - cout << format("%1%\n") % *i; -} - - -static void opClearFailedPaths(Strings opFlags, Strings opArgs) -{ - if (!opFlags.empty()) - throw UsageError("no flags expected"); - store->clearFailedPaths(PathSet(opArgs.begin(), opArgs.end())); -} - - /* Serve the nix store in a way usable by a restricted ssh user. */ static void opServe(Strings opFlags, Strings opArgs) { bool writeAllowed = false; - foreach (Strings::iterator, i, opFlags) - if (*i == "--write") writeAllowed = true; - else throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + if (i == "--write") writeAllowed = true; + else throw UsageError(format("unknown flag ‘%1%’") % i); if (!opArgs.empty()) throw UsageError("no arguments expected"); @@ -857,10 +818,21 @@ static void opServe(Strings opFlags, Strings opArgs) /* Exchange the greeting. */ unsigned int magic = readInt(in); if (magic != SERVE_MAGIC_1) throw Error("protocol mismatch"); - writeInt(SERVE_MAGIC_2, out); - writeInt(SERVE_PROTOCOL_VERSION, out); + out << SERVE_MAGIC_2 << SERVE_PROTOCOL_VERSION; out.flush(); - readInt(in); // Client version, unused for now + unsigned int clientVersion = readInt(in); + + auto getBuildSettings = [&]() { + // FIXME: changing options here doesn't work if we're + // building through the daemon. + verbosity = lvlError; + settings.keepLog = false; + settings.useSubstitutes = false; + settings.maxSilentTime = readInt(in); + settings.buildTimeout = readInt(in); + if (GET_PROTOCOL_MINOR(clientVersion) >= 2) + settings.maxLogSize = readInt(in); + }; while (true) { ServeCommand cmd; @@ -890,7 +862,7 @@ static void opServe(Strings opFlags, Strings opArgs) if (!isDerivation(path)) paths2.insert(path); unsigned long long downloadSize, narSize; PathSet willBuild, willSubstitute, unknown; - queryMissing(*store, PathSet(paths2.begin(), paths2.end()), + store->queryMissing(PathSet(paths2.begin(), paths2.end()), willBuild, willSubstitute, unknown, downloadSize, narSize); /* FIXME: should use ensurePath(), but it only does one path at a time. */ @@ -902,25 +874,24 @@ static void opServe(Strings opFlags, Strings opArgs) } } - writeStrings(store->queryValidPaths(paths), out); + out << store->queryValidPaths(paths); break; } case cmdQueryPathInfos: { PathSet paths = readStorePaths<PathSet>(in); // !!! Maybe we want a queryPathInfos? - foreach (PathSet::iterator, i, paths) { - if (!store->isValidPath(*i)) - continue; - ValidPathInfo info = store->queryPathInfo(*i); - writeString(info.path, out); - writeString(info.deriver, out); - writeStrings(info.references, out); - // !!! Maybe we want compression? - writeLongLong(info.narSize, out); // downloadSize - writeLongLong(info.narSize, out); + for (auto & i : paths) { + try { + auto info = store->queryPathInfo(i); + out << info->path << info->deriver << info->references; + // !!! Maybe we want compression? + out << info->narSize // downloadSize + << info->narSize; + } catch (InvalidPath &) { + } } - writeString("", out); + out << ""; break; } @@ -930,52 +901,62 @@ static void opServe(Strings opFlags, Strings opArgs) case cmdImportPaths: { if (!writeAllowed) throw Error("importing paths is not allowed"); - store->importPaths(false, in); - writeInt(1, out); // indicate success + store->importPaths(in, 0); + out << 1; // indicate success break; } case cmdExportPaths: { - bool sign = readInt(in); - Paths sorted = topoSortPaths(*store, readStorePaths<PathSet>(in)); + readInt(in); // obsolete + Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(in)); reverse(sorted.begin(), sorted.end()); - exportPaths(*store, sorted, sign, out); + store->exportPaths(sorted, out); break; } - case cmdBuildPaths: { + case cmdBuildPaths: { /* Used by build-remote.pl. */ - /* Used by build-remote.pl. */ if (!writeAllowed) throw Error("building paths is not allowed"); PathSet paths = readStorePaths<PathSet>(in); - // FIXME: changing options here doesn't work if we're - // building through the daemon. - verbosity = lvlError; - settings.keepLog = false; - settings.useSubstitutes = false; - settings.maxSilentTime = readInt(in); - settings.buildTimeout = readInt(in); + getBuildSettings(); try { MonitorFdHup monitor(in.fd); store->buildPaths(paths); - writeInt(0, out); + out << 0; } catch (Error & e) { assert(e.status); - writeInt(e.status, out); - writeString(e.msg(), out); + out << e.status << e.msg(); } break; } + case cmdBuildDerivation: { /* Used by hydra-queue-runner. */ + + if (!writeAllowed) throw Error("building paths is not allowed"); + + Path drvPath = readStorePath(in); // informational only + BasicDerivation drv; + in >> drv; + + getBuildSettings(); + + MonitorFdHup monitor(in.fd); + auto status = store->buildDerivation(drvPath, drv); + + out << status.status << status.errorMsg; + + break; + } + case cmdQueryClosure: { bool includeOutputs = readInt(in); PathSet paths = readStorePaths<PathSet>(in); PathSet closure; for (auto & i : paths) - computeFSClosure(*store, i, closure, false, includeOutputs); - writeStrings(closure, out); + store->computeFSClosure(i, closure, false, includeOutputs); + out << closure; break; } @@ -990,8 +971,8 @@ static void opServe(Strings opFlags, Strings opArgs) static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs) { - foreach (Strings::iterator, i, opFlags) - throw UsageError(format("unknown flag ‘%1%’") % *i); + for (auto & i : opFlags) + throw UsageError(format("unknown flag ‘%1%’") % i); if (opArgs.size() != 3) throw UsageError("three arguments expected"); auto i = opArgs.begin(); @@ -1000,7 +981,8 @@ static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs) string publicKeyFile = *i++; #if HAVE_SODIUM - sodium_init(); + if (sodium_init() == -1) + throw Error("could not initialise libsodium"); unsigned char pk[crypto_sign_PUBLICKEYBYTES]; unsigned char sk[crypto_sign_SECRETKEYBYTES]; @@ -1016,6 +998,12 @@ static void opGenerateBinaryCacheKey(Strings opFlags, Strings opArgs) } +static void opVersion(Strings opFlags, Strings opArgs) +{ + printVersion("nix-store"); +} + + /* Scan the arguments; find the operation, set global flags, put all other flags in a list, and put all other arguments in another list. */ @@ -1033,7 +1021,7 @@ int main(int argc, char * * argv) if (*arg == "--help") showManPage("nix-store"); else if (*arg == "--version") - printVersion("nix-store"); + op = opVersion; else if (*arg == "--realise" || *arg == "--realize" || *arg == "-r") op = opRealise; else if (*arg == "--add" || *arg == "-A") @@ -1078,10 +1066,6 @@ int main(int argc, char * * argv) op = opRepairPath; else if (*arg == "--optimise" || *arg == "--optimize") op = opOptimise; - else if (*arg == "--query-failed-paths") - op = opQueryFailedPaths; - else if (*arg == "--clear-failed-paths") - op = opClearFailedPaths; else if (*arg == "--serve") op = opServe; else if (*arg == "--generate-binary-cache-key") @@ -1109,7 +1093,7 @@ int main(int argc, char * * argv) if (!op) throw UsageError("no operation specified"); if (op != opDump && op != opRestore) /* !!! hack */ - store = openStore(op != opGC); + store = openStore(); op(opFlags, opArgs); }); |