build: add exit code for hash and check mismatches
Makes it easier to identify the failure reason in other tooling, eg. differentiate between a non-deterministic --check vs a failed build. $ nix-build '<nix/fetchurl.nix>' --argstr url http://example.org --argstr sha256 0000000000000000000000000000000000000000000000000000 hash mismatch in fixed-output derivation '/nix/store/nzi9ck45rwlxzcwr25is7qlf3hs5xl83-example.org': wanted: sha256:0000000000000000000000000000000000000000000000000000 got: sha256:08y4734bm2zahw75b16bcmcg587vvyvh0n11gwiyir70divwp1rm $ echo $? 102 $ nix-build -E 'with import <nixpkgs> {}; runCommand "foo" {} "date +%s > $out"' --check warning: rewriting hashes in '/nix/store/g3k47g0399fvjmbm0p0mnad74k4w8vkz-foo'; cross fingers error: derivation '/nix/store/mggc8dz13ackb49qca6m23zq4fpq132q-foo.drv' may not be deterministic: output '/nix/store/g3k47g0399fvjmbm0p0mnad74k4w8vkz-foo' differs $ echo $? 104
This commit is contained in:
parent
5c8f477283
commit
97baf32fbc
2 changed files with 15 additions and 4 deletions
|
@ -266,6 +266,12 @@ public:
|
||||||
/* Set if at least one derivation had a timeout. */
|
/* Set if at least one derivation had a timeout. */
|
||||||
bool timedOut;
|
bool timedOut;
|
||||||
|
|
||||||
|
/* Set if at least one derivation fails with a hash mismatch. */
|
||||||
|
bool hashMismatch;
|
||||||
|
|
||||||
|
/* Set if at least one derivation is not deterministic in check mode. */
|
||||||
|
bool checkMismatch;
|
||||||
|
|
||||||
LocalStore & store;
|
LocalStore & store;
|
||||||
|
|
||||||
std::unique_ptr<HookInstance> hook;
|
std::unique_ptr<HookInstance> hook;
|
||||||
|
@ -3213,6 +3219,7 @@ void DerivationGoal::registerOutputs()
|
||||||
|
|
||||||
/* Throw an error after registering the path as
|
/* Throw an error after registering the path as
|
||||||
valid. */
|
valid. */
|
||||||
|
worker.hashMismatch = true;
|
||||||
delayedException = std::make_exception_ptr(
|
delayedException = std::make_exception_ptr(
|
||||||
BuildError("hash mismatch in fixed-output derivation '%s':\n wanted: %s\n got: %s",
|
BuildError("hash mismatch in fixed-output derivation '%s':\n wanted: %s\n got: %s",
|
||||||
dest, h.to_string(), h2.to_string()));
|
dest, h.to_string(), h2.to_string()));
|
||||||
|
@ -3255,6 +3262,7 @@ void DerivationGoal::registerOutputs()
|
||||||
if (!worker.store.isValidPath(path)) continue;
|
if (!worker.store.isValidPath(path)) continue;
|
||||||
auto info = *worker.store.queryPathInfo(path);
|
auto info = *worker.store.queryPathInfo(path);
|
||||||
if (hash.first != info.narHash) {
|
if (hash.first != info.narHash) {
|
||||||
|
worker.checkMismatch = true;
|
||||||
if (settings.runDiffHook || settings.keepFailed) {
|
if (settings.runDiffHook || settings.keepFailed) {
|
||||||
Path dst = worker.store.toRealPath(path + checkSuffix);
|
Path dst = worker.store.toRealPath(path + checkSuffix);
|
||||||
deletePath(dst);
|
deletePath(dst);
|
||||||
|
@ -3266,10 +3274,10 @@ void DerivationGoal::registerOutputs()
|
||||||
buildUser ? buildUser->getGID() : getgid(),
|
buildUser ? buildUser->getGID() : getgid(),
|
||||||
path, dst, drvPath, tmpDir);
|
path, dst, drvPath, tmpDir);
|
||||||
|
|
||||||
throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs from '%3%'")
|
throw NotDeterministic(format("derivation '%1%' may not be deterministic: output '%2%' differs from '%3%'")
|
||||||
% drvPath % path % dst);
|
% drvPath % path % dst);
|
||||||
} else
|
} else
|
||||||
throw Error(format("derivation '%1%' may not be deterministic: output '%2%' differs")
|
throw NotDeterministic(format("derivation '%1%' may not be deterministic: output '%2%' differs")
|
||||||
% drvPath % path);
|
% drvPath % path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4101,6 +4109,8 @@ Worker::Worker(LocalStore & store)
|
||||||
lastWokenUp = steady_time_point::min();
|
lastWokenUp = steady_time_point::min();
|
||||||
permanentFailure = false;
|
permanentFailure = false;
|
||||||
timedOut = false;
|
timedOut = false;
|
||||||
|
hashMismatch = false;
|
||||||
|
checkMismatch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4461,7 +4471,7 @@ void Worker::waitForInput()
|
||||||
|
|
||||||
unsigned int Worker::exitStatus()
|
unsigned int Worker::exitStatus()
|
||||||
{
|
{
|
||||||
return timedOut ? 101 : (permanentFailure ? 100 : 1);
|
return checkMismatch ? 104 : (hashMismatch ? 102 : (timedOut ? 101 : (permanentFailure ? 100 : 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -855,10 +855,11 @@ CachedDownloadResult Downloader::downloadCached(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedStorePath != "" && storePath != expectedStorePath) {
|
if (expectedStorePath != "" && storePath != expectedStorePath) {
|
||||||
|
unsigned int statusCode = 102;
|
||||||
Hash gotHash = request.unpack
|
Hash gotHash = request.unpack
|
||||||
? hashPath(request.expectedHash.type, store->toRealPath(storePath)).first
|
? hashPath(request.expectedHash.type, store->toRealPath(storePath)).first
|
||||||
: hashFile(request.expectedHash.type, store->toRealPath(storePath));
|
: hashFile(request.expectedHash.type, store->toRealPath(storePath));
|
||||||
throw nix::Error("hash mismatch in file downloaded from '%s':\n wanted: %s\n got: %s",
|
throw nix::Error(statusCode, "hash mismatch in file downloaded from '%s':\n wanted: %s\n got: %s",
|
||||||
url, request.expectedHash.to_string(), gotHash.to_string());
|
url, request.expectedHash.to_string(), gotHash.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue