Repository navigation
Add TOML configuration for default DNS nameservers, search, options - #1614
Conversation
6af7693 to
b010238
Compare
Code Coverage
|
3eb0a7e to
46bd18b
Compare
|
Thanks for the review, @katiewasnothere. Happy to iterate further if anything else needs addressing. |
|
Hi @0xMH thank you for all the work you've done on this change! We are planning to make a new release of the container package some time in the next week and we want to hold off on merging this change until then. |
|
Hi @0xMH and @katiewasnothere! First, thanks for the great work figuring out the core logic for this. I noticed this PR has been stalled since the June release and has picked up some merge conflicts. I also saw that a couple of newer PRs for #1449 were opened recently, but they seem to have missed the @0xMH, if you are currently swamped with other things, would you mind if I pull your branch, resolve the conflicts against Let me know if that sounds good! |
|
Thanks for the offer! but no need since I'm waiting for the green flag to continue and rebase and prepare for the merge. |
|
Awesome, sounds good! Looking forward to seeing it merged. Let me know if you end up needing a hand later on! |
|
@0xMH Really sorry for the delay here, we've been swamped. I'd love to get this in for this sprint (which ends at the end of August). Could you rebase your PR? I will take another pass through the code. Thank you for your work here! |
| - `192.168.*.*` | ||
| - `172.16.*.*` through `172.31.*.*` | ||
| - The host ends with the machine's default container DNS domain (as defined in `DNSConfig.defaultDomain`, located [here](../Sources/ContainerPersistence/ContainerSystemConfig.swift)) | ||
| - The host ends with the machine's configured internal DNS domain from `[dns].domain` |
There was a problem hiding this comment.
Could we add a link to the reference doc here instead?
| public static func dnsConfiguration( | ||
| from flags: Flags.DNS, | ||
| defaults: ContainerDNSConfig, | ||
| hostDomainFallback: String? = nil |
There was a problem hiding this comment.
This to preserve the existing behavior. hostDomainFallback uses [dns].domain only when no --dns-domain flag or [container.dns].domain is set. I added tests for the fallback and for container specific override
| public let nameservers: [String] | ||
| public let searchDomains: [String] | ||
| public let options: [String] |
There was a problem hiding this comment.
What do you think about making these optionals instead of empty arrays?
There was a problem hiding this comment.
Yes, I made them optional.
|
|
||
| public let cpus: Int | ||
| public let memory: MemorySize | ||
| public let dns: ContainerDNSConfig |
There was a problem hiding this comment.
What do you think about making this an optional as well?
There was a problem hiding this comment.
Yes, I made ContainerConfig.dns optional as well.
|
@0xMH I'm Scrubbing through some of the PRs that fell through the cracks. When you can, can you rebase and address the PR review feedback? Thanks! |
606c4d4 to
5b9e784
Compare
|
I rebased the branch and addressed the comments. Please let me know if there’s anything else to address. |
|
@0xMH Sorry, looks like you'll need to do one more rebase. The builder got extracted to a plugin so your changes there will need to move over to the new locations. |
|
Sure, Will do that maybe tomorrow. |
5b9e784 to
9e5041b
Compare
|
Rebased nw. |
|
@0xMH Thanks for your contribution and patience! Merged. |
….0 (#238) Closes #231. Closes #232. Moves Berthly's `container` pin from 1.6.1 to 1.7.1, and `containerization` from 0.53.0 to 0.54.0. No other package moved. 1.7.1 is the first 1.7 release (1.7.0 was tagged but never published). ## Why - **Builds with builder shim 0.13.3.** The pin also moves the builder shim from 0.13.2 to 0.13.3 (apple/container#2434). 0.13.3 is built with gRPC-Go v1.84.0, which rejects requests without an `:authority` (grpc/grpc-go#9365). apple/container#2428 adds one in `ContainerBuild`, which Berthly links, so the shim and the fix arrive together here. - **Build steps that need the whole context.** apple/container#2414: an empty `followpaths` now means the whole context instead of nothing. - **`[container.dns]` defaults** (apple/container#1614) reach Run/Create through `Utility.containerConfigFromFlags`. The builder side is #233. ## Changes - `project.pbxproj`: `minimumVersion = 1.7.1` (`upToNextMinorVersion`). - `Package.resolved`: `container` 1.7.1, `containerization` 0.54.0. - `ContainerCompatibility`: - `requiredVersion = "1.7.1"`: every 1.6.x daemon hits the upgrade gate (#232, option 1). - `patchFloor` becomes `String? = nil` rather than being removed, so the mechanism and its tests stay for the next known-bad patch. - New `requiredVersionRationale`. - `shippedFloorBlocksContainer160` becomes `shippedGateBlocks16xAndAccepts171`. No compile breaks. `ContainerListFilters.withoutMachines()` was removed upstream, but Berthly doesn't call it. The new defaulted `Builder.start` parameters don't affect it either, since Berthly uses its own replica (#210). The 1.7.1 pkg and the `container` binary are still signed by `Apple Inc. - Containerization (UPBK2H6LZM)`, so the installer's signature check still accepts them. ## Testing All local, on Xcode 27.2 with a container 1.7.1 daemon and the 1.7.1 recommended kernel (Kata 4.3.1, `vmlinux-6.18.56-208-debug`): - `swiftlint lint --strict`: clean - BerthlyTests: 611 passed - BerthlyUITests (mock): 85 passed, 2 skipped (App Intents tests, which need a team-signed runner) - E2E via `scripts/e2e.sh`: 28/28 passed. Covers Dockerfile builds, SSH-forwarded builds, a machine-image build plus boot, a registry build/push/pull round trip, and machine first boot. After the run, the `buildkit` container is on `builder:0.13.3`. ## Follow-ups (milestone v1.7.1) #233 builder DNS defaults, #234 System page `container.dns.*` rows, #235 CPU % unit decision, #236 PARITY.md re-audit, #237 remaining real-daemon checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…ilder (#239) Closes #233. ## Problem `LiveContainerService.startBuilderContainer` is Berthly's copy of upstream's `Builder.start`, kept separate on purpose (#210). Two things diverged from the CLI: - **Builder DNS has been hard-coded to `1.1.1.1` since the initial commit.** It set `config.dns = DNSConfiguration()`, and that init's default nameserver is `1.1.1.1`. Upstream has always passed empty nameservers, which the runtime replaces with the network gateway's resolver (`RuntimeService`: "Dynamically configure the DNS nameserver from a network if no explicit configuration"). So `RUN` steps in Berthly builds skipped the gateway resolver, which the CLI's builds use. - **`[container.dns]` defaults were ignored.** container 1.7.1 (apple/container#1614) applies these `config.toml` defaults to the builder. Berthly's Run/Create picked them up with #238, but its builder didn't. ## Changes - New `builderDNS(defaults:)` resolves DNS exactly as upstream's builder does: `[container.dns]` defaults, else empty nameservers, with no host-domain fallback. - It uses the four-argument `Flags.DNS` init. The empty init leaves the `@Option`s in ArgumentParser's unset `.definition` state, the same trap as `Flags.MachineUser`. This differs from the task text in #233. - DNS joins `builderNeedsRecreate`. - A missing DNS block is compared as `.init()` (`1.1.1.1`), copying upstream's `dnsConfigurationChanged`, so a CLI build and a Berthly build don't recreate each other's builder. #233's task text expected "no change" there; this matches upstream instead. - Tests: four DNS-field recreate cases, a missing-DNS case, and `BuilderDNSTests` for nil, full and partial defaults. ## Behavior change - **Builds now resolve through the gateway (`192.168.64.1`) by default instead of `1.1.1.1`, matching `container build`.** Builds behind a VPN or split DNS may resolve differently. - **The first Berthly build after updating recreates an existing builder once,** because it was made with `1.1.1.1`. That drops the build cache. ## Testing Local, container 1.7.1 daemon: - `swiftlint lint --strict`: clean - BerthlyTests: 619 passed (8 new) - E2E via `scripts/e2e.sh`: - `ResourceJourneyTests/testBuildImageFromDockerfileThenRun` (×5) - `testBuildWithSSHForwardingMountsAgentSocket` - `MachineJourneyTests/testBuildMachineImageThenBootMachine` - I watched the `buildkit` container's `startedDate` and stored `dns` across runs: 1. A builder from before this PR (`['1.1.1.1']`) was recreated once on the first build, now with `[]`. The second build reused it. 2. A CLI `container build`, then a Berthly build: no recreate either way. The CLI build's `RUN cat /etc/resolv.conf` printed `nameserver 192.168.64.1`. 3. With `[container.dns]` (`nameservers = ["9.9.9.9"]`, `searchDomains = [...]`) set and the daemon restarted, the builder was recreated with those values, and its `/etc/resolv.conf` matched. After restoring the config, the builder went back to `[]`. - The daemon stores `nameservers: []` and only fills in the gateway inside the guest, so the comparison doesn't recreate the builder on every build. I confirmed this with a plain `container run` plus `inspect`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…240) Closes #234. container 1.7.1 added a `[container.dns]` section to `config.toml` (apple/container#1614), and `container system property list` shows it. Berthly's System page builds its own list in `LiveContainerService.mapSystemProperties`, which had no rows for the new section. ## Changes - Four rows after `container.memory`, matching where the CLI's TOML puts the subsection: `container.dns.domain`, `container.dns.nameservers`, `container.dns.searchDomains`, `container.dns.options`. - An unset value shows as the existing em dash. An empty list does too, because for `[container.dns]` it means the same as unset: the runtime falls back to the network gateway's resolver. - Lists show comma-separated (`10.0.0.53, 10.0.0.54`). The issue suggested TOML array syntax, but no other row on the page uses TOML quoting (`dns.domain` shows `test`, not `"test"`). - The mock fixture gets the same rows with sample values. - Not done: the issue's optional idea of showing these defaults as placeholders in the Run sheet's DNS fields. ## Testing - `swiftlint lint --strict`: clean - BerthlyTests: 622 passed, 3 of them new (all dashes when unset, configured values shown, row order) - E2E: `SystemViewJourneyTests/testSystemPropertiesDisclosureExpands` passed 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Closes #236. Re-audits PARITY.md against container CLI 1.7.1, following #217 for 1.6.1. 1.7.1 changed no CLI flags outside `cluster` (diffed `ContainerCommands`, `Flags.swift`, and the cluster plugin between 1.6.1 and 1.7.1). ## Changes - **Header:** "Audited against" moves to 1.7.1 (2026-11-12). - **`stats`:** CPU is a percentage of one core, the CLI's `cpuUtilization` × 100 (#235). - **Run/Create:** - Empty DNS fields fall back to `[container.dns]` (apple/container#1614), and a value in the sheet overrides them. - Out-of-range cpus or memory get the CLI's own error, since 1.7.1 validates both on the client. - **Builder:** gets the `[container.dns]` defaults, or the gateway's resolver, and is recreated when its DNS changes (#233). - **`property`:** the list includes the `container.dns.*` defaults (#234). - **`cluster` (deliberate gap):** - Records the 1.7.1 changes: `load-image` replaced by `--shared-image-store` (apple/container#2437), `cluster ls` per cluster with `--nodes` (apple/container#2451), and per-worker cpus/memory (apple/container#2448). - Notes that the CLI now skips cluster nodes in `ls`/`start`/`stop`/`kill`/`delete`/`prune` (apple/container#2462), as Berthly already did (#204). `prune` isn't in #236's list, but the 1.7.1 source filters it too. - The revisit condition is half met: the new `container-core-clusters` XPC service only handles cluster records, and the command is still EXPERIMENTAL. Time Machine exclusion (apple/container#2412) and the smaller install (apple/container#2458) are daemon-side with no CLI command to compare against, so they get no entry. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Apple container **1.7.1** is out. The previously tracked version is `1.6.1`. Upstream notes: https://github.com/apple/container/releases/tag/1.7.1. A copy is in `docs/upstream/apple-container-1.7.1.md`. Most of the 1.7.1 support is already on main from PR #57 (`specs/001-apple-container-1-7-1`) and PR #50 (clusters). This PR adds no code. It adds the 1.7.1 features to the README and records the live check in spec 001. ## Review checklist - [x] New or changed CLI flags Gantry should surface: `cluster run --shared-image-store` and `--workers count=,cpus=,memory=` came in PR #50. The `run`, `create`, `machine` and `build` commands have no new flags in 1.7.1. - [x] Changed `--format json` shapes the DockerKit apple transport decodes: only `stats` changed (`cpuUtilization`). `AppleContainerJSON.statsBody` uses it, with the counter math as fallback (`Packages/DockerKit/Sources/DockerKit/AppleContainer/AppleContainerJSON.swift:653`). The live output matches the test fixture. `container ls --format json` did not change. - [x] Fixed upstream bugs Gantry currently works around: none. The BuildKit fixes (#2428, #2414) need no change in Gantry. The "Builder image is outdated" card covers the new builder shim 0.13.3 (`AppleBuilderStatus.imageUpdate`). - [x] `ContainerTooling.recommendedVersion` and feature gates: `recommendedVersion = "1.7.1"` (`Packages/AppCore/Sources/AppCore/ContainerTooling.swift:18`). The DNS defaults are gated on 1.7.0 (`containerDNSDefaultsVersion`, line 46). - [x] MCP tools and App Intents that expose the affected commands: `container_stats` uses the same DockerKit decoder. `apple_set_property` accepts lists for the DNS keys (PR #57). No App Intent shows the changed commands. - [x] README and CHANGELOG entries for whatever is adopted: the CHANGELOG has the #57 and #50 lines. This PR adds the 1.7.1 features to the README. ## Adopted (on main, checked again on CLI 1.7.1) - Stats `cpuUtilization` (#2146). The old calculation stays as fallback for 1.6.1. - `[container.dns]` defaults in `config.toml` (#1614): a list editor in System Properties, gated on 1.7.0. - Recommended kernel (#2447): Gantry has no kernel version of its own. It runs `system kernel set --recommended`. - Cluster changes (#2437, #2448, #2451, #2462) came in PR #50. The notice for missing or stopped cluster services came in PR #57. - Builder shim 0.13.3: the outdated builder card. ## Not adopted, and why - #2412 Time Machine exclusion, #2443 containerization 0.54.0, #2458 package size, #2470 copy blobs, #2416 bootstrapper, #2477 test library: internal changes. Gantry has nothing to show for them. - #2457, #2459, #2433, #2413: upstream docs and examples only. ## Checks - `swift test` in DockerKit: 324 tests passed. AppCore `AppleContainer171` tests: 19 passed. - `scripts/check-localization.py`: 0 problems in 28 languages. This PR adds no strings. - Debug build on CLI 1.7.1: a busy test container shows 98 % CPU. The CLI reports `cpuUtilization` 1.0 for it. - The Builder card shows 0.13.2 to 0.13.3 in light and dark mode. System Properties shows `[container.dns]`. The cluster list shows one row for each cluster. - Open (T035 in spec 001): two items had no check in the app. These are the DNS list editor sheet and the cluster services notice. The editor needs a click. The notice needs a broken cluster setup. --- <details><summary>Upstream release notes</summary> ## Highlights ⌨️ denotes breaking CLI changes. 👩💻 denotes breaking API changes. - Core - [`container stats` now reports `cpuUtilization` in JSON, YAML, and TOML output](apple/container#2146) - [Image snapshots and container filesystems are now excluded from Time Machine backups](apple/container#2412) - [Default Kata kernel is now 4.3.1 (`vmlinux-6.18.56-208-debug`)](apple/container#2447) - [Updated Containerization to 0.54.0](apple/container#2443) - Networking - [Default DNS nameservers, search domains, and options can now be set in `config.toml`](apple/container#1614) - Build - [Fixed `container build` failures with newer BuildKit](apple/container#2428) and [missing build context for steps that need the full context](apple/container#2414) - Kubernetes - ⌨️ [New `--shared-image-store` option on `container cluster run` to use the `container` image store from cluster nodes; removed the `load-image` subcommand](apple/container#2437) - ⌨️ [`container cluster ls` now shows one row per cluster; use `--nodes` for the per-node view](apple/container#2451) - ⌨️ [Container lifecycle commands no longer operate on cluster nodes](apple/container#2462) - [Worker node CPU and memory can now be set with `--workers count=<n>,cpus=<n>,memory=<size>`](apple/container#2448) ## What's Changed * Send an :authority on the builder gRPC connection by @jglogan in apple/container#2428 * Adds `container cluster` example. by @jglogan in apple/container#2433 * Update container-builder-shim to 0.13.3. by @jglogan in apple/container#2434 * use macos 27 runners by @madrob in apple/container#2436 * Fix empty followpaths handling in BuildFSSync by @onlyarnav in apple/container#2414 * Document container clean in the reclaim disk space guide by @lucasbrito-wdt in apple/container#2413 * Bump to use containerization 0.54.0 by @adityaramani in apple/container#2443 * feat(stats): report cpuUtilization in the machine-readable formats by @guanchzhou in apple/container#2146 * [k8s plugin] Create a cluster bootstrapper by @katiewasnothere in apple/container#2416 * Update recommended kernel to kata 4.3.1 release vmlinux-6.18.56-208-debug by @katiewasnothere in apple/container#2447 * Add TOML configuration for default DNS nameservers, search, options by @0xMH in apple/container#1614 * Add the ability to share container's image store with container cluster by @crosbymichael in apple/container#2437 * Reduce install package size and install footprint. by @jglogan in apple/container#2458 * Add reference to apple/container-examples and remove examples/ out of this repo by @michaelzhang114 in apple/container#2457 * Create container-core-clusters XPC service by @adityaramani in apple/container#2451 * Exclude recreatable container data from Time Machine by @abdullahtas0 in apple/container#2412 * Clean the `cluster-shim` build files with `make clean` by @dkovba in apple/container#2463 * Quiet the `cluster-shim` build output and show the swift progress in place by @dkovba in apple/container#2461 * Do not allow high level container lifecycle commands to operate on cluster nodes by @katiewasnothere in apple/container#2462 * Switch to copy blobs by @crosbymichael in apple/container#2470 * Add option to set cpus and memory resources for worker nodes of cluster by @katiewasnothere in apple/container#2448 * Removed bug-report-how-to.md as this info is now consolidated in CONTRIBUTING.md by @michaelzhang114 in apple/container#2459 * Move HostStoreServer into a library so tests don't link the executable by @katiewasnothere in apple/container#2477 ## New Contributors * @madrob made their first contribution in apple/container#2436 * @onlyarnav made their first contribution in apple/container#2414 * @lucasbrito-wdt made their first contribution in apple/container#2413 * @abdullahtas0 made their first contribution in apple/container#2412 **Full Changelog**: apple/container@1.6.1...1.7.1 </details> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: andrewkomkov <33517893+andrewkomkov@users.noreply.github.com>
Type of Change
Motivation and Context
Closes #1449. Adds default values for
--dns,--dns-search,--dns-option, and--dns-domainto the[dns]section of~/.config/container/config.toml, so users hitting macOSmDNSResponderconflicts can set the workaround once instead of repeating it on every invocation. Depends on the merged TOML configuration introduced by #1425.Defaults are read by
container run,container build, andcontainer builder startvia a sharedUtility.dnsConfiguration(from:defaults:)helper. CLI flags take precedence;--no-dnsstill disables DNS. Two pre-existing bugs in the build path were fixed to make the feature work end-to-end:BuildCommandwas forwarding onlydnsNameserversto the builder (now forwards all four DNS fields), andBuilderStart'sdnsChangedcheck only compared the first non-empty field (now compares all four).Testing