Skip to content

Merge master into nix-next - #1844

Open
github-actions[bot] wants to merge 29 commits into
nix-nextfrom
master
Open

Merge master into nix-next#1844
github-actions[bot] wants to merge 29 commits into
nix-nextfrom
master

Conversation

@github-actions

Copy link
Copy Markdown

Automated PR to keep nix-next in sync with master.

artemist and others added 29 commits July 23, 2026 13:39
Noticed this error while debugging something else, broke cpu load
measurement.
Bumps [nix](https://github.com/NixOS/nix) from `aa2613f` to `4969304`.
- [Commits](NixOS/nix@aa2613f...4969304)

---
updated-dependencies:
- dependency-name: nix
  dependency-version: 4969304fd81c9bf498d94b82cf2ea651594e0c26
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [nixpkgs](https://github.com/NixOS/nixpkgs) from `a50de1b` to `8623c4c`.
- [Commits](https://github.com/NixOS/nixpkgs/commits)

---
updated-dependencies:
- dependency-name: nixpkgs
  dependency-version: 8623c4c20aa4ca2f5fb81510d2944066c3fb0d96
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Since db55968, we don't need to
snapshot the *current* schema, since we already have it. We just need to
snapshot historical schemas. This makes the process of writing a new
migration slightly less onerous: there is no need to keep a just-changed
file and a copy in sync, whereas vendoring the old schema version is
low-effort because by definition it should not be changing!
Update SQL readme to reflect laxer old schema snapshot rules
…fig file

The builder took every tuning knob as a `--flag`, so the NixOS and
Darwin modules reconstructed a dozen-argument `ExecStart` and each
setting existed twice: once as a module option, once as a CLI flag. The
queue runner already solved this with a `--config-path` TOML file; the
builder now follows the same shape.

`config.rs` splits into three concerns:

- `Args` (the clap entry point) carries only `--config-path`, which is
  meta-config locating the file, plus a flattened `Cli`.

- `Cli` keeps the connection/security options that don't belong in a
  world-readable config file: gateway endpoint, mTLS cert paths, auth
  token.

- `AppConfig` (serde, `camelCase`, `deny_unknown_fields`) holds the
  operational settings, each defaulting to the old clap default, so a
  missing file behaves exactly as before.

`systems` and `supportedFeatures` stay `Option`: absent means "read from
`nix show-config`", an explicit `[]` means "advertise none" — the
modules type them as `nullOr (listOf ...)` so that distinction survives
into the generated TOML. It was unclear how to take advantage of this
`None` for `Some([])` distinction before --- certainly the old NixOS
module was not doing it.

The modules now generate `/etc/hydra/builder.toml` with
`pkgs.formats.toml` and pass only the connection/security flags.

This also drops the old `--use-substitutes` always-on bug: the modules
guarded it with `useSubstitutes != null`, always true for a non-null
bool, so the option never actually took effect.
hydra-builder: move operational settings from CLI flags to a TOML config file
Soon, we're going to make a new build step page which will share a
number of things with the build page.

In order to get ready for that, extract the following into a new
`build-common.tt` for reuse:

- `renderOutputs`
- `renderOutputsTable`
- `renderStepStatus`
- `renderStepDuration`
- `renderStepMachine`
- `renderLogButtons`

Likewise, move the `showLog` helper out of `Build.pm` into
`Hydra::Helper::LogEndpoints`. Both are needed by the BuildStep
controller introduced in a later commit.

As a bonus, the new `renderLogButtons` is already used twice within
`build.tt` itself (for the build log and the runcommand log),
deduplicating previously identical button markup.

No behavior changes, except one fix that falls out of the
deduplication: the runcommand log "raw" and "tail" buttons previously
had broken markup (the `/raw` and `/tail` suffixes ended up outside
the `href` attribute), so all three buttons linked to the pretty log
page. Using `renderLogButtons` fixes those links.
Build steps are, in my view, an important concept that Hydra doesn't
yet give enough attention. This is my attempt to rectify that.

A new detail page at `/build/:id/step/:stepnr` shows output paths,
derivation, system, machine, duration, status, and log links, reusing
the shared blocks extracted in the previous commit. Clicking anywhere in
the build steps table row now navigates to this page, instead of the
step log page. The step log pages also have a link back to this page.

Also reflecting giving build steps more status, introduce
`Hydra::Controller::BuildStep`, chained off `/build/buildChain`, giving
them a first-class controller.

For a bit of back story, note that in the future, we might switch
associating build steps more with derivations than builds. This
reflects that we don't really care *why* something was scheduled (the
build/root derivation) as much as *what* was scheduled, especially when
multiple new builds would "race" to schedule the same derivation. It
also bodes well for a future where Hydra can act as a Nix derivation
that receives ad-hoc build requests, so the "build" in this case would
be rather lacking in metadata. Both these scenarios point to a world
where `BuildStep`s become more important than `Build`s, building (ahem)
atop this refactor.

The step log handling is now better suited to live as part of this
controller. Accordingly, it is moved from
`/build/:id/nixlog/:stepnr[/raw|/tail]` to
`/build/:id/step/:stepnr/log[/raw|/tail]`. The old `nixlog` URLs are
preserved as 301 redirects in `Build.pm`. All templates updated to
generate the new canonical URLs.
Create a proper build step details page
Replace the in-memory `resolved_drv_map` with a `resolvedDrvPath`
column on `BuildSteps` (migration upgrade-87). The
`resolve_drv_output_chains` SQL query now joins through this column to
follow unresolved → resolved chains when looking up outputs, so the
mapping survives restarts.

`try_resolve_force` no longer needs the in-memory map, and the
recursive SQL handles resolution transparently on the primary path.
The per-link loop survives only as a fallback for chains the SQL
cannot resolve: it retries each link against the DB and then the
`.drv` file on disk (authoritative for input-addressed derivations),
since a chain can mix links known only to the DB with links whose drv
only exists on disk, and the recursive SQL stops at the first miss.

A step with `status = 13` (`Resolved`) always has a non-null
`resolvedDrvPath` (enforced by a check constraint). Since the original
step's row is only inserted once resolution has already happened, the
resolved path is recorded directly in that `INSERT` rather than by a
later `UPDATE`. Resolved steps get their own `InsertResolvedBuildStep`
/ `create_resolved_build_step` rather than extra optional fields on
`InsertBuildStep`, since the two cases are semantically disjoint. The
lookup query uses the column to find outputs from the resolved drv's
successful buildstep instead.
`State` stored the whole clap-derived `Cli`, and `State::new` parsed argv
(`Cli::new()`) and read the config file (`App::init`) itself. Because
`config.rs` and `State` live in the library crate (consumed by the
examples), that pulled `clap` and the entire argv surface into the
library's compilation unit, even though the library only ever needs the
mTLS material from those arguments.

Split it along what each side actually uses:

- The library keeps a plain, clap-free `MtlsConfig` (the gRPC server's
  only need from the CLI). `State` holds that instead of `Cli`, and
  `State::new(mtls, config)` takes both as values rather than reaching out
  to argv and the filesystem.

- A new binary-only `cli` module owns `Cli`, `BindSocket`, and the
  `clap::Parser` derive. `main` parses the arguments, loads the config,
  lifts out `cli.mtls()`, and injects everything into `State::new`. The
  config-path used by the SIGHUP reloader is threaded through from `main`
  rather than read back off `State`.

`clap` is now referenced only from `src/cli.rs`, which is not part of the
library, so the library (and `examples/collect-fods`) compile without it.
The unused `env` clap feature is dropped while we're here.
queue-runner: keep argument parsing out of the library crate
Upcoming server-side copy support needs to parse CopyObject/UploadPartCopy
results and S3 error bodies, not just <UploadId>.

quick-xml was already a dependency anyway.
hydra.nixos.org wants to divert staging-next-only derivations to a separate
overflow S3 bucket. Objects later needed in the default bucket must be copied
over instead of re-uploaded.

Add copy_object_from(): header-signed CopyObject, or multipart UploadPartCopy
above 5 GiB. Both buckets must share endpoint and static credentials.
hydra.nixos.org wants steps that only staging-next needs uploaded to a
separate S3 bucket. Add [overflowStore] with the store URI and the jobsets
whose exclusive steps go there, plus the NixOS option. Routing follows in
later commits.
Initialize it from overflowStore at startup, rebuild it on config reload,
and add Step::wants_overflow() to decide which steps it applies to. Not
used for uploads yet.
Steps whose jobsets are all in overflowStore.jobsets upload to the
overflow bucket. The queue runner uploads there itself, or hands out
presigned URLs for it, with the builder echoing the bucket name in
follow-up requests. Realisations follow the same routing. Unset or
unknown means the default store.
When a step's outputs exist only in the overflow bucket but a non-overflow
jobset needs them, queue a server-side copy of the closure (NARs, listings,
debug-info links, narinfos, log, realisations) instead of rebuilding. The
step stays gated until the copy completed, like pending uploads. Adds copy
counters to the metrics.
Two Garage buckets. A build from the overflow jobset must upload to the
overflow bucket only. A later build from a regular jobset that references
it must trigger a copy back to the default bucket.
hydra-builder: Fix typo in cpu pressure
build(deps): bump nixpkgs from `a50de1b` to `8623c4c`
build(deps): bump nix from `aa2613f` to `4969304`
queue-runner: persist resolved drv paths in the database
Hydra grew a second database-connection convention when the Rust queue
runner arrived: it takes a standard `postgres://` URL (`db_url` /
`HYDRA_DATABASE_URL`), while the Perl and C++ services read `HYDRA_DBI`,
a Perl DBI string. Converge on the URL as the single convention before
more Rust services appear, rather than teaching each of them the legacy
DBI syntax.

The two formats are equally expressive — the PostgreSQL URI scheme
accepts every libpq keyword as a query parameter — so nothing is lost,
and each consumer needs only a small change:

- Perl: `Hydra::Model::DB` converts the URL to a DBI DSN with `URI::db`
  (new dependency). See the comment there for the user/password caveat.

- C++ (`hydra-evaluator`): libpq accepts a `postgres://` URL verbatim,
  so the DBI-to-conninfo translation code is deleted outright.

- NixOS module: the `dbi` option is replaced by `dbUrl`, and all
  services now get `HYDRA_DATABASE_URL` with a per-service
  `application_name` query parameter. Neither hydra.nixos.org nor
  staging ever set `dbi`, so the option's removal breaks no known
  deployment.

- The foreman dev scripts, test harness, and manual switch accordingly.
  The test harness already exported both variables; the `HYDRA_DBI` half
  is now dropped.

The Perl and C++ in-code default becomes `postgres:///hydra`, which is
byte-for-byte equivalent to the old `dbi:Pg:dbname=hydra;` (local
socket, OS-user auth). The NixOS module default matches the queue
runner's explicit `postgres://hydra@%2Frun%2Fpostgresql:5432/hydra`.
Replace `HYDRA_DBI` with `HYDRA_DATABASE_URL` everywhere
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants