forked from lix-project/lix
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…
Reference in a new issue