Add a ‘--repair’ flag to nix-instantiate
This allows repairing corrupted derivations and other source files.
This commit is contained in:
		
							parent
							
								
									a807edfae8
								
							
						
					
					
						commit
						0a7084567f
					
				
					 11 changed files with 36 additions and 25 deletions
				
			
		|  | @ -141,6 +141,7 @@ EvalState::EvalState() | ||||||
|     , baseEnv(allocEnv(128)) |     , baseEnv(allocEnv(128)) | ||||||
|     , baseEnvDispl(0) |     , baseEnvDispl(0) | ||||||
|     , staticBaseEnv(false, 0) |     , staticBaseEnv(false, 0) | ||||||
|  |     , repair(false) | ||||||
| { | { | ||||||
|     nrEnvs = nrValuesInEnvs = nrValues = nrListElems = 0; |     nrEnvs = nrValuesInEnvs = nrValues = nrListElems = 0; | ||||||
|     nrAttrsets = nrOpUpdates = nrOpUpdateValuesCopied = 0; |     nrAttrsets = nrOpUpdates = nrOpUpdateValuesCopied = 0; | ||||||
|  | @ -1093,7 +1094,7 @@ string EvalState::coerceToString(Value & v, PathSet & context, | ||||||
|         else { |         else { | ||||||
|             dstPath = settings.readOnlyMode |             dstPath = settings.readOnlyMode | ||||||
|                 ? computeStorePathForPath(path).first |                 ? computeStorePathForPath(path).first | ||||||
|                 : store->addToStore(path); |                 : store->addToStore(path, true, htSHA256, defaultPathFilter, repair); | ||||||
|             srcToStore[path] = dstPath; |             srcToStore[path] = dstPath; | ||||||
|             printMsg(lvlChatty, format("copied source `%1%' -> `%2%'") |             printMsg(lvlChatty, format("copied source `%1%' -> `%2%'") | ||||||
|                 % path % dstPath); |                 % path % dstPath); | ||||||
|  |  | ||||||
|  | @ -95,6 +95,10 @@ public: | ||||||
|     const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, |     const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, | ||||||
|         sSystem, sOverrides; |         sSystem, sOverrides; | ||||||
| 
 | 
 | ||||||
|  |     /* If set, force copying files to the Nix store even if they
 | ||||||
|  |        already exist there. */ | ||||||
|  |     bool repair; | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     SrcToStore srcToStore;  |     SrcToStore srcToStore;  | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -487,7 +487,7 @@ static void prim_derivationStrict(EvalState & state, Value * * args, Value & v) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* Write the resulting term into the Nix store directory. */ |     /* 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%'") |     printMsg(lvlChatty, format("instantiated `%1%' -> `%2%'") | ||||||
|         % drvName % drvPath); |         % drvName % drvPath); | ||||||
|  | @ -625,7 +625,7 @@ static void prim_toFile(EvalState & state, Value * * args, Value & v) | ||||||
|      |      | ||||||
|     Path storePath = settings.readOnlyMode |     Path storePath = settings.readOnlyMode | ||||||
|         ? computeStorePathForText(name, contents, refs) |         ? 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
 |     /* Note: we don't need to add `context' to the context of the
 | ||||||
|        result, since `storePath' itself has references to the paths |        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 |     Path dstPath = settings.readOnlyMode | ||||||
|         ? computeStorePathForPath(path, true, htSHA256, filter).first |         ? computeStorePathForPath(path, true, htSHA256, filter).first | ||||||
|         : store->addToStore(path, true, htSHA256, filter); |         : store->addToStore(path, true, htSHA256, filter, state.repair); | ||||||
| 
 | 
 | ||||||
|     mkString(v, dstPath, singleton<PathSet>(dstPath)); |     mkString(v, dstPath, singleton<PathSet>(dstPath)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -27,7 +27,7 @@ void DerivationOutput::parseHashInfo(bool & recursive, HashType & hashType, Hash | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Path writeDerivation(StoreAPI & store, | Path writeDerivation(StoreAPI & store, | ||||||
|     const Derivation & drv, const string & name) |     const Derivation & drv, const string & name, bool repair) | ||||||
| { | { | ||||||
|     PathSet references; |     PathSet references; | ||||||
|     references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end()); |     references.insert(drv.inputSrcs.begin(), drv.inputSrcs.end()); | ||||||
|  | @ -40,7 +40,7 @@ Path writeDerivation(StoreAPI & store, | ||||||
|     string contents = unparseDerivation(drv); |     string contents = unparseDerivation(drv); | ||||||
|     return settings.readOnlyMode |     return settings.readOnlyMode | ||||||
|         ? computeStorePathForText(suffix, contents, references) |         ? computeStorePathForText(suffix, contents, references) | ||||||
|         : store.addTextToStore(suffix, contents, references); |         : store.addTextToStore(suffix, contents, references, repair); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -57,7 +57,7 @@ class StoreAPI; | ||||||
| 
 | 
 | ||||||
| /* Write a derivation to the Nix store, and return its path. */ | /* Write a derivation to the Nix store, and return its path. */ | ||||||
| Path writeDerivation(StoreAPI & store, | Path writeDerivation(StoreAPI & store, | ||||||
|     const Derivation & drv, const string & name); |     const Derivation & drv, const string & name, bool repair = false); | ||||||
| 
 | 
 | ||||||
| /* Parse a derivation. */ | /* Parse a derivation. */ | ||||||
| Derivation parseDerivation(const string & s); | Derivation parseDerivation(const string & s); | ||||||
|  |  | ||||||
|  | @ -1158,7 +1158,7 @@ void LocalStore::invalidatePath(const Path & path) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Path LocalStore::addToStoreFromDump(const string & dump, const string & name, | Path LocalStore::addToStoreFromDump(const string & dump, const string & name, | ||||||
|     bool recursive, HashType hashAlgo) |     bool recursive, HashType hashAlgo, bool repair) | ||||||
| { | { | ||||||
|     Hash h = hashString(hashAlgo, dump); |     Hash h = hashString(hashAlgo, dump); | ||||||
| 
 | 
 | ||||||
|  | @ -1166,14 +1166,14 @@ Path LocalStore::addToStoreFromDump(const string & dump, const string & name, | ||||||
| 
 | 
 | ||||||
|     addTempRoot(dstPath); |     addTempRoot(dstPath); | ||||||
| 
 | 
 | ||||||
|     if (!isValidPath(dstPath)) { |     if (repair || !isValidPath(dstPath)) { | ||||||
| 
 | 
 | ||||||
|         /* The first check above is an optimisation to prevent
 |         /* The first check above is an optimisation to prevent
 | ||||||
|            unnecessary lock acquisition. */ |            unnecessary lock acquisition. */ | ||||||
| 
 | 
 | ||||||
|         PathLocks outputLock(singleton<PathSet, Path>(dstPath)); |         PathLocks outputLock(singleton<PathSet, Path>(dstPath)); | ||||||
| 
 | 
 | ||||||
|         if (!isValidPath(dstPath)) { |         if (repair || !isValidPath(dstPath)) { | ||||||
| 
 | 
 | ||||||
|             if (pathExists(dstPath)) deletePathWrapped(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, | Path LocalStore::addToStore(const Path & _srcPath, | ||||||
|     bool recursive, HashType hashAlgo, PathFilter & filter) |     bool recursive, HashType hashAlgo, PathFilter & filter, bool repair) | ||||||
| { | { | ||||||
|     Path srcPath(absPath(_srcPath)); |     Path srcPath(absPath(_srcPath)); | ||||||
|     debug(format("adding `%1%' to the store") % srcPath); |     debug(format("adding `%1%' to the store") % srcPath); | ||||||
|  | @ -1227,22 +1227,22 @@ Path LocalStore::addToStore(const Path & _srcPath, | ||||||
|     else |     else | ||||||
|         sink.s = readFile(srcPath); |         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, | Path LocalStore::addTextToStore(const string & name, const string & s, | ||||||
|     const PathSet & references) |     const PathSet & references, bool repair) | ||||||
| { | { | ||||||
|     Path dstPath = computeStorePathForText(name, s, references); |     Path dstPath = computeStorePathForText(name, s, references); | ||||||
| 
 | 
 | ||||||
|     addTempRoot(dstPath); |     addTempRoot(dstPath); | ||||||
| 
 | 
 | ||||||
|     if (!isValidPath(dstPath)) { |     if (repair || !isValidPath(dstPath)) { | ||||||
| 
 | 
 | ||||||
|         PathLocks outputLock(singleton<PathSet, Path>(dstPath)); |         PathLocks outputLock(singleton<PathSet, Path>(dstPath)); | ||||||
| 
 | 
 | ||||||
|         if (!isValidPath(dstPath)) { |         if (repair || !isValidPath(dstPath)) { | ||||||
| 
 | 
 | ||||||
|             if (pathExists(dstPath)) deletePathWrapped(dstPath); |             if (pathExists(dstPath)) deletePathWrapped(dstPath); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -133,17 +133,17 @@ public: | ||||||
| 
 | 
 | ||||||
|     Path addToStore(const Path & srcPath, |     Path addToStore(const Path & srcPath, | ||||||
|         bool recursive = true, HashType hashAlgo = htSHA256, |         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
 |     /* 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 recursive = true, HashType hashAlgo = htSHA256, bool repair = false); | ||||||
| 
 | 
 | ||||||
|     Path addTextToStore(const string & name, const string & s, |     Path addTextToStore(const string & name, const string & s, | ||||||
|         const PathSet & references); |         const PathSet & references, bool repair = false); | ||||||
| 
 | 
 | ||||||
|     void exportPath(const Path & path, bool sign, |     void exportPath(const Path & path, bool sign, | ||||||
|         Sink & sink); |         Sink & sink); | ||||||
|  |  | ||||||
|  | @ -419,8 +419,10 @@ Path RemoteStore::queryPathFromHashPart(const string & hashPart) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Path RemoteStore::addToStore(const Path & _srcPath, | 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(); |     openConnection(); | ||||||
| 
 | 
 | ||||||
|     Path srcPath(absPath(_srcPath)); |     Path srcPath(absPath(_srcPath)); | ||||||
|  | @ -438,8 +440,10 @@ Path RemoteStore::addToStore(const Path & _srcPath, | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Path RemoteStore::addTextToStore(const string & name, const string & s, | 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(); |     openConnection(); | ||||||
|     writeInt(wopAddTextToStore, to); |     writeInt(wopAddTextToStore, to); | ||||||
|     writeString(name, to); |     writeString(name, to); | ||||||
|  | @ -476,7 +480,7 @@ Paths RemoteStore::importPaths(bool requireSignature, Source & source) | ||||||
| 
 | 
 | ||||||
| void RemoteStore::buildPaths(const PathSet & drvPaths, bool repair) | 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(); |     openConnection(); | ||||||
|     writeInt(wopBuildPaths, to); |     writeInt(wopBuildPaths, to); | ||||||
|     writeStrings(drvPaths, to); |     writeStrings(drvPaths, to); | ||||||
|  |  | ||||||
|  | @ -53,10 +53,10 @@ public: | ||||||
|      |      | ||||||
|     Path addToStore(const Path & srcPath, |     Path addToStore(const Path & srcPath, | ||||||
|         bool recursive = true, HashType hashAlgo = htSHA256, |         bool recursive = true, HashType hashAlgo = htSHA256, | ||||||
|         PathFilter & filter = defaultPathFilter); |         PathFilter & filter = defaultPathFilter, bool repair = false); | ||||||
| 
 | 
 | ||||||
|     Path addTextToStore(const string & name, const string & s, |     Path addTextToStore(const string & name, const string & s, | ||||||
|         const PathSet & references); |         const PathSet & references, bool repair = false); | ||||||
| 
 | 
 | ||||||
|     void exportPath(const Path & path, bool sign, |     void exportPath(const Path & path, bool sign, | ||||||
|         Sink & sink); |         Sink & sink); | ||||||
|  |  | ||||||
|  | @ -158,12 +158,12 @@ public: | ||||||
|        libutil/archive.hh). */ |        libutil/archive.hh). */ | ||||||
|     virtual Path addToStore(const Path & srcPath, |     virtual Path addToStore(const Path & srcPath, | ||||||
|         bool recursive = true, HashType hashAlgo = htSHA256, |         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
 |     /* 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) = 0; |         const PathSet & references, bool repair = false) = 0; | ||||||
| 
 | 
 | ||||||
|     /* Export a store path, that is, create a NAR dump of the store
 |     /* Export a store path, that is, create a NAR dump of the store
 | ||||||
|        path and append its references and its deriver.  Optionally, a |        path and append its references and its deriver.  Optionally, a | ||||||
|  |  | ||||||
|  | @ -125,6 +125,8 @@ void run(Strings args) | ||||||
|             xmlOutputSourceLocation = false; |             xmlOutputSourceLocation = false; | ||||||
|         else if (arg == "--strict") |         else if (arg == "--strict") | ||||||
|             strict = true; |             strict = true; | ||||||
|  |         else if (arg == "--repair") | ||||||
|  |             state.repair = true; | ||||||
|         else if (arg[0] == '-') |         else if (arg[0] == '-') | ||||||
|             throw UsageError(format("unknown flag `%1%'") % arg); |             throw UsageError(format("unknown flag `%1%'") % arg); | ||||||
|         else |         else | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue