Replace a few bool flags with enums

Functions like copyClosure() had 3 bool arguments, which creates a
severe risk of mixing up arguments.

Also, implement copyClosure() using copyPaths().
This commit is contained in:
Eelco Dolstra 2017-06-28 18:11:01 +02:00
parent 90da34e421
commit fcca702a96
No known key found for this signature in database
GPG key ID: 8170B4726D7198DE
22 changed files with 144 additions and 147 deletions

View file

@ -201,7 +201,7 @@ connected:
printError("somebody is hogging the upload lock for %s, continuing..."); printError("somebody is hogging the upload lock for %s, continuing...");
alarm(0); alarm(0);
signal(SIGALRM, old); signal(SIGALRM, old);
copyPaths(store, ref<Store>(sshStore), inputs, false, true); copyPaths(store, ref<Store>(sshStore), inputs, NoRepair, NoCheckSigs);
uploadLock = -1; uploadLock = -1;
BasicDerivation drv(readDerivation(drvPath)); BasicDerivation drv(readDerivation(drvPath));
@ -219,7 +219,7 @@ connected:
if (!missing.empty()) { if (!missing.empty()) {
setenv("NIX_HELD_LOCKS", concatStringsSep(" ", missing).c_str(), 1); /* FIXME: ugly */ setenv("NIX_HELD_LOCKS", concatStringsSep(" ", missing).c_str(), 1); /* FIXME: ugly */
copyPaths(ref<Store>(sshStore), store, missing, false, true); copyPaths(ref<Store>(sshStore), store, missing, NoRepair, NoCheckSigs);
} }
return; return;

View file

@ -293,6 +293,7 @@ EvalState::EvalState(const Strings & _searchPath, ref<Store> store)
, sWrong(symbols.create("wrong")) , sWrong(symbols.create("wrong"))
, sStructuredAttrs(symbols.create("__structuredAttrs")) , sStructuredAttrs(symbols.create("__structuredAttrs"))
, sBuilder(symbols.create("builder")) , sBuilder(symbols.create("builder"))
, repair(NoRepair)
, store(store) , store(store)
, baseEnv(allocEnv(128)) , baseEnv(allocEnv(128))
, staticBaseEnv(false, 0) , staticBaseEnv(false, 0)

View file

@ -14,6 +14,7 @@ namespace nix {
class Store; class Store;
class EvalState; class EvalState;
enum RepairFlag : bool;
typedef void (* PrimOpFun) (EvalState & state, const Pos & pos, Value * * args, Value & v); typedef void (* PrimOpFun) (EvalState & state, const Pos & pos, Value * * args, Value & v);
@ -73,7 +74,7 @@ public:
/* If set, force copying files to the Nix store even if they /* If set, force copying files to the Nix store even if they
already exist there. */ already exist there. */
bool repair = false; RepairFlag repair;
/* If set, don't allow access to files outside of the Nix search /* If set, don't allow access to files outside of the Nix search
path or to environment variables. */ path or to environment variables. */

View file

@ -134,7 +134,7 @@ Path BinaryCacheStore::narInfoFileFor(const Path & storePath)
} }
void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::string> & nar, void BinaryCacheStore::addToStore(const ValidPathInfo & info, const ref<std::string> & nar,
bool repair, bool dontCheckSigs, std::shared_ptr<FSAccessor> accessor) RepairFlag repair, CheckSigsFlag checkSigs, std::shared_ptr<FSAccessor> accessor)
{ {
if (!repair && isValidPath(info.path)) return; if (!repair && isValidPath(info.path)) return;
@ -328,7 +328,7 @@ void BinaryCacheStore::queryPathInfoUncached(const Path & storePath,
} }
Path BinaryCacheStore::addToStore(const string & name, const Path & srcPath, Path BinaryCacheStore::addToStore(const string & name, const Path & srcPath,
bool recursive, HashType hashAlgo, PathFilter & filter, bool repair) bool recursive, HashType hashAlgo, PathFilter & filter, RepairFlag repair)
{ {
// FIXME: some cut&paste from LocalStore::addToStore(). // FIXME: some cut&paste from LocalStore::addToStore().
@ -349,13 +349,13 @@ Path BinaryCacheStore::addToStore(const string & name, const Path & srcPath,
ValidPathInfo info; ValidPathInfo info;
info.path = makeFixedOutputPath(recursive, h, name); info.path = makeFixedOutputPath(recursive, h, name);
addToStore(info, sink.s, repair, false, 0); addToStore(info, sink.s, repair, CheckSigs, nullptr);
return info.path; return info.path;
} }
Path BinaryCacheStore::addTextToStore(const string & name, const string & s, Path BinaryCacheStore::addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair) const PathSet & references, RepairFlag repair)
{ {
ValidPathInfo info; ValidPathInfo info;
info.path = computeStorePathForText(name, s, references); info.path = computeStorePathForText(name, s, references);
@ -364,7 +364,7 @@ Path BinaryCacheStore::addTextToStore(const string & name, const string & s,
if (repair || !isValidPath(info.path)) { if (repair || !isValidPath(info.path)) {
StringSink sink; StringSink sink;
dumpString(s, sink); dumpString(s, sink);
addToStore(info, sink.s, repair, false, 0); addToStore(info, sink.s, repair, CheckSigs, nullptr);
} }
return info.path; return info.path;

View file

@ -85,15 +85,15 @@ public:
bool wantMassQuery() override { return wantMassQuery_; } bool wantMassQuery() override { return wantMassQuery_; }
void addToStore(const ValidPathInfo & info, const ref<std::string> & nar, void addToStore(const ValidPathInfo & info, const ref<std::string> & nar,
bool repair, bool dontCheckSigs, RepairFlag repair, CheckSigsFlag checkSigs,
std::shared_ptr<FSAccessor> accessor) override; std::shared_ptr<FSAccessor> accessor) override;
Path addToStore(const string & name, const Path & srcPath, Path addToStore(const string & name, const Path & srcPath,
bool recursive, HashType hashAlgo, bool recursive, HashType hashAlgo,
PathFilter & filter, bool repair) override; PathFilter & filter, RepairFlag repair) override;
Path addTextToStore(const string & name, const string & s, Path addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair) override; const PathSet & references, RepairFlag repair) override;
void narFromPath(const Path & path, Sink & sink) override; void narFromPath(const Path & path, Sink & sink) override;

View file

@ -262,7 +262,7 @@ public:
GoalPtr makeDerivationGoal(const Path & drvPath, const StringSet & wantedOutputs, BuildMode buildMode = bmNormal); GoalPtr makeDerivationGoal(const Path & drvPath, const StringSet & wantedOutputs, BuildMode buildMode = bmNormal);
std::shared_ptr<DerivationGoal> makeBasicDerivationGoal(const Path & drvPath, std::shared_ptr<DerivationGoal> makeBasicDerivationGoal(const Path & drvPath,
const BasicDerivation & drv, BuildMode buildMode = bmNormal); const BasicDerivation & drv, BuildMode buildMode = bmNormal);
GoalPtr makeSubstitutionGoal(const Path & storePath, bool repair = false); GoalPtr makeSubstitutionGoal(const Path & storePath, RepairFlag repair = NoRepair);
/* Remove a dead goal. */ /* Remove a dead goal. */
void removeGoal(GoalPtr goal); void removeGoal(GoalPtr goal);
@ -1087,7 +1087,7 @@ void DerivationGoal::haveDerivation()
them. */ them. */
if (settings.useSubstitutes && drv->substitutesAllowed()) if (settings.useSubstitutes && drv->substitutesAllowed())
for (auto & i : invalidOutputs) for (auto & i : invalidOutputs)
addWaitee(worker.makeSubstitutionGoal(i, buildMode == bmRepair)); addWaitee(worker.makeSubstitutionGoal(i, buildMode == bmRepair ? Repair : NoRepair));
if (waitees.empty()) /* to prevent hang (no wake-up event) */ if (waitees.empty()) /* to prevent hang (no wake-up event) */
outputsSubstituted(); outputsSubstituted();
@ -1195,7 +1195,7 @@ void DerivationGoal::repairClosure()
printError(format("found corrupted or missing path %1% in the output closure of %2%") % i % drvPath); printError(format("found corrupted or missing path %1% in the output closure of %2%") % i % drvPath);
Path drvPath2 = outputsToDrv[i]; Path drvPath2 = outputsToDrv[i];
if (drvPath2 == "") if (drvPath2 == "")
addWaitee(worker.makeSubstitutionGoal(i, true)); addWaitee(worker.makeSubstitutionGoal(i, Repair));
else else
addWaitee(worker.makeDerivationGoal(drvPath2, PathSet(), bmRepair)); addWaitee(worker.makeDerivationGoal(drvPath2, PathSet(), bmRepair));
} }
@ -3291,7 +3291,7 @@ private:
std::promise<void> promise; std::promise<void> promise;
/* Whether to try to repair a valid path. */ /* Whether to try to repair a valid path. */
bool repair; RepairFlag repair;
/* Location where we're downloading the substitute. Differs from /* Location where we're downloading the substitute. Differs from
storePath when doing a repair. */ storePath when doing a repair. */
@ -3301,7 +3301,7 @@ private:
GoalState state; GoalState state;
public: public:
SubstitutionGoal(const Path & storePath, Worker & worker, bool repair = false); SubstitutionGoal(const Path & storePath, Worker & worker, RepairFlag repair = NoRepair);
~SubstitutionGoal(); ~SubstitutionGoal();
void timedOut() override { abort(); }; void timedOut() override { abort(); };
@ -3337,7 +3337,7 @@ public:
}; };
SubstitutionGoal::SubstitutionGoal(const Path & storePath, Worker & worker, bool repair) SubstitutionGoal::SubstitutionGoal(const Path & storePath, Worker & worker, RepairFlag repair)
: Goal(worker) : Goal(worker)
, hasSubstitute(false) , hasSubstitute(false)
, repair(repair) , repair(repair)
@ -3600,7 +3600,7 @@ std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const Path & drv
} }
GoalPtr Worker::makeSubstitutionGoal(const Path & path, bool repair) GoalPtr Worker::makeSubstitutionGoal(const Path & path, RepairFlag repair)
{ {
GoalPtr goal = substitutionGoals[path].lock(); GoalPtr goal = substitutionGoals[path].lock();
if (!goal) { if (!goal) {
@ -3953,7 +3953,7 @@ void LocalStore::buildPaths(const PathSet & drvPaths, BuildMode buildMode)
if (isDerivation(i2.first)) if (isDerivation(i2.first))
goals.insert(worker.makeDerivationGoal(i2.first, i2.second, buildMode)); goals.insert(worker.makeDerivationGoal(i2.first, i2.second, buildMode));
else else
goals.insert(worker.makeSubstitutionGoal(i, buildMode)); goals.insert(worker.makeSubstitutionGoal(i, buildMode == bmRepair ? Repair : NoRepair));
} }
worker.run(goals); worker.run(goals);
@ -4011,7 +4011,7 @@ void LocalStore::ensurePath(const Path & path)
void LocalStore::repairPath(const Path & path) void LocalStore::repairPath(const Path & path)
{ {
Worker worker(*this); Worker worker(*this);
GoalPtr goal = worker.makeSubstitutionGoal(path, true); GoalPtr goal = worker.makeSubstitutionGoal(path, Repair);
Goals goals = {goal}; Goals goals = {goal};
worker.run(goals); worker.run(goals);

View file

@ -71,7 +71,7 @@ bool BasicDerivation::canBuildLocally() const
Path writeDerivation(ref<Store> store, Path writeDerivation(ref<Store> store,
const Derivation & drv, const string & name, bool repair) const Derivation & drv, const string & name, RepairFlag repair)
{ {
PathSet references; PathSet references;
references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end()); references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end());

View file

@ -2,6 +2,7 @@
#include "types.hh" #include "types.hh"
#include "hash.hh" #include "hash.hh"
#include "store-api.hh"
#include <map> #include <map>
@ -85,7 +86,7 @@ class Store;
/* Write a derivation to the Nix store, and return its path. */ /* Write a derivation to the Nix store, and return its path. */
Path writeDerivation(ref<Store> store, Path writeDerivation(ref<Store> store,
const Derivation & drv, const string & name, bool repair = false); const Derivation & drv, const string & name, RepairFlag repair = NoRepair);
/* Read a derivation from a file. */ /* Read a derivation from a file. */
Derivation readDerivation(const Path & drvPath); Derivation readDerivation(const Path & drvPath);

View file

@ -631,7 +631,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
info.narHash = hashString(htSHA256, *sink.s); info.narHash = hashString(htSHA256, *sink.s);
info.narSize = sink.s->size(); info.narSize = sink.s->size();
info.ca = makeFixedOutputCA(false, hash); info.ca = makeFixedOutputCA(false, hash);
store->addToStore(info, sink.s, false, true); store->addToStore(info, sink.s, NoRepair, NoCheckSigs);
storePath = info.path; storePath = info.path;
} }
@ -660,7 +660,7 @@ Path Downloader::downloadCached(ref<Store> store, const string & url_, bool unpa
AutoDelete autoDelete(tmpDir, true); AutoDelete autoDelete(tmpDir, true);
// FIXME: this requires GNU tar for decompression. // FIXME: this requires GNU tar for decompression.
runProgram("tar", true, {"xf", storePath, "-C", tmpDir, "--strip-components", "1"}); runProgram("tar", true, {"xf", storePath, "-C", tmpDir, "--strip-components", "1"});
unpackedStorePath = store->addToStore(name, tmpDir, true, htSHA256, defaultPathFilter, false); unpackedStorePath = store->addToStore(name, tmpDir, true, htSHA256, defaultPathFilter, NoRepair);
} }
replaceSymlink(unpackedStorePath, unpackedLink); replaceSymlink(unpackedStorePath, unpackedLink);
storePath = unpackedStorePath; storePath = unpackedStorePath;

View file

@ -61,7 +61,7 @@ void Store::exportPath(const Path & path, Sink & sink)
hashAndWriteSink << exportMagic << path << info->references << info->deriver << 0; hashAndWriteSink << exportMagic << path << info->references << info->deriver << 0;
} }
Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor, bool dontCheckSigs) Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor, CheckSigsFlag checkSigs)
{ {
Paths res; Paths res;
while (true) { while (true) {
@ -95,7 +95,7 @@ Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor,
if (readInt(source) == 1) if (readInt(source) == 1)
readString(source); readString(source);
addToStore(info, tee.source.data, false, dontCheckSigs, accessor); addToStore(info, tee.source.data, NoRepair, checkSigs, accessor);
res.push_back(info.path); res.push_back(info.path);
} }

View file

@ -113,7 +113,7 @@ struct LegacySSHStore : public Store
} }
void addToStore(const ValidPathInfo & info, const ref<std::string> & nar, void addToStore(const ValidPathInfo & info, const ref<std::string> & nar,
bool repair, bool dontCheckSigs, RepairFlag repair, CheckSigsFlag checkSigs,
std::shared_ptr<FSAccessor> accessor) override std::shared_ptr<FSAccessor> accessor) override
{ {
debug("adding path %s to remote host %s", info.path, host); debug("adding path %s to remote host %s", info.path, host);
@ -168,11 +168,11 @@ struct LegacySSHStore : public Store
Path addToStore(const string & name, const Path & srcPath, Path addToStore(const string & name, const Path & srcPath,
bool recursive, HashType hashAlgo, bool recursive, HashType hashAlgo,
PathFilter & filter, bool repair) override PathFilter & filter, RepairFlag repair) override
{ unsupported(); } { unsupported(); }
Path addTextToStore(const string & name, const string & s, Path addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair) override const PathSet & references, RepairFlag repair) override
{ unsupported(); } { unsupported(); }
BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv, BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv,
@ -249,7 +249,8 @@ struct LegacySSHStore : public Store
out.insert(res.begin(), res.end()); out.insert(res.begin(), res.end());
} }
PathSet queryValidPaths(const PathSet & paths, bool maybeSubstitute = false) override PathSet queryValidPaths(const PathSet & paths,
SubstituteFlag maybeSubstitute = NoSubstitute) override
{ {
auto conn(connections->get()); auto conn(connections->get());

View file

@ -718,7 +718,7 @@ bool LocalStore::isValidPathUncached(const Path & path)
} }
PathSet LocalStore::queryValidPaths(const PathSet & paths, bool maybeSubstitute) PathSet LocalStore::queryValidPaths(const PathSet & paths, SubstituteFlag maybeSubstitute)
{ {
PathSet res; PathSet res;
for (auto & i : paths) for (auto & i : paths)
@ -961,7 +961,7 @@ void LocalStore::invalidatePath(State & state, const Path & path)
void LocalStore::addToStore(const ValidPathInfo & info, const ref<std::string> & nar, void LocalStore::addToStore(const ValidPathInfo & info, const ref<std::string> & nar,
bool repair, bool dontCheckSigs, std::shared_ptr<FSAccessor> accessor) RepairFlag repair, CheckSigsFlag checkSigs, std::shared_ptr<FSAccessor> accessor)
{ {
assert(info.narHash); assert(info.narHash);
@ -974,7 +974,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, const ref<std::string> &
throw Error("size mismatch importing path %s; expected %s, got %s", throw Error("size mismatch importing path %s; expected %s, got %s",
info.path, info.narSize, nar->size()); info.path, info.narSize, nar->size());
if (requireSigs && !dontCheckSigs && !info.checkSignatures(*this, publicKeys)) if (requireSigs && checkSigs && !info.checkSignatures(*this, publicKeys))
throw Error("cannot add path %s because it lacks a valid signature", info.path); throw Error("cannot add path %s because it lacks a valid signature", info.path);
addTempRoot(info.path); addTempRoot(info.path);
@ -1012,7 +1012,7 @@ void LocalStore::addToStore(const ValidPathInfo & info, const ref<std::string> &
Path LocalStore::addToStoreFromDump(const string & dump, const string & name, Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
bool recursive, HashType hashAlgo, bool repair) bool recursive, HashType hashAlgo, RepairFlag repair)
{ {
Hash h = hashString(hashAlgo, dump); Hash h = hashString(hashAlgo, dump);
@ -1070,7 +1070,7 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name,
Path LocalStore::addToStore(const string & name, const Path & _srcPath, Path LocalStore::addToStore(const string & name, const Path & _srcPath,
bool recursive, HashType hashAlgo, PathFilter & filter, bool repair) bool recursive, HashType hashAlgo, PathFilter & filter, RepairFlag repair)
{ {
Path srcPath(absPath(_srcPath)); Path srcPath(absPath(_srcPath));
@ -1088,7 +1088,7 @@ Path LocalStore::addToStore(const string & name, const Path & _srcPath,
Path LocalStore::addTextToStore(const string & name, const string & s, Path LocalStore::addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair) const PathSet & references, RepairFlag repair)
{ {
auto hash = hashString(htSHA256, s); auto hash = hashString(htSHA256, s);
auto dstPath = makeTextPath(name, hash, references); auto dstPath = makeTextPath(name, hash, references);
@ -1170,7 +1170,7 @@ void LocalStore::invalidatePathChecked(const Path & path)
} }
bool LocalStore::verifyStore(bool checkContents, bool repair) bool LocalStore::verifyStore(bool checkContents, RepairFlag repair)
{ {
printError(format("reading the Nix store...")); printError(format("reading the Nix store..."));
@ -1255,7 +1255,7 @@ bool LocalStore::verifyStore(bool checkContents, bool repair)
void LocalStore::verifyPath(const Path & path, const PathSet & store, void LocalStore::verifyPath(const Path & path, const PathSet & store,
PathSet & done, PathSet & validPaths, bool repair, bool & errors) PathSet & done, PathSet & validPaths, RepairFlag repair, bool & errors)
{ {
checkInterrupt(); checkInterrupt();

View file

@ -98,7 +98,8 @@ public:
bool isValidPathUncached(const Path & path) override; bool isValidPathUncached(const Path & path) override;
PathSet queryValidPaths(const PathSet & paths, bool maybeSubstitute = false) override; PathSet queryValidPaths(const PathSet & paths,
SubstituteFlag maybeSubstitute = NoSubstitute) override;
PathSet queryAllValidPaths() override; PathSet queryAllValidPaths() override;
@ -122,22 +123,22 @@ public:
SubstitutablePathInfos & infos) override; SubstitutablePathInfos & infos) override;
void addToStore(const ValidPathInfo & info, const ref<std::string> & nar, void addToStore(const ValidPathInfo & info, const ref<std::string> & nar,
bool repair, bool dontCheckSigs, RepairFlag repair, CheckSigsFlag checkSigs,
std::shared_ptr<FSAccessor> accessor) override; std::shared_ptr<FSAccessor> accessor) override;
Path addToStore(const string & name, const Path & srcPath, Path addToStore(const string & name, const Path & srcPath,
bool recursive, HashType hashAlgo, bool recursive, HashType hashAlgo,
PathFilter & filter, bool repair) override; PathFilter & filter, RepairFlag repair) override;
/* Like addToStore(), but the contents of the path are contained /* Like addToStore(), but the contents of the path are contained
in `dump', which is either a NAR serialisation (if recursive == in `dump', which is either a NAR serialisation (if recursive ==
true) or simply the contents of a regular file (if recursive == true) or simply the contents of a regular file (if recursive ==
false). */ false). */
Path addToStoreFromDump(const string & dump, const string & name, Path addToStoreFromDump(const string & dump, const string & name,
bool recursive = true, HashType hashAlgo = htSHA256, bool repair = false); bool recursive = true, HashType hashAlgo = htSHA256, RepairFlag repair = NoRepair);
Path addTextToStore(const string & name, const string & s, Path addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair) override; const PathSet & references, RepairFlag repair) override;
void buildPaths(const PathSet & paths, BuildMode buildMode) override; void buildPaths(const PathSet & paths, BuildMode buildMode) override;
@ -174,7 +175,7 @@ public:
/* Optimise a single store path. */ /* Optimise a single store path. */
void optimisePath(const Path & path); void optimisePath(const Path & path);
bool verifyStore(bool checkContents, bool repair) override; bool verifyStore(bool checkContents, RepairFlag repair) override;
/* Register the validity of a path, i.e., that `path' exists, that /* Register the validity of a path, i.e., that `path' exists, that
the paths referenced by it exists, and in the case of an output the paths referenced by it exists, and in the case of an output
@ -212,7 +213,7 @@ private:
void invalidatePathChecked(const Path & path); void invalidatePathChecked(const Path & path);
void verifyPath(const Path & path, const PathSet & store, void verifyPath(const Path & path, const PathSet & store,
PathSet & done, PathSet & validPaths, bool repair, bool & errors); PathSet & done, PathSet & validPaths, RepairFlag repair, bool & errors);
void updatePathInfo(State & state, const ValidPathInfo & info); void updatePathInfo(State & state, const ValidPathInfo & info);

View file

@ -185,7 +185,7 @@ bool RemoteStore::isValidPathUncached(const Path & path)
} }
PathSet RemoteStore::queryValidPaths(const PathSet & paths, bool maybeSubstitute) PathSet RemoteStore::queryValidPaths(const PathSet & paths, SubstituteFlag maybeSubstitute)
{ {
auto conn(connections->get()); auto conn(connections->get());
if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 12) { if (GET_PROTOCOL_MINOR(conn->daemonVersion) < 12) {
@ -357,7 +357,7 @@ Path RemoteStore::queryPathFromHashPart(const string & hashPart)
void RemoteStore::addToStore(const ValidPathInfo & info, const ref<std::string> & nar, void RemoteStore::addToStore(const ValidPathInfo & info, const ref<std::string> & nar,
bool repair, bool dontCheckSigs, std::shared_ptr<FSAccessor> accessor) RepairFlag repair, CheckSigsFlag checkSigs, std::shared_ptr<FSAccessor> accessor)
{ {
auto conn(connections->get()); auto conn(connections->get());
@ -390,7 +390,7 @@ void RemoteStore::addToStore(const ValidPathInfo & info, const ref<std::string>
<< info.path << info.deriver << printHash(info.narHash) << info.path << info.deriver << printHash(info.narHash)
<< info.references << info.registrationTime << info.narSize << info.references << info.registrationTime << info.narSize
<< info.ultimate << info.sigs << info.ca << info.ultimate << info.sigs << info.ca
<< repair << dontCheckSigs; << repair << !checkSigs;
conn->to(*nar); conn->to(*nar);
conn->processStderr(); conn->processStderr();
} }
@ -398,7 +398,7 @@ void RemoteStore::addToStore(const ValidPathInfo & info, const ref<std::string>
Path RemoteStore::addToStore(const string & name, const Path & _srcPath, Path RemoteStore::addToStore(const string & name, const Path & _srcPath,
bool recursive, HashType hashAlgo, PathFilter & filter, bool repair) bool recursive, HashType hashAlgo, PathFilter & filter, RepairFlag repair)
{ {
if (repair) throw Error("repairing is not supported when building through the Nix daemon"); if (repair) throw Error("repairing is not supported when building through the Nix daemon");
@ -434,7 +434,7 @@ Path RemoteStore::addToStore(const string & name, const Path & _srcPath,
Path RemoteStore::addTextToStore(const string & name, const string & s, Path RemoteStore::addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair) const PathSet & references, RepairFlag repair)
{ {
if (repair) throw Error("repairing is not supported when building through the Nix daemon"); if (repair) throw Error("repairing is not supported when building through the Nix daemon");
@ -570,7 +570,7 @@ void RemoteStore::optimiseStore()
} }
bool RemoteStore::verifyStore(bool checkContents, bool repair) bool RemoteStore::verifyStore(bool checkContents, RepairFlag repair)
{ {
auto conn(connections->get()); auto conn(connections->get());
conn->to << wopVerifyStore << checkContents << repair; conn->to << wopVerifyStore << checkContents << repair;

View file

@ -31,7 +31,8 @@ public:
bool isValidPathUncached(const Path & path) override; bool isValidPathUncached(const Path & path) override;
PathSet queryValidPaths(const PathSet & paths, bool maybeSubstitute = false) override; PathSet queryValidPaths(const PathSet & paths,
SubstituteFlag maybeSubstitute = NoSubstitute) override;
PathSet queryAllValidPaths() override; PathSet queryAllValidPaths() override;
@ -55,15 +56,15 @@ public:
SubstitutablePathInfos & infos) override; SubstitutablePathInfos & infos) override;
void addToStore(const ValidPathInfo & info, const ref<std::string> & nar, void addToStore(const ValidPathInfo & info, const ref<std::string> & nar,
bool repair, bool dontCheckSigs, RepairFlag repair, CheckSigsFlag checkSigs,
std::shared_ptr<FSAccessor> accessor) override; std::shared_ptr<FSAccessor> accessor) override;
Path addToStore(const string & name, const Path & srcPath, Path addToStore(const string & name, const Path & srcPath,
bool recursive = true, HashType hashAlgo = htSHA256, bool recursive = true, HashType hashAlgo = htSHA256,
PathFilter & filter = defaultPathFilter, bool repair = false) override; PathFilter & filter = defaultPathFilter, RepairFlag repair = NoRepair) override;
Path addTextToStore(const string & name, const string & s, Path addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair = false) override; const PathSet & references, RepairFlag repair) override;
void buildPaths(const PathSet & paths, BuildMode buildMode) override; void buildPaths(const PathSet & paths, BuildMode buildMode) override;
@ -84,7 +85,7 @@ public:
void optimiseStore() override; void optimiseStore() override;
bool verifyStore(bool checkContents, bool repair) override; bool verifyStore(bool checkContents, RepairFlag repair) override;
void addSignatures(const Path & storePath, const StringSet & sigs) override; void addSignatures(const Path & storePath, const StringSet & sigs) override;

View file

@ -378,7 +378,7 @@ void Store::queryPathInfo(const Path & storePath,
} }
PathSet Store::queryValidPaths(const PathSet & paths, bool maybeSubstitute) PathSet Store::queryValidPaths(const PathSet & paths, SubstituteFlag maybeSubstitute)
{ {
struct State struct State
{ {
@ -537,14 +537,14 @@ void Store::buildPaths(const PathSet & paths, BuildMode buildMode)
void copyStorePath(ref<Store> srcStore, ref<Store> dstStore, void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
const Path & storePath, bool repair, bool dontCheckSigs) const Path & storePath, RepairFlag repair, CheckSigsFlag checkSigs)
{ {
auto info = srcStore->queryPathInfo(storePath); auto info = srcStore->queryPathInfo(storePath);
StringSink sink; StringSink sink;
srcStore->narFromPath({storePath}, sink); srcStore->narFromPath({storePath}, sink);
if (!info->narHash && dontCheckSigs) { if (!info->narHash && !checkSigs) {
auto info2 = make_ref<ValidPathInfo>(*info); auto info2 = make_ref<ValidPathInfo>(*info);
info2->narHash = hashString(htSHA256, *sink.s); info2->narHash = hashString(htSHA256, *sink.s);
if (!info->narSize) info2->narSize = sink.s->size(); if (!info->narSize) info2->narSize = sink.s->size();
@ -561,33 +561,47 @@ void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
assert(info->narHash); assert(info->narHash);
dstStore->addToStore(*info, sink.s, repair, dontCheckSigs); dstStore->addToStore(*info, sink.s, repair, checkSigs);
}
void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const PathSet & storePaths,
RepairFlag repair, CheckSigsFlag checkSigs, SubstituteFlag substitute)
{
PathSet valid = dstStore->queryValidPaths(storePaths, substitute);
PathSet missing;
for (auto & path : storePaths)
if (!valid.count(path)) missing.insert(path);
ThreadPool pool;
processGraph<Path>(pool,
PathSet(missing.begin(), missing.end()),
[&](const Path & storePath) {
if (dstStore->isValidPath(storePath)) return PathSet();
return srcStore->queryPathInfo(storePath)->references;
},
[&](const Path & storePath) {
checkInterrupt();
if (!dstStore->isValidPath(storePath)) {
printError("copying %s...", storePath);
copyStorePath(srcStore, dstStore, storePath, repair, checkSigs);
}
});
} }
void copyClosure(ref<Store> srcStore, ref<Store> dstStore, void copyClosure(ref<Store> srcStore, ref<Store> dstStore,
const PathSet & storePaths, bool repair, bool dontCheckSigs) const PathSet & storePaths, RepairFlag repair, CheckSigsFlag checkSigs,
SubstituteFlag substitute)
{ {
PathSet closure; PathSet closure;
for (auto & path : storePaths) srcStore->computeFSClosure({storePaths}, closure);
srcStore->computeFSClosure(path, closure); copyPaths(srcStore, dstStore, closure, repair, checkSigs, substitute);
// FIXME: use copyStorePaths()
PathSet valid = dstStore->queryValidPaths(closure);
if (valid.size() == closure.size()) return;
Paths sorted = srcStore->topoSortPaths(closure);
Paths missing;
for (auto i = sorted.rbegin(); i != sorted.rend(); ++i)
if (!valid.count(*i)) missing.push_back(*i);
printMsg(lvlDebug, format("copying %1% missing paths") % missing.size());
for (auto & i : missing)
copyStorePath(srcStore, dstStore, i, repair, dontCheckSigs);
} }
@ -812,45 +826,4 @@ std::list<ref<Store>> getDefaultSubstituters()
} }
void copyPaths(ref<Store> from, ref<Store> to, const PathSet & storePaths,
bool substitute, bool dontCheckSigs)
{
PathSet valid = to->queryValidPaths(storePaths, substitute);
PathSet missing;
for (auto & path : storePaths)
if (!valid.count(path)) missing.insert(path);
std::string copiedLabel = "copied";
//logger->setExpected(copiedLabel, missing.size());
ThreadPool pool;
processGraph<Path>(pool,
PathSet(missing.begin(), missing.end()),
[&](const Path & storePath) {
if (to->isValidPath(storePath)) return PathSet();
return from->queryPathInfo(storePath)->references;
},
[&](const Path & storePath) {
checkInterrupt();
if (!to->isValidPath(storePath)) {
//Activity act(*logger, lvlInfo, format("copying %s...") % storePath);
copyStorePath(from, to, storePath, false, dontCheckSigs);
//logger->incProgress(copiedLabel);
} else
;
//logger->incExpected(copiedLabel, -1);
});
pool.process();
}
} }

View file

@ -32,6 +32,11 @@ class Store;
class JSONPlaceholder; class JSONPlaceholder;
enum RepairFlag : bool { NoRepair = false, Repair = true };
enum CheckSigsFlag : bool { NoCheckSigs = false, CheckSigs = true };
enum SubstituteFlag : bool { NoSubstitute = false, Substitute = true };
/* Size of the hash part of store paths, in base-32 characters. */ /* Size of the hash part of store paths, in base-32 characters. */
const size_t storePathHashLen = 32; // i.e. 160 bits const size_t storePathHashLen = 32; // i.e. 160 bits
@ -332,7 +337,7 @@ public:
/* Query which of the given paths is valid. Optionally, try to /* Query which of the given paths is valid. Optionally, try to
substitute missing paths. */ substitute missing paths. */
virtual PathSet queryValidPaths(const PathSet & paths, virtual PathSet queryValidPaths(const PathSet & paths,
bool maybeSubstitute = false); SubstituteFlag maybeSubstitute = NoSubstitute);
/* Query the set of all valid paths. Note that for some store /* Query the set of all valid paths. Note that for some store
backends, the name part of store paths may be omitted backends, the name part of store paths may be omitted
@ -392,7 +397,7 @@ public:
/* Import a path into the store. */ /* Import a path into the store. */
virtual void addToStore(const ValidPathInfo & info, const ref<std::string> & nar, virtual void addToStore(const ValidPathInfo & info, const ref<std::string> & nar,
bool repair = false, bool dontCheckSigs = false, RepairFlag repair = NoRepair, CheckSigsFlag checkSigs = CheckSigs,
std::shared_ptr<FSAccessor> accessor = 0) = 0; std::shared_ptr<FSAccessor> accessor = 0) = 0;
/* Copy the contents of a path to the store and register the /* Copy the contents of a path to the store and register the
@ -401,12 +406,12 @@ public:
libutil/archive.hh). */ libutil/archive.hh). */
virtual Path addToStore(const string & name, const Path & srcPath, virtual Path addToStore(const string & name, const Path & srcPath,
bool recursive = true, HashType hashAlgo = htSHA256, bool recursive = true, HashType hashAlgo = htSHA256,
PathFilter & filter = defaultPathFilter, bool repair = false) = 0; PathFilter & filter = defaultPathFilter, RepairFlag repair = NoRepair) = 0;
/* Like addToStore, but the contents written to the output path is /* Like addToStore, but the contents written to the output path is
a regular file containing the given string. */ a regular file containing the given string. */
virtual Path addTextToStore(const string & name, const string & s, virtual Path addTextToStore(const string & name, const string & s,
const PathSet & references, bool repair = false) = 0; const PathSet & references, RepairFlag repair = NoRepair) = 0;
/* Write a NAR dump of a store path. */ /* Write a NAR dump of a store path. */
virtual void narFromPath(const Path & path, Sink & sink) = 0; virtual void narFromPath(const Path & path, Sink & sink) = 0;
@ -496,7 +501,7 @@ public:
/* Check the integrity of the Nix store. Returns true if errors /* Check the integrity of the Nix store. Returns true if errors
remain. */ remain. */
virtual bool verifyStore(bool checkContents, bool repair) { return false; }; virtual bool verifyStore(bool checkContents, RepairFlag repair = NoRepair) { return false; };
/* Return an object to access files in the Nix store. */ /* Return an object to access files in the Nix store. */
virtual ref<FSAccessor> getFSAccessor() = 0; virtual ref<FSAccessor> getFSAccessor() = 0;
@ -548,7 +553,7 @@ public:
preloaded into the specified FS accessor to speed up subsequent preloaded into the specified FS accessor to speed up subsequent
access. */ access. */
Paths importPaths(Source & source, std::shared_ptr<FSAccessor> accessor, Paths importPaths(Source & source, std::shared_ptr<FSAccessor> accessor,
bool dontCheckSigs = false); CheckSigsFlag checkSigs = CheckSigs);
struct Stats struct Stats
{ {
@ -650,12 +655,26 @@ void checkStoreName(const string & name);
/* Copy a path from one store to another. */ /* Copy a path from one store to another. */
void copyStorePath(ref<Store> srcStore, ref<Store> dstStore, void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
const Path & storePath, bool repair = false, bool dontCheckSigs = false); const Path & storePath, RepairFlag repair = NoRepair, CheckSigsFlag checkSigs = CheckSigs);
/* Copy store paths from one store to another. The paths may be copied
in parallel. They are copied in a topologically sorted order
(i.e. if A is a reference of B, then A is copied before B), but
the set of store paths is not automatically closed; use
copyClosure() for that. */
void copyPaths(ref<Store> srcStore, ref<Store> dstStore, const PathSet & storePaths,
RepairFlag repair = NoRepair,
CheckSigsFlag checkSigs = CheckSigs,
SubstituteFlag substitute = NoSubstitute);
/* Copy the closure of the specified paths from one store to another. */ /* Copy the closure of the specified paths from one store to another. */
void copyClosure(ref<Store> srcStore, ref<Store> dstStore, void copyClosure(ref<Store> srcStore, ref<Store> dstStore,
const PathSet & storePaths, bool repair = false, bool dontCheckSigs = false); const PathSet & storePaths,
RepairFlag repair = NoRepair,
CheckSigsFlag checkSigs = CheckSigs,
SubstituteFlag substitute = NoSubstitute);
/* Remove the temporary roots file for this process. Any temporary /* Remove the temporary roots file for this process. Any temporary
@ -694,9 +713,6 @@ ref<Store> openStore(const std::string & uri = getEnv("NIX_REMOTE"),
const Store::Params & extraParams = Store::Params()); const Store::Params & extraParams = Store::Params());
void copyPaths(ref<Store> from, ref<Store> to, const PathSet & storePaths,
bool substitute = false, bool dontCheckSigs = false);
enum StoreType { enum StoreType {
tDaemon, tDaemon,
tLocal, tLocal,

View file

@ -12,7 +12,7 @@ int main(int argc, char ** argv)
auto toMode = true; auto toMode = true;
auto includeOutputs = false; auto includeOutputs = false;
auto dryRun = false; auto dryRun = false;
auto useSubstitutes = false; auto useSubstitutes = NoSubstitute;
std::string sshHost; std::string sshHost;
PathSet storePaths; PathSet storePaths;
@ -36,7 +36,7 @@ int main(int argc, char ** argv)
else if (*arg == "--dry-run") else if (*arg == "--dry-run")
dryRun = true; dryRun = true;
else if (*arg == "--use-substitutes" || *arg == "-s") else if (*arg == "--use-substitutes" || *arg == "-s")
useSubstitutes = true; useSubstitutes = Substitute;
else if (sshHost.empty()) else if (sshHost.empty())
sshHost = *arg; sshHost = *arg;
else else
@ -58,6 +58,6 @@ int main(int argc, char ** argv)
PathSet closure; PathSet closure;
from->computeFSClosure(storePaths2, closure, false, includeOutputs); from->computeFSClosure(storePaths2, closure, false, includeOutputs);
copyPaths(from, to, closure, useSubstitutes, true); copyPaths(from, to, closure, NoRepair, NoCheckSigs, useSubstitutes);
}); });
} }

View file

@ -304,7 +304,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
string s = readString(from); string s = readString(from);
PathSet refs = readStorePaths<PathSet>(*store, from); PathSet refs = readStorePaths<PathSet>(*store, from);
startWork(); startWork();
Path path = store->addTextToStore(suffix, s, refs, false); Path path = store->addTextToStore(suffix, s, refs, NoRepair);
stopWork(); stopWork();
to << path; to << path;
break; break;
@ -324,7 +324,8 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
case wopImportPaths: { case wopImportPaths: {
startWork(); startWork();
TunnelSource source(from); TunnelSource source(from);
Paths paths = store->importPaths(source, 0, trusted); Paths paths = store->importPaths(source, nullptr,
trusted ? NoCheckSigs : CheckSigs);
stopWork(); stopWork();
to << paths; to << paths;
break; break;
@ -576,7 +577,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
startWork(); startWork();
if (repair && !trusted) if (repair && !trusted)
throw Error("you are not privileged to repair paths"); throw Error("you are not privileged to repair paths");
bool errors = store->verifyStore(checkContents, repair); bool errors = store->verifyStore(checkContents, (RepairFlag) repair);
stopWork(); stopWork();
to << errors; to << errors;
break; break;
@ -623,7 +624,8 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe
parseDump(tee, tee.source); parseDump(tee, tee.source);
startWork(); startWork();
store->addToStore(info, tee.source.data, repair, dontCheckSigs, nullptr); store->addToStore(info, tee.source.data, (RepairFlag) repair,
dontCheckSigs ? NoCheckSigs : CheckSigs, nullptr);
stopWork(); stopWork();
break; break;
} }

View file

@ -1310,7 +1310,7 @@ int main(int argc, char * * argv)
Strings opFlags, opArgs, searchPath; Strings opFlags, opArgs, searchPath;
std::map<string, string> autoArgs_; std::map<string, string> autoArgs_;
Operation op = 0; Operation op = 0;
bool repair = false; RepairFlag repair = NoRepair;
string file; string file;
Globals globals; Globals globals;
@ -1372,7 +1372,7 @@ int main(int argc, char * * argv)
else if (*arg == "--prebuilt-only" || *arg == "-b") else if (*arg == "--prebuilt-only" || *arg == "-b")
globals.prebuiltOnly = true; globals.prebuiltOnly = true;
else if (*arg == "--repair") else if (*arg == "--repair")
repair = true; repair = Repair;
else if (*arg != "" && arg->at(0) == '-') { else if (*arg != "" && arg->at(0) == '-') {
opFlags.push_back(*arg); opFlags.push_back(*arg);
/* FIXME: hacky */ /* FIXME: hacky */

View file

@ -108,7 +108,7 @@ int main(int argc, char * * argv)
Strings attrPaths; Strings attrPaths;
bool wantsReadWrite = false; bool wantsReadWrite = false;
std::map<string, string> autoArgs_; std::map<string, string> autoArgs_;
bool repair = false; RepairFlag repair = NoRepair;
parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) {
if (*arg == "--help") if (*arg == "--help")
@ -146,7 +146,7 @@ int main(int argc, char * * argv)
else if (*arg == "--strict") else if (*arg == "--strict")
strict = true; strict = true;
else if (*arg == "--repair") else if (*arg == "--repair")
repair = true; repair = Repair;
else if (*arg == "--dry-run") else if (*arg == "--dry-run")
settings.readOnlyMode = true; settings.readOnlyMode = true;
else if (*arg != "" && arg->at(0) == '-') else if (*arg != "" && arg->at(0) == '-')

View file

@ -677,7 +677,7 @@ static void opImport(Strings opFlags, Strings opArgs)
if (!opArgs.empty()) throw UsageError("no arguments expected"); if (!opArgs.empty()) throw UsageError("no arguments expected");
FdSource source(STDIN_FILENO); FdSource source(STDIN_FILENO);
Paths paths = store->importPaths(source, nullptr, true); Paths paths = store->importPaths(source, nullptr, NoCheckSigs);
for (auto & i : paths) for (auto & i : paths)
cout << format("%1%\n") % i << std::flush; cout << format("%1%\n") % i << std::flush;
@ -702,11 +702,11 @@ static void opVerify(Strings opFlags, Strings opArgs)
throw UsageError("no arguments expected"); throw UsageError("no arguments expected");
bool checkContents = false; bool checkContents = false;
bool repair = false; RepairFlag repair = NoRepair;
for (auto & i : opFlags) for (auto & i : opFlags)
if (i == "--check-contents") checkContents = true; if (i == "--check-contents") checkContents = true;
else if (i == "--repair") repair = true; else if (i == "--repair") repair = Repair;
else throw UsageError(format("unknown flag %1%") % i); else throw UsageError(format("unknown flag %1%") % i);
if (store->verifyStore(checkContents, repair)) { if (store->verifyStore(checkContents, repair)) {
@ -871,7 +871,7 @@ static void opServe(Strings opFlags, Strings opArgs)
case cmdImportPaths: { case cmdImportPaths: {
if (!writeAllowed) throw Error("importing paths is not allowed"); if (!writeAllowed) throw Error("importing paths is not allowed");
store->importPaths(in, 0, true); // FIXME: should we skip sig checking? store->importPaths(in, nullptr, NoCheckSigs); // FIXME: should we skip sig checking?
out << 1; // indicate success out << 1; // indicate success
break; break;
} }