From 0a7084567fc4e7d077863075a7ea1bb82d843341 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 3 Oct 2012 15:09:18 -0400 Subject: [PATCH] =?UTF-8?q?Add=20a=20=E2=80=98--repair=E2=80=99=20flag=20t?= =?UTF-8?q?o=20nix-instantiate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows repairing corrupted derivations and other source files. --- src/libexpr/eval.cc | 3 ++- src/libexpr/eval.hh | 4 ++++ src/libexpr/primops.cc | 6 +++--- src/libstore/derivations.cc | 4 ++-- src/libstore/derivations.hh | 2 +- src/libstore/local-store.cc | 16 ++++++++-------- src/libstore/local-store.hh | 6 +++--- src/libstore/remote-store.cc | 10 +++++++--- src/libstore/remote-store.hh | 4 ++-- src/libstore/store-api.hh | 4 ++-- src/nix-instantiate/nix-instantiate.cc | 2 ++ 11 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 9e5be908f..2f9601ec5 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -141,6 +141,7 @@ EvalState::EvalState() , baseEnv(allocEnv(128)) , baseEnvDispl(0) , staticBaseEnv(false, 0) + , repair(false) { nrEnvs = nrValuesInEnvs = nrValues = nrListElems = 0; nrAttrsets = nrOpUpdates = nrOpUpdateValuesCopied = 0; @@ -1093,7 +1094,7 @@ string EvalState::coerceToString(Value & v, PathSet & context, else { dstPath = settings.readOnlyMode ? computeStorePathForPath(path).first - : store->addToStore(path); + : store->addToStore(path, true, htSHA256, defaultPathFilter, repair); srcToStore[path] = dstPath; printMsg(lvlChatty, format("copied source `%1%' -> `%2%'") % path % dstPath); diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index a1f26a056..a3c55a388 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -95,6 +95,10 @@ public: const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sSystem, sOverrides; + /* If set, force copying files to the Nix store even if they + already exist there. */ + bool repair; + private: SrcToStore srcToStore; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index bbe89c5f5..509297003 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -487,7 +487,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) } /* Write the resulting term into the Nix store directory. */ - Path drvPath = writeDerivation(*store, drv, drvName); + Path drvPath = writeDerivation(*store, drv, drvName, state.repair); printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'") % drvName % drvPath); @@ -625,7 +625,7 @@ static void prim_toFile(EvalState & state, Value * * args, Value & v) Path storePath = settings.readOnlyMode ? computeStorePathForText(name, contents, refs) - : store->addTextToStore(name, contents, refs); + : store->addTextToStore(name, contents, refs, state.repair); /* Note: we don't need to add `context' to the context of the result, since `storePath' itself has references to the paths @@ -689,7 +689,7 @@ static void prim_filterSource(EvalState & state, Value * * args, Value & v) Path dstPath = settings.readOnlyMode ? computeStorePathForPath(path, true, htSHA256, filter).first - : store->addToStore(path, true, htSHA256, filter); + : store->addToStore(path, true, htSHA256, filter, state.repair); mkString(v, dstPath, singleton(dstPath)); } diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index 73047c753..e0a4f43c0 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -27,7 +27,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash Path writeDerivation(StoreAPI & store, - const Derivation & drv, const string & name) + const Derivation & drv, const string & name, bool repair) { PathSet references; references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end()); @@ -40,7 +40,7 @@ Path writeDerivation(StoreAPI & store, string contents = unparseDerivation(drv); return settings.readOnlyMode ? computeStorePathForText(suffix, contents, references) - : store.addTextToStore(suffix, contents, references); + : store.addTextToStore(suffix, contents, references, repair); } diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index a5ffc2252..7d38e60c0 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -57,7 +57,7 @@ class StoreAPI; /* Write a derivation to the Nix store, and return its path. */ Path writeDerivation(StoreAPI & store, - const Derivation & drv, const string & name); + const Derivation & drv, const string & name, bool repair = false); /* Parse a derivation. */ Derivation parseDerivation(const string & s); diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index b55ab4284..982644af7 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -1158,7 +1158,7 @@ void LocalStore::invalidatePath(const Path & path) Path LocalStore::addToStoreFromDump(const string & dump, const string & name, - bool recursive, HashType hashAlgo) + bool recursive, HashType hashAlgo, bool repair) { Hash h = hashString(hashAlgo, dump); @@ -1166,14 +1166,14 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name, addTempRoot(dstPath); - if (!isValidPath(dstPath)) { + if (repair || !isValidPath(dstPath)) { /* The first check above is an optimisation to prevent unnecessary lock acquisition. */ PathLocks outputLock(singleton(dstPath)); - if (!isValidPath(dstPath)) { + if (repair || !isValidPath(dstPath)) { if (pathExists(dstPath)) deletePathWrapped(dstPath); @@ -1213,7 +1213,7 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name, Path LocalStore::addToStore(const Path & _srcPath, - bool recursive, HashType hashAlgo, PathFilter & filter) + bool recursive, HashType hashAlgo, PathFilter & filter, bool repair) { Path srcPath(absPath(_srcPath)); debug(format("adding `%1%' to the store") % srcPath); @@ -1227,22 +1227,22 @@ Path LocalStore::addToStore(const Path & _srcPath, else sink.s = readFile(srcPath); - return addToStoreFromDump(sink.s, baseNameOf(srcPath), recursive, hashAlgo); + return addToStoreFromDump(sink.s, baseNameOf(srcPath), recursive, hashAlgo, repair); } Path LocalStore::addTextToStore(const string & name, const string & s, - const PathSet & references) + const PathSet & references, bool repair) { Path dstPath = computeStorePathForText(name, s, references); addTempRoot(dstPath); - if (!isValidPath(dstPath)) { + if (repair || !isValidPath(dstPath)) { PathLocks outputLock(singleton(dstPath)); - if (!isValidPath(dstPath)) { + if (repair || !isValidPath(dstPath)) { if (pathExists(dstPath)) deletePathWrapped(dstPath); diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index b2f06d811..8d745cfb8 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -133,17 +133,17 @@ public: Path addToStore(const Path & srcPath, bool recursive = true, HashType hashAlgo = htSHA256, - PathFilter & filter = defaultPathFilter); + PathFilter & filter = defaultPathFilter, bool repair = false); /* Like addToStore(), but the contents of the path are contained in `dump', which is either a NAR serialisation (if recursive == true) or simply the contents of a regular file (if recursive == false). */ Path addToStoreFromDump(const string & dump, const string & name, - bool recursive = true, HashType hashAlgo = htSHA256); + bool recursive = true, HashType hashAlgo = htSHA256, bool repair = false); Path addTextToStore(const string & name, const string & s, - const PathSet & references); + const PathSet & references, bool repair = false); void exportPath(const Path & path, bool sign, Sink & sink); diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 2a895593b..08e409d3f 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -419,8 +419,10 @@ Path RemoteStore::queryPathFromHashPart(const string & hashPart) Path RemoteStore::addToStore(const Path & _srcPath, - bool recursive, HashType hashAlgo, PathFilter & filter) + bool recursive, HashType hashAlgo, PathFilter & filter, bool repair) { + if (repair) throw Error("repairing is not supported when building through the Nix daemon"); + openConnection(); Path srcPath(absPath(_srcPath)); @@ -438,8 +440,10 @@ Path RemoteStore::addToStore(const Path & _srcPath, Path RemoteStore::addTextToStore(const string & name, const string & s, - const PathSet & references) + const PathSet & references, bool repair) { + if (repair) throw Error("repairing is not supported when building through the Nix daemon"); + openConnection(); writeInt(wopAddTextToStore, to); writeString(name, to); @@ -476,7 +480,7 @@ Paths RemoteStore::importPaths(bool requireSignature, Source & source) void RemoteStore::buildPaths(const PathSet & drvPaths, bool repair) { - if (repair) throw Error("`--repair' is not supported when building through the Nix daemon"); + if (repair) throw Error("repairing is not supported when building through the Nix daemon"); openConnection(); writeInt(wopBuildPaths, to); writeStrings(drvPaths, to); diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index fe60ccb39..d23b07176 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -53,10 +53,10 @@ public: Path addToStore(const Path & srcPath, bool recursive = true, HashType hashAlgo = htSHA256, - PathFilter & filter = defaultPathFilter); + PathFilter & filter = defaultPathFilter, bool repair = false); Path addTextToStore(const string & name, const string & s, - const PathSet & references); + const PathSet & references, bool repair = false); void exportPath(const Path & path, bool sign, Sink & sink); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 800645fa4..cbbacc12c 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -158,12 +158,12 @@ public: libutil/archive.hh). */ virtual Path addToStore(const Path & srcPath, bool recursive = true, HashType hashAlgo = htSHA256, - PathFilter & filter = defaultPathFilter) = 0; + PathFilter & filter = defaultPathFilter, bool repair = false) = 0; /* Like addToStore, but the contents written to the output path is a regular file containing the given string. */ virtual Path addTextToStore(const string & name, const string & s, - const PathSet & references) = 0; + const PathSet & references, bool repair = false) = 0; /* Export a store path, that is, create a NAR dump of the store path and append its references and its deriver. Optionally, a diff --git a/src/nix-instantiate/nix-instantiate.cc b/src/nix-instantiate/nix-instantiate.cc index 6ddf9f069..34f81b14a 100644 --- a/src/nix-instantiate/nix-instantiate.cc +++ b/src/nix-instantiate/nix-instantiate.cc @@ -125,6 +125,8 @@ void run(Strings args) xmlOutputSourceLocation = false; else if (arg == "--strict") strict = true; + else if (arg == "--repair") + state.repair = true; else if (arg[0] == '-') throw UsageError(format("unknown flag `%1%'") % arg); else