1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-25 11:49:35 +01:00

Merge pull request #13765 from obsidiansystems/simplify-derivation-building-goal

Simplify `DerivationBuildingGoal`
This commit is contained in:
John Ericson 2025-08-15 16:19:44 -04:00 committed by GitHub
commit 97c966cc69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 30 additions and 52 deletions

View file

@ -157,9 +157,7 @@ Goal::Co DerivationBuildingGoal::gaveUpOnSubstitution()
we care about all outputs. */ we care about all outputs. */
auto outputHashes = staticOutputHashes(worker.evalStore, *drv); auto outputHashes = staticOutputHashes(worker.evalStore, *drv);
for (auto & [outputName, outputHash] : outputHashes) { for (auto & [outputName, outputHash] : outputHashes) {
InitialOutput v{ InitialOutput v{.outputHash = outputHash};
.wanted = true, // Will be refined later
.outputHash = outputHash};
/* TODO we might want to also allow randomizing the paths /* TODO we might want to also allow randomizing the paths
for regular CA derivations, e.g. for sake of checking for regular CA derivations, e.g. for sake of checking
@ -675,10 +673,13 @@ Goal::Co DerivationBuildingGoal::tryToBuild()
} }
}; };
auto * localStoreP = dynamic_cast<LocalStore *>(&worker.store);
assert(localStoreP);
/* If we have to wait and retry (see below), then `builder` will /* If we have to wait and retry (see below), then `builder` will
already be created, so we don't need to create it again. */ already be created, so we don't need to create it again. */
builder = makeDerivationBuilder( builder = makeDerivationBuilder(
worker.store, *localStoreP,
std::make_unique<DerivationBuildingGoalCallbacks>(*this, builder), std::make_unique<DerivationBuildingGoalCallbacks>(*this, builder),
DerivationBuilderParams{ DerivationBuilderParams{
drvPath, drvPath,
@ -1202,7 +1203,6 @@ std::pair<bool, SingleDrvOutputs> DerivationBuildingGoal::checkPathValidity()
// this is an invalid output, gets caught with (!wantedOutputsLeft.empty()) // this is an invalid output, gets caught with (!wantedOutputsLeft.empty())
continue; continue;
auto & info = *initialOutput; auto & info = *initialOutput;
info.wanted = true;
if (i.second) { if (i.second) {
auto outputPath = *i.second; auto outputPath = *i.second;
info.known = { info.known = {
@ -1237,8 +1237,6 @@ std::pair<bool, SingleDrvOutputs> DerivationBuildingGoal::checkPathValidity()
bool allValid = true; bool allValid = true;
for (auto & [_, status] : initialOutputs) { for (auto & [_, status] : initialOutputs) {
if (!status.wanted)
continue;
if (!status.known || !status.known->isValid()) { if (!status.known || !status.known->isValid()) {
allValid = false; allValid = false;
break; break;

View file

@ -45,7 +45,6 @@ struct InitialOutputStatus
struct InitialOutput struct InitialOutput
{ {
bool wanted;
Hash outputHash; Hash outputHash;
std::optional<InitialOutputStatus> known; std::optional<InitialOutputStatus> known;
}; };

View file

@ -5,7 +5,7 @@ namespace nix {
struct ChrootDerivationBuilder : virtual DerivationBuilderImpl struct ChrootDerivationBuilder : virtual DerivationBuilderImpl
{ {
ChrootDerivationBuilder( ChrootDerivationBuilder(
Store & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params) LocalStore & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params)
: DerivationBuilderImpl{store, std::move(miscMethods), std::move(params)} : DerivationBuilderImpl{store, std::move(miscMethods), std::move(params)}
{ {
} }
@ -178,7 +178,7 @@ struct ChrootDerivationBuilder : virtual DerivationBuilderImpl
continue; continue;
if (buildMode != bmCheck && status.known->isValid()) if (buildMode != bmCheck && status.known->isValid())
continue; continue;
auto p = store.toRealPath(status.known->path); auto p = store.Store::toRealPath(status.known->path);
if (pathExists(chrootRootDir + p)) if (pathExists(chrootRootDir + p))
std::filesystem::rename((chrootRootDir + p), p); std::filesystem::rename((chrootRootDir + p), p);
} }

View file

@ -21,7 +21,7 @@ struct DarwinDerivationBuilder : DerivationBuilderImpl
bool useSandbox; bool useSandbox;
DarwinDerivationBuilder( DarwinDerivationBuilder(
Store & store, LocalStore & store,
std::unique_ptr<DerivationBuilderCallbacks> miscMethods, std::unique_ptr<DerivationBuilderCallbacks> miscMethods,
DerivationBuilderParams params, DerivationBuilderParams params,
bool useSandbox) bool useSandbox)

View file

@ -61,14 +61,14 @@ class DerivationBuilderImpl : public DerivationBuilder, public DerivationBuilder
{ {
protected: protected:
Store & store; LocalStore & store;
std::unique_ptr<DerivationBuilderCallbacks> miscMethods; std::unique_ptr<DerivationBuilderCallbacks> miscMethods;
public: public:
DerivationBuilderImpl( DerivationBuilderImpl(
Store & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params) LocalStore & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params)
: DerivationBuilderParams{std::move(params)} : DerivationBuilderParams{std::move(params)}
, store{store} , store{store}
, miscMethods{std::move(miscMethods)} , miscMethods{std::move(miscMethods)}
@ -424,13 +424,6 @@ void handleDiffHook(
const Path DerivationBuilderImpl::homeDir = "/homeless-shelter"; const Path DerivationBuilderImpl::homeDir = "/homeless-shelter";
static LocalStore & getLocalStore(Store & store)
{
auto p = dynamic_cast<LocalStore *>(&store);
assert(p);
return *p;
}
void DerivationBuilderImpl::killSandbox(bool getStats) void DerivationBuilderImpl::killSandbox(bool getStats)
{ {
if (buildUser) { if (buildUser) {
@ -631,10 +624,9 @@ bool DerivationBuilderImpl::decideWhetherDiskFull()
so, we don't mark this build as a permanent failure. */ so, we don't mark this build as a permanent failure. */
#if HAVE_STATVFS #if HAVE_STATVFS
{ {
auto & localStore = getLocalStore(store);
uint64_t required = 8ULL * 1024 * 1024; // FIXME: make configurable uint64_t required = 8ULL * 1024 * 1024; // FIXME: make configurable
struct statvfs st; struct statvfs st;
if (statvfs(localStore.config->realStoreDir.get().c_str(), &st) == 0 if (statvfs(store.config->realStoreDir.get().c_str(), &st) == 0
&& (uint64_t) st.f_bavail * st.f_bsize < required) && (uint64_t) st.f_bavail * st.f_bsize < required)
diskFull = true; diskFull = true;
if (statvfs(tmpDir.c_str(), &st) == 0 && (uint64_t) st.f_bavail * st.f_bsize < required) if (statvfs(tmpDir.c_str(), &st) == 0 && (uint64_t) st.f_bavail * st.f_bsize < required)
@ -712,7 +704,7 @@ void DerivationBuilderImpl::startBuilder()
Magenta(drv.platform), Magenta(drv.platform),
concatStringsSep(", ", drvOptions.getRequiredSystemFeatures(drv)), concatStringsSep(", ", drvOptions.getRequiredSystemFeatures(drv)),
Magenta(settings.thisSystem), Magenta(settings.thisSystem),
concatStringsSep<StringSet>(", ", store.config.systemFeatures)); concatStringsSep<StringSet>(", ", store.Store::config.systemFeatures));
// since aarch64-darwin has Rosetta 2, this user can actually run x86_64-darwin on their hardware - we should // since aarch64-darwin has Rosetta 2, this user can actually run x86_64-darwin on their hardware - we should
// tell them to run the command to install Darwin 2 // tell them to run the command to install Darwin 2
@ -724,7 +716,7 @@ void DerivationBuilderImpl::startBuilder()
throw BuildError(msg); throw BuildError(msg);
} }
auto buildDir = getLocalStore(store).config->getBuildDir(); auto buildDir = store.config->getBuildDir();
createDirs(buildDir); createDirs(buildDir);
@ -1173,7 +1165,7 @@ void DerivationBuilderImpl::startDaemon()
auto store = makeRestrictedStore( auto store = makeRestrictedStore(
[&] { [&] {
auto config = make_ref<LocalStore::Config>(*getLocalStore(this->store).config); auto config = make_ref<LocalStore::Config>(*this->store.config);
config->pathInfoCacheSize = 0; config->pathInfoCacheSize = 0;
config->stateDir = "/no-such-path"; config->stateDir = "/no-such-path";
config->logDir = "/no-such-path"; config->logDir = "/no-such-path";
@ -1430,8 +1422,6 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
outputs to allow hard links between outputs. */ outputs to allow hard links between outputs. */
InodesSeen inodesSeen; InodesSeen inodesSeen;
Path checkSuffix = ".check";
std::exception_ptr delayedException; std::exception_ptr delayedException;
/* The paths that can be referenced are the input closures, the /* The paths that can be referenced are the input closures, the
@ -1466,23 +1456,19 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
std::map<std::string, struct stat> outputStats; std::map<std::string, struct stat> outputStats;
for (auto & [outputName, _] : drv.outputs) { for (auto & [outputName, _] : drv.outputs) {
auto scratchOutput = get(scratchOutputs, outputName); auto scratchOutput = get(scratchOutputs, outputName);
if (!scratchOutput) assert(scratchOutput);
throw BuildError(
"builder for '%s' has no scratch output for '%s'", store.printStorePath(drvPath), outputName);
auto actualPath = realPathInSandbox(store.printStorePath(*scratchOutput)); auto actualPath = realPathInSandbox(store.printStorePath(*scratchOutput));
outputsToSort.insert(outputName); outputsToSort.insert(outputName);
/* Updated wanted info to remove the outputs we definitely don't need to register */ /* Updated wanted info to remove the outputs we definitely don't need to register */
auto initialOutput = get(initialOutputs, outputName); auto initialOutput = get(initialOutputs, outputName);
if (!initialOutput) assert(initialOutput);
throw BuildError(
"builder for '%s' has no initial output for '%s'", store.printStorePath(drvPath), outputName);
auto & initialInfo = *initialOutput; auto & initialInfo = *initialOutput;
/* Don't register if already valid, and not checking */ /* Don't register if already valid, and not checking */
initialInfo.wanted = buildMode == bmCheck || !(initialInfo.known && initialInfo.known->isValid()); bool wanted = buildMode == bmCheck || !(initialInfo.known && initialInfo.known->isValid());
if (!initialInfo.wanted) { if (!wanted) {
outputReferencesIfUnregistered.insert_or_assign( outputReferencesIfUnregistered.insert_or_assign(
outputName, AlreadyRegistered{.path = initialInfo.known->path}); outputName, AlreadyRegistered{.path = initialInfo.known->path});
continue; continue;
@ -1839,8 +1825,6 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
} }
} }
auto & localStore = getLocalStore(store);
if (buildMode == bmCheck) { if (buildMode == bmCheck) {
if (!store.isValidPath(newInfo.path)) if (!store.isValidPath(newInfo.path))
@ -1849,7 +1833,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
if (newInfo.narHash != oldInfo.narHash) { if (newInfo.narHash != oldInfo.narHash) {
miscMethods->noteCheckMismatch(); miscMethods->noteCheckMismatch();
if (settings.runDiffHook || settings.keepFailed) { if (settings.runDiffHook || settings.keepFailed) {
auto dst = store.toRealPath(finalDestPath + checkSuffix); auto dst = store.toRealPath(finalDestPath + ".check");
deletePath(dst); deletePath(dst);
movePath(actualPath, dst); movePath(actualPath, dst);
@ -1876,8 +1860,8 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
/* Since we verified the build, it's now ultimately trusted. */ /* Since we verified the build, it's now ultimately trusted. */
if (!oldInfo.ultimate) { if (!oldInfo.ultimate) {
oldInfo.ultimate = true; oldInfo.ultimate = true;
localStore.signPathInfo(oldInfo); store.signPathInfo(oldInfo);
localStore.registerValidPaths({{oldInfo.path, oldInfo}}); store.registerValidPaths({{oldInfo.path, oldInfo}});
} }
continue; continue;
@ -1891,12 +1875,12 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
debug("unreferenced input: '%1%'", store.printStorePath(i)); debug("unreferenced input: '%1%'", store.printStorePath(i));
} }
localStore.optimisePath(actualPath, NoRepair); // FIXME: combine with scanForReferences() store.optimisePath(actualPath, NoRepair); // FIXME: combine with scanForReferences()
miscMethods->markContentsGood(newInfo.path); miscMethods->markContentsGood(newInfo.path);
newInfo.deriver = drvPath; newInfo.deriver = drvPath;
newInfo.ultimate = true; newInfo.ultimate = true;
localStore.signPathInfo(newInfo); store.signPathInfo(newInfo);
finish(newInfo.path); finish(newInfo.path);
@ -1904,7 +1888,7 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
isn't statically known so that we can safely unlock the path before isn't statically known so that we can safely unlock the path before
the next iteration */ the next iteration */
if (newInfo.ca) if (newInfo.ca)
localStore.registerValidPaths({{newInfo.path, newInfo}}); store.registerValidPaths({{newInfo.path, newInfo}});
infos.emplace(outputName, std::move(newInfo)); infos.emplace(outputName, std::move(newInfo));
} }
@ -1925,13 +1909,11 @@ SingleDrvOutputs DerivationBuilderImpl::registerOutputs()
paths referenced by each of them. If there are cycles in the paths referenced by each of them. If there are cycles in the
outputs, this will fail. */ outputs, this will fail. */
{ {
auto & localStore = getLocalStore(store);
ValidPathInfos infos2; ValidPathInfos infos2;
for (auto & [outputName, newInfo] : infos) { for (auto & [outputName, newInfo] : infos) {
infos2.insert_or_assign(newInfo.path, newInfo); infos2.insert_or_assign(newInfo.path, newInfo);
} }
localStore.registerValidPaths(infos2); store.registerValidPaths(infos2);
} }
/* In case of a fixed-output derivation hash mismatch, throw an /* In case of a fixed-output derivation hash mismatch, throw an
@ -2164,7 +2146,7 @@ StorePath DerivationBuilderImpl::makeFallbackPath(const StorePath & path)
namespace nix { namespace nix {
std::unique_ptr<DerivationBuilder> makeDerivationBuilder( std::unique_ptr<DerivationBuilder> makeDerivationBuilder(
Store & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params) LocalStore & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params)
{ {
bool useSandbox = false; bool useSandbox = false;
@ -2191,8 +2173,7 @@ std::unique_ptr<DerivationBuilder> makeDerivationBuilder(
useSandbox = params.drv.type().isSandboxed() && !params.drvOptions.noChroot; useSandbox = params.drv.type().isSandboxed() && !params.drvOptions.noChroot;
} }
auto & localStore = getLocalStore(store); if (store.storeDir != store.config->realStoreDir.get()) {
if (localStore.storeDir != localStore.config->realStoreDir.get()) {
#ifdef __linux__ #ifdef __linux__
useSandbox = true; useSandbox = true;
#else #else

View file

@ -191,7 +191,7 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu
std::optional<Path> cgroup; std::optional<Path> cgroup;
ChrootLinuxDerivationBuilder( ChrootLinuxDerivationBuilder(
Store & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params) LocalStore & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params)
: DerivationBuilderImpl{store, std::move(miscMethods), std::move(params)} : DerivationBuilderImpl{store, std::move(miscMethods), std::move(params)}
, ChrootDerivationBuilder{store, std::move(miscMethods), std::move(params)} , ChrootDerivationBuilder{store, std::move(miscMethods), std::move(params)}
, LinuxDerivationBuilder{store, std::move(miscMethods), std::move(params)} , LinuxDerivationBuilder{store, std::move(miscMethods), std::move(params)}
@ -492,7 +492,7 @@ struct ChrootLinuxDerivationBuilder : ChrootDerivationBuilder, LinuxDerivationBu
createDirs(chrootRootDir + "/dev/shm"); createDirs(chrootRootDir + "/dev/shm");
createDirs(chrootRootDir + "/dev/pts"); createDirs(chrootRootDir + "/dev/pts");
ss.push_back("/dev/full"); ss.push_back("/dev/full");
if (store.config.systemFeatures.get().count("kvm") && pathExists("/dev/kvm")) if (store.Store::config.systemFeatures.get().count("kvm") && pathExists("/dev/kvm"))
ss.push_back("/dev/kvm"); ss.push_back("/dev/kvm");
ss.push_back("/dev/null"); ss.push_back("/dev/null");
ss.push_back("/dev/random"); ss.push_back("/dev/random");

View file

@ -179,6 +179,6 @@ struct DerivationBuilder : RestrictionContext
}; };
std::unique_ptr<DerivationBuilder> makeDerivationBuilder( std::unique_ptr<DerivationBuilder> makeDerivationBuilder(
Store & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params); LocalStore & store, std::unique_ptr<DerivationBuilderCallbacks> miscMethods, DerivationBuilderParams params);
} // namespace nix } // namespace nix