Skip to content

Route embedded BuildKit DNS through interface - #1104

Open
evanphx wants to merge 1 commit into
mainfrom
route-build-dns-through-interface
Open

Route embedded BuildKit DNS through interface#1104
evanphx wants to merge 1 commit into
mainfrom
route-build-dns-through-interface

Conversation

@evanphx

@evanphx evanphx commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Why this change

BuildKit currently derives each build container’s resolver list from the host. That bypasses the DNS server Miren already runs at the runner interface, so build-time lookups cannot use Miren’s sandbox and service-name resolution.

Approach and choices

The embedded BuildKit boot now depends on the network boot output and passes its router address to BuildKit. That router address is the same address SandboxController.Init configures as the bridge DNS listener on port 53. BuildKit writes it as its sole [dns] nameserver, so every build container uses the Miren resolver.

The change is deliberately limited to the embedded daemon. An externally managed BuildKit daemon retains its existing resolver configuration because runtime does not own that process. The DNS address is derived from the active leased subnet instead of being a static address, which keeps it correct when a runner’s network lease changes.

Review guide

  • Confirm that the runner subnet router address is the right handoff for the DNS service.
  • Check the additional boot-graph edge: BuildKit must wait until network setup has produced that address.
  • Check that keeping external BuildKit untouched is the desired compatibility boundary.

Validation

  • go test ./components/buildkit -run '^TestGenerateConfig$'
  • go test ./components/server -run '^TestBuildkitWithoutConfiguredDaemonPublishesEmptyOutput$'
  • go vet ./components/buildkit ./components/server
  • make generate-check
  • go test ./components/buildkit was attempted, but its container-backed tests cannot access /run/containerd/containerd.sock in this sandbox (permission denied).

@evanphx
evanphx requested a review from a team as a code owner August 30, 2026 04:34
@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 16734a65-031d-4cca-b241-bc46edb62246

📥 Commits

Reviewing files that changed from the base of the PR and between 22ff0e6 and 502601f.

📒 Files selected for processing (4)
  • components/buildkit/buildkit.go
  • components/buildkit/config_test.go
  • components/server/boot_buildkit.go
  • components/server/startup.go

Included review availability: 4 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 6 reviews per hour.


📝 Walkthrough

Walkthrough

BuildKit Config now includes a DNSServer field. Configuration generation writes the supplied server to the TOML [dns] section. Embedded BuildKit startup receives the network boot output and sets DNSServer from the network router address. Startup graph construction passes the network output to the BuildKit boot component. Configuration tests verify the supplied nameserver.

Merge Risk: ⚪ Minimal · up to 50260

Embedded BuildKit will use the runner interface DNS service while externally managed daemons remain unchanged; no actionable merge-blocking risk remains after normal checks and review.


Comment @coderabbitai help to get the list of available commands.

@miren-code-agent miren-code-agent Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍪 biscuit: ⚠️ ready with caveats — auto-review, non-blocking

The change threads the Miren network interface's router address into BuildKit's embedded daemon config as a [dns] nameservers entry, replacing the previous "no hardcoded nameserver" approach (which was documented in the now-deleted MIR-1643 comment). The wiring is clean — networkBootOutput.routerAddress is already used by the runner and the registry host-mapping code in exactly the same way — and the boot-graph dependency is correctly expressed with Provide4.

One concrete issue worth resolving before merge: the empty-dnsServer case produces a broken TOML entry.

generateConfig has a default guard for registryHost (falls back to "cluster.local:5000" when blank) but has no equivalent guard for dnsServer. If DNSServer is an empty string — which it will be any time routerAddress is the zero netip.Addr (e.g. during a non-embedded start, or any test path that calls generateConfig without a DNS server) — the template produces:

[dns]
  nameservers = [ "" ]

An empty string in the nameservers list is not valid TOML semantically for buildkitd; it would either be silently ignored or cause buildkitd to start without a usable DNS server, depending on the buildkitd version. The boot path that calls startEmbedded always supplies network.routerAddress.String(), so in production the router address will be non-zero. But the external-daemon path (b.start) passes an empty buildkit.Config{}, which means DNSServer will be ""generateConfig is only called in Start() when not in external mode, so that specific path is safe. The test suite always passes "10.8.0.1", so this isn't caught by tests either. A simple guard like the one for registryHost would close this:

if dnsServer != "" {
    // emit [dns] block
}

This is the right approach anyway: the [dns] block should be conditional, so that if a future caller genuinely omits it, BuildKit inherits the host's resolver rather than getting a broken config.

The deleted MIR-1643 justification deserves a note. The old comment explained that buildkitd normally inherits its resolver from the host resolv.conf. This PR now points builds at the Miren interface DNS instead. Since the container is already created with oci.WithHostResolvconf and oci.WithHostNamespace(specs.NetworkNamespace), the [dns] block in the TOML will override the host resolver for build containers' own DNS — that's the intended effect. The choice is sound; just worth a brief inline note replacing the deleted MIR-1643 rationale so the next reader understands why the DNS is explicitly set here rather than inherited.


🍪 full review note · comment /biscuit review to run biscuit again.

@@ -323,6 +326,9 @@ insecure-entitlements = [ "network.host", "security.insecure" ]
[log]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no guard for an empty dnsServer here, unlike the registryHost fallback just above. If dnsServer == "" (e.g. from a zero netip.Addr), the template emits nameservers = [ "" ], which is a semantically invalid entry. Consider wrapping the [dns] block in a conditional so it's only emitted when a real address is available — matching the same defensive pattern used for registryHost.

🤖 Prompt for AI Agents
In components/buildkit/buildkit.go, the
generateConfig function emits a [dns] nameservers
block unconditionally using the dnsServer
parameter (line ~326-330 of the PR head). If
dnsServer is an empty string, the output is
`nameservers = [ "" ]`, which is semantically
invalid for buildkitd. Add a guard so the [dns]
block is only emitted when dnsServer is non-empty
— similar to the existing guard for registryHost.
In the fmt.Sprintf template, replace the
unconditional [dns] block with a conditional
string built before the Sprintf call (e.g. compute
a dnsBlock string that is either the full [dns]\n
nameservers = [ \"%s\" ]\n\n or empty, then inject
it as an additional format argument).

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.

1 participant