1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-14 04:51:05 +01:00

Merge pull request #13858 from obsidiansystems/no-more-defered-exception

Get rid of `delayedException` in `DerivationBuilder`
This commit is contained in:
Jörg Thalheim 2025-09-01 20:11:51 +02:00 committed by GitHub
commit dc29cdf66d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 133 additions and 119 deletions

View file

@ -653,16 +653,6 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
goal.worker.childTerminated(&goal);
}
void noteHashMismatch() override
{
goal.worker.hashMismatch = true;
}
void noteCheckMismatch() override
{
goal.worker.checkMismatch = true;
}
void markContentsGood(const StorePath & path) override
{
goal.worker.markContentsGood(path);
@ -770,6 +760,26 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
// N.B. cannot use `std::visit` with co-routine return
if (auto * ste = std::get_if<0>(&res)) {
outputLocks.unlock();
// Allow selecting a subset of enum values
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wswitch-enum"
switch (ste->status) {
case BuildResult::HashMismatch:
worker.hashMismatch = true;
/* See header, the protocols don't know about `HashMismatch`
yet, so change it to `OutputRejected`, which they expect
for this case (hash mismatch is a type of output
rejection). */
ste->status = BuildResult::OutputRejected;
break;
case BuildResult::NotDeterministic:
worker.checkMismatch = true;
break;
default:
/* Other statuses need no adjusting */
break;
}
# pragma GCC diagnostic pop
co_return doneFailure(std::move(*ste));
} else if (auto * builtOutputs = std::get_if<1>(&res)) {
StorePathSet outputPaths;

View file

@ -10,6 +10,7 @@ namespace nix {
void checkOutputs(
Store & store,
const StorePath & drvPath,
const decltype(Derivation::outputs) & drvOutputs,
const decltype(DerivationOptions::outputChecks) & outputChecks,
const std::map<std::string, ValidPathInfo> & outputs)
{
@ -17,9 +18,37 @@ void checkOutputs(
for (auto & output : outputs)
outputsByPath.emplace(store.printStorePath(output.second.path), output.second);
for (auto & output : outputs) {
auto & outputName = output.first;
auto & info = output.second;
for (auto & [outputName, info] : outputs) {
auto * outputSpec = get(drvOutputs, outputName);
assert(outputSpec);
if (const auto * dof = std::get_if<DerivationOutput::CAFixed>(&outputSpec->raw)) {
auto & wanted = dof->ca.hash;
/* Check wanted hash */
assert(info.ca);
auto & got = info.ca->hash;
if (wanted != got) {
/* Throw an error after registering the path as
valid. */
throw BuildError(
BuildResult::HashMismatch,
"hash mismatch in fixed-output derivation '%s':\n specified: %s\n got: %s",
store.printStorePath(drvPath),
wanted.to_string(HashFormat::SRI, true),
got.to_string(HashFormat::SRI, true));
}
if (!info.references.empty()) {
auto numViolations = info.references.size();
throw BuildError(
BuildResult::HashMismatch,
"fixed-output derivations must not reference store paths: '%s' references %d distinct paths, e.g. '%s'",
store.printStorePath(drvPath),
numViolations,
store.printStorePath(*info.references.begin()));
}
}
/* Compute the closure and closure size of some output. This
is slightly tricky because some of its references (namely

View file

@ -20,6 +20,7 @@ namespace nix {
void checkOutputs(
Store & store,
const StorePath & drvPath,
const decltype(Derivation::outputs) & drvOutputs,
const decltype(DerivationOptions::outputChecks) & drvOptions,
const std::map<std::string, ValidPathInfo> & outputs);