Skip to content

Derivation builder refactor#15302

Draft
amaanq wants to merge 15 commits intoNixOS:masterfrom
obsidiansystems:drv-builder-raii
Draft

Derivation builder refactor#15302
amaanq wants to merge 15 commits intoNixOS:masterfrom
obsidiansystems:drv-builder-raii

Conversation

@amaanq
Copy link
Member

@amaanq amaanq commented Feb 20, 2026

Motivation

We want to clean up the code around derivation builders and make it easier to add addl support for windows and other oses in the future


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@github-actions github-actions bot added the new-cli Relating to the "nix" command label Feb 20, 2026
@amaanq amaanq force-pushed the drv-builder-raii branch 9 times, most recently from 82cd254 to 4716030 Compare March 9, 2026 00:46
@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Mar 9, 2026
@amaanq amaanq force-pushed the drv-builder-raii branch from 4716030 to 5b2d842 Compare March 9, 2026 05:41
amaanq and others added 14 commits March 10, 2026 00:34
This shrinks the big derivation builder compilation unit, and hopefully
puts on on the road to being able to do all derivation builder cleanup
with RAII.
This is what we do for other OS-specific functionality.
…erface

Add a virtual `cleanupOnDestruction() noexcept` method to `DerivationBuilder`.
This is needed so that `DerivationBuilderDeleter` can call it directly on any
`DerivationBuilder` pointer without requiring a `dynamic_cast` to
`DerivationBuilderImpl`. `DerivationBuilderImpl` overrides it with the
existing cleanup logic.
Move the identical setupSeccomp function from both
linux-derivation-builder.cc and linux-chroot-derivation-builder.cc
into a new shared file to eliminate code duplication.
Once per impl, that is.

This hopefully makes the code easier to read.
Convert `tmpDirFd`, `inputRewrites`, and `outputRewrites` from member
fields to local variables since they are only used within a single method:

- `tmpDirFd` is only used in `startBuild()`
- `inputRewrites` is only used in `startBuild()`
- `outputRewrites` is only used in `unprepareBuild()`

Applied to all four builder implementations.

TODO there are more variables like this which can be converted.
The five builder files (`generic-unix`, `linux`, `linux-chroot`, `darwin`,
`external`) contained massive duplication: identical `computeScratchOutputs`
loops, `stopDaemon` methods, `processSandboxSetupMessages` blocks,
`setupRecursiveNixDaemon` code, PTY setup, AWS credential resolution,
builtin builder dispatch, privilege dropping, `execve` wrappers, disk
space checks, `unprepareBuild` preambles, cleanup logic, impure path
validation, and pre-build hook parsing.

This commit extracts all of these into free functions in
`derivation-builder-common.{cc,hh}`. Each builder now calls the common
functions, keeping only platform-specific logic inline. The `inputRewrites`,
`outputRewrites`, and `tmpDirFd` locals are promoted to fields so that
the extracted functions can access them without excessive parameter counts.
Replaces the `stopDaemon` and `setupRecursiveNixDaemon` free functions with
a `RecursiveNixDaemon` struct whose `stop()` and `start()` methods reference
`socket`, `thread`, and `workerThreads` as members. The 3 duplicated fields
in all 5 derivation builder implementations collapse to a single
`RecursiveNixDaemon daemon` member. Also folds remaining single-use locals
(`env`, `inputRewrites`, `tmpDirFd`, etc.) back into the functions that use
them and removes dead declarations from the builder headers.
Gives `RestrictionContext` a stored reference to the input paths and
provides non-virtual `originalPaths()`, `isAllowed()`, and a default
`addDependencyImpl()`. This removes identical boilerplate from all 5
derivation builders: `originalPaths()`, both `isAllowed()` overrides,
`addDependencyImpl()`, and the unnecessary `friend struct RestrictedStore`
declaration. `LinuxChrootDerivationBuilder` keeps its `addDependencyImpl`
override for bind-mounting, delegating to the base implementation.
`RecursiveNixDaemon::start()` drops two redundant parameters (`params`,
`addedPaths`) now reachable through the `DerivationBuilder` reference.
@amaanq amaanq force-pushed the drv-builder-raii branch from 5b2d842 to 55c9872 Compare March 10, 2026 04:48
@amaanq amaanq force-pushed the drv-builder-raii branch from 55c9872 to 6b6294d Compare March 10, 2026 05:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new-cli Relating to the "nix" command with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants