-
-
Notifications
You must be signed in to change notification settings - Fork 226
feat(darwin): add nix-darwin host and linux-builder for NixOS tests #1999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
WalkthroughThe changes introduce nix-darwin support to the flake, adding a complete Darwin host configuration with Linux builder setup, activation scripts, distributed build settings, and shell-based setup utilities for system initialization on macOS. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
2eaa972 to
bdd5fd8
Compare
fa26b67 to
0131d17
Compare
Running NixOS tests on macOS requires a Linux VM capable of building
NixOS VMs. This adds a nix-darwin configuration that provisions an
ephemeral QEMU linux-builder with support for aarch64-linux and
x86_64-linux builds.
Usage:
nix run github:supabase/postgres#setup-darwin-linux-builder
Enables running NixOS integration tests from macOS development machines
(see #1989).
bdd5fd8 to
1c61ed9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@nix/hosts/darwin-nixostest/darwin-configuration.nix`:
- Around line 56-62: The file hardcodes nixpkgs.hostPlatform = "aarch64-darwin",
which will break on Intel Macs; replace that hardcoded value with an
auto-detected platform (e.g. set nixpkgs.hostPlatform to builtins.currentSystem
or derive the arch from builtins.currentSystem) so the configuration is generic,
and keep environment.systemPackages as-is; alternatively, if this is intended to
be ARM-only, rename the directory to indicate aarch64 (e.g.
darwin-aarch64-nixostest) and add a comment next to the nixpkgs.hostPlatform
assignment clarifying the ARM-only constraint.
- Around line 104-123: Remove the unsupported "kvm" feature from the linux
builder's advertised supportedFeatures so macOS-hosted QEMU VMs don't get
scheduled for KVM-only builds: in the nix.linux-builder block update
supportedFeatures to only include the actual macOS/QEMU-supported entries (e.g.,
"benchmark", "big-parallel", and "nixos-test" if validated) and ensure nothing
else in the darwin-builder config (virtualisation.darwin-builder, diskSize,
memorySize, cores) claims KVM support.
In `@nix/packages/setup-darwin-linux-builder.nix`:
- Around line 27-33: The revert() function currently skips restoration when the
target file is a symlink; update revert() so it restores backups even if /etc
files are symlinks: for each file in the loop, check if the backup
"$file.before-nix-darwin" exists ( -f ) and if the target is a symlink ( -L ),
remove the symlink (sudo rm "$file") before moving the backup into place (sudo
mv "$file.before-nix-darwin" "$file"); keep the existing branch for non-symlink
files but ensure both cases handle presence of the backup and use sudo for
removals/moves to avoid permission issues in the revert() function.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
flake.lockis excluded by!**/*.lock
📒 Files selected for processing (5)
flake.nixnix/hosts.nixnix/hosts/darwin-nixostest/darwin-configuration.nixnix/packages/default.nixnix/packages/setup-darwin-linux-builder.nix
🔇 Additional comments (10)
nix/packages/default.nix (1)
87-89: Darwin-only exposure looks good.Keeps non-Darwin package sets clean while still surfacing the setup utility where it’s needed.
flake.nix (2)
14-14: Confirmnix-darwinis pinned inflake.lock.Please ensure the lock file was refreshed so this new input is reproducible.
49-49: LGTM wiringnix/hosts.nixinto outputs.nix/hosts.nix (1)
1-8: LGTM exporting thedarwin-nixostestsystem.Please verify
inputs.nix-darwin.lib.darwinSystemis available in the pinned nix-darwin version.nix/hosts/darwin-nixostest/darwin-configuration.nix (5)
3-29: Start script flow looks solid.Checks for the existing service and handles load errors cleanly.
31-52: Stop script handling is clear and safe.
79-103: Activation guard and daemon readiness loop look good.
125-127: LGTM enabling distributed builds and settingstateVersion.
64-77: These configuration options are valid and fully supported.
extra-substituters,extra-trusted-substituters, andextra-trusted-public-keysare standard Nix configuration options that append to their respective lists without replacing defaults. The repository's own flake.nix uses these options, and nix-darwin translatesnix.settingsdirectly to/etc/nix/nix.conf. This configuration is correct and follows best practices.nix/packages/setup-darwin-linux-builder.nix (1)
45-45: Avoid hard‑coding the feature branch indarwin-rebuild.Using
github:supabase/postgres/darwin-linux-builderwill break once the branch is deleted and decouples the script from the revision that built it. However, the proposed fix is not valid—${inputs.self}cannot be interpolated into a runtime shell script.To fix this properly, pass the flake URL as a Nix string value at build time. For example, modify
nix/packages/setup-darwin-linux-builder.nixto receive and useselfas a parameter, or updatenix/packages/default.nixto pass the flake location explicitly:-setup-darwin-linux-builder = pkgs.callPackage ./setup-darwin-linux-builder.nix { inherit inputs; }; +setup-darwin-linux-builder = pkgs.callPackage ./setup-darwin-linux-builder.nix { inherit inputs self; };Then in the script, interpolate the flake URL as a proper string during Nix evaluation (not as a shell variable).
Likely an incorrect or invalid review comment.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| nixpkgs.hostPlatform = "aarch64-darwin"; | ||
|
|
||
| # Install builder control scripts | ||
| environment.systemPackages = [ | ||
| start-linux-builder | ||
| stop-linux-builder | ||
| ]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Read the file to understand context
file_path="nix/hosts/darwin-nixostest/darwin-configuration.nix"
# Check if file exists
if [ -f "$file_path" ]; then
echo "=== File content with line numbers ==="
cat -n "$file_path"
else
echo "File not found: $file_path"
fiRepository: supabase/postgres
Length of output: 4788
Remove the hardcoded architecture or clarify intent with a comment.
The aarch64-darwin platform is hardcoded, which will fail on Intel Macs. Since the host directory "darwin-nixostest" lacks architecture specificity, this configuration appears generic and should auto-detect the platform instead.
🔧 Suggested adjustment
- nixpkgs.hostPlatform = "aarch64-darwin";
+ nixpkgs.hostPlatform = lib.mkDefault pkgs.stdenv.hostPlatform.system;Alternatively, if this configuration is intentionally ARM-only, rename the directory to darwin-aarch64-nixostest and add a comment explaining the constraint.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| nixpkgs.hostPlatform = "aarch64-darwin"; | |
| # Install builder control scripts | |
| environment.systemPackages = [ | |
| start-linux-builder | |
| stop-linux-builder | |
| ]; | |
| nixpkgs.hostPlatform = lib.mkDefault pkgs.stdenv.hostPlatform.system; | |
| # Install builder control scripts | |
| environment.systemPackages = [ | |
| start-linux-builder | |
| stop-linux-builder | |
| ]; |
🤖 Prompt for AI Agents
In `@nix/hosts/darwin-nixostest/darwin-configuration.nix` around lines 56 - 62,
The file hardcodes nixpkgs.hostPlatform = "aarch64-darwin", which will break on
Intel Macs; replace that hardcoded value with an auto-detected platform (e.g.
set nixpkgs.hostPlatform to builtins.currentSystem or derive the arch from
builtins.currentSystem) so the configuration is generic, and keep
environment.systemPackages as-is; alternatively, if this is intended to be
ARM-only, rename the directory to indicate aarch64 (e.g.
darwin-aarch64-nixostest) and add a comment next to the nixpkgs.hostPlatform
assignment clarifying the ARM-only constraint.
| nix.linux-builder = { | ||
| enable = true; | ||
| ephemeral = true; | ||
| maxJobs = 4; | ||
| supportedFeatures = [ | ||
| "kvm" | ||
| "benchmark" | ||
| "big-parallel" | ||
| "nixos-test" | ||
| ]; | ||
| config = { | ||
| virtualisation = { | ||
| darwin-builder = { | ||
| diskSize = 40 * 1024; | ||
| memorySize = 8 * 1024; | ||
| }; | ||
| cores = 6; | ||
| }; | ||
| }; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, let's explore the repository structure
git ls-files | head -20Repository: supabase/postgres
Length of output: 796
🏁 Script executed:
# Find files related to darwin-builder or linux-builder
fd "darwin" --type fRepository: supabase/postgres
Length of output: 156
🏁 Script executed:
# Look for documentation or comments about supportedFeatures
rg "supportedFeatures" -A 3 -B 3Repository: supabase/postgres
Length of output: 559
🏁 Script executed:
# Check for any nix-darwin or linux-builder related files
fd "linux-builder\|darwin" --type fRepository: supabase/postgres
Length of output: 43
🏁 Script executed:
cat -n nix/packages/setup-darwin-linux-builder.nixRepository: supabase/postgres
Length of output: 2361
🏁 Script executed:
# Check if there are any comments or documentation about KVM support in the entire darwin-nixostest directory
rg "kvm\|KVM" --type nix -iRepository: supabase/postgres
Length of output: 43
🏁 Script executed:
# Look at the full darwin-configuration.nix file to understand context
cat -n nix/hosts/darwin-nixostest/darwin-configuration.nixRepository: supabase/postgres
Length of output: 4749
🏁 Script executed:
# Search for any CI or tests that might use this configuration
rg "darwin-nixostest\|linux-builder" --type yml --type yaml -B 2 -A 2Repository: supabase/postgres
Length of output: 88
🏁 Script executed:
# Check if there are any issues or documentation about supportedFeatures in nix files
rg "supportedFeatures" -B 5 -A 5Repository: supabase/postgres
Length of output: 818
🏁 Script executed:
# Look for any references to darwin-builder in comments or documentation
rg "darwin-builder" --type nix -B 3 -A 3Repository: supabase/postgres
Length of output: 574
🏁 Script executed:
# Search for nixos-test or other features mentioned
rg "benchmark\|big-parallel\|nixos-test" --type nixRepository: supabase/postgres
Length of output: 43
🏁 Script executed:
# Search for workflow files that might use this configuration
fd "\.ya?ml" nix/hosts .github/workflows | head -20Repository: supabase/postgres
Length of output: 789
🏁 Script executed:
# Look at the flake.nix to understand how this configuration is defined
cat -n flake.nix | head -100Repository: supabase/postgres
Length of output: 2484
🏁 Script executed:
# Search for any references to darwin-nixostest in the repo
rg "darwin-nixostest" -B 2 -A 2Repository: supabase/postgres
Length of output: 697
🏁 Script executed:
# Check if there are any comments in the configuration about feature support
cat -n nix/hosts/darwin-nixostest/darwin-configuration.nix | grep -A 20 -B 5 "supportedFeatures"Repository: supabase/postgres
Length of output: 674
🏁 Script executed:
# Look for any README or documentation files in the nix directory
find nix -name "README*" -o -name "*.md"Repository: supabase/postgres
Length of output: 806
🏁 Script executed:
# Check for any comments or documentation in the hosts.nix file
cat -n nix/hosts.nixRepository: supabase/postgres
Length of output: 348
🏁 Script executed:
# Search for any references to KVM, nested virtualization, or capabilities in the repo
rg "nested\|virtuali\|capab" --type nix -iRepository: supabase/postgres
Length of output: 43
🏁 Script executed:
# Look for any notes or issues in git history about this configuration
git log --oneline --all -- nix/hosts/darwin-nixostest/darwin-configuration.nix | head -10Repository: supabase/postgres
Length of output: 136
🏁 Script executed:
# Show the commit that added this configuration
git show --stat 1c61ed9Repository: supabase/postgres
Length of output: 45187
🏁 Script executed:
# Check the nix documentation about development workflow and darwin
cat nix/docs/development-workflow.mdRepository: supabase/postgres
Length of output: 3966
🏁 Script executed:
# Check if there's any documentation about darwin or linux-builder setup
cat nix/docs/start-here.mdRepository: supabase/postgres
Length of output: 5176
🏁 Script executed:
# Search for any comments or context about the features in the actual implementation
git show 1c61ed9 -- nix/hosts/darwin-nixostest/darwin-configuration.nix | head -150Repository: supabase/postgres
Length of output: 4880
🏁 Script executed:
# Look for any issues or documentation about linux-builder features
rg "supportedFeatures\|linux-builder" --type mdRepository: supabase/postgres
Length of output: 43
🏁 Script executed:
# Check the PR that added this configuration
git log --all --oneline --grep="darwin\|linux-builder" | head -20Repository: supabase/postgres
Length of output: 888
🏁 Script executed:
# Search online for nix-darwin linux-builder documentation or issues
# Let's check what the actual feature requirements are
rg "benchmark\|big-parallel\|nixos-test" --type nix -B 2 -A 2Repository: supabase/postgres
Length of output: 43
🏁 Script executed:
# Look at the nix-darwin source to understand linux-builder better
cat flake.lock | grep -A 5 "nix-darwin"Repository: supabase/postgres
Length of output: 747
🏁 Script executed:
# Look for any existing issues or documentation in the repo about feature support
rg "kvm\|nested" --type nix --type md -iRepository: supabase/postgres
Length of output: 43
🏁 Script executed:
# Check if there are any test results or CI logs that might indicate feature success/failure
find . -name "*.log" -o -name "*test*" -type f | grep -i darwin | head -10Repository: supabase/postgres
Length of output: 43
🏁 Script executed:
# Search for nix-darwin module documentation in the repo
fd "modules\|options" | xargs grep -l "linux-builder" 2>/dev/null | head -5Repository: supabase/postgres
Length of output: 43
🏁 Script executed:
# Check git history for any issues or fixes related to this configuration
git log --all --oneline -- "nix/hosts/darwin-nixostest/" | head -10Repository: supabase/postgres
Length of output: 136
🌐 Web query:
nix-darwin linux-builder KVM support macOS QEMU nested virtualization
💡 Result:
Short answer
- nix-darwin’s linux-builder can expose a Linux builder VM and declare "kvm" as a supported feature, but whether KVM-backed nested VMs actually work depends on the host hypervisor support — not nix-darwin itself. [1][2]
- On macOS you do not get Linux KVM; QEMU on macOS uses the Hypervisor.framework (accel=hvf) rather than Linux KVM, and macOS/QEMU lacks some features (virtfs, etc.) compared to Linux KVM. [3][4]
- Apple Silicon: M1 does not support hardware nested virtualization, M2/M3+ have improved CPU capability but macOS Hypervisor/Virtualization framework support for nested virt is limited/only recently evolving — in practice nested virtualization inside a linux-builder on Apple Silicon is generally not possible or unreliable today. [2][5][6]
Relevant sources
- nix-darwin / linux-builder docs and example config (how to enable linux-builder and expose "kvm" feature). [NixOS wiki: NixOS virtual machines on macOS]. [2]
- darwin.linux-builder / nixpkgs docs and examples (how linux-builder is launched from macOS). [darwin.linux-builder docs]. [4]
- OSX‑KVM / macOS QEMU projects and notes on running macOS under QEMU on Linux/macOS. [OSX‑KVM (NixOS wiki)]. [1]
- QEMU on macOS uses Hypervisor.framework (hvf) not KVM; some QEMU features (virtfs) are missing on macOS. (See QEMU/hvf discussion and issue threads). [QEMU hvf docs/patches; nixpkgs issue re: virtfs]. [6][3]
- Notes on nested virtualization support on Apple Silicon (M1 lacks nested‑virt; M2/M3 have more CPU capability but software/framework support is limited). [NixOS wiki discussion; macOS nested-virt threads]. [2][5]
- Recent bug/issue reports showing practical limits (virtfs, missing nested support in QEMU/hvf and in projects like UTM/Parallels). [nixpkgs issues; UTM/Parallels KB]. [3][7]
If you want, tell me:
- your Mac model (Intel vs M1/M2/M3/M4) and macOS version, and I’ll give specific practical steps or a recommended setup (e.g., use darwin.linux-builder + QEMU accel=hvf on Intel, or use a remote Linux builder / cloud builder when nested KVM is required).
Remove unsupported kvm feature from supportedFeatures.
QEMU on macOS uses the Hypervisor.framework (hvf), not KVM. Advertising kvm in supportedFeatures will schedule KVM-dependent builds to this builder, where they will fail. Keep only the features actually supported by the macOS-hosted QEMU VM: benchmark, big-parallel, and nixos-test (if confirmed to work without KVM).
🤖 Prompt for AI Agents
In `@nix/hosts/darwin-nixostest/darwin-configuration.nix` around lines 104 - 123,
Remove the unsupported "kvm" feature from the linux builder's advertised
supportedFeatures so macOS-hosted QEMU VMs don't get scheduled for KVM-only
builds: in the nix.linux-builder block update supportedFeatures to only include
the actual macOS/QEMU-supported entries (e.g., "benchmark", "big-parallel", and
"nixos-test" if validated) and ensure nothing else in the darwin-builder config
(virtualisation.darwin-builder, diskSize, memorySize, cores) claims KVM support.
| revert() { | ||
| for file in /etc/nix/nix.conf /etc/bashrc /etc/zshrc; do | ||
| if [[ ! -L "$file" && -f "$file.before-nix-darwin" ]]; then | ||
| echo " Restoring original $file" | ||
| sudo mv "$file.before-nix-darwin" "$file" | ||
| fi | ||
| done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rollback won’t restore backups after nix-darwin symlinks files.
revert skips restoration when the target is a symlink, but darwin-rebuild typically creates symlinks in /etc. On failure, the originals remain stranded and the symlinked config persists.
🔧 Proposed fix
- if [[ ! -L "$file" && -f "$file.before-nix-darwin" ]]; then
- echo " Restoring original $file"
- sudo mv "$file.before-nix-darwin" "$file"
+ if [[ -f "$file.before-nix-darwin" ]]; then
+ echo " Restoring original $file"
+ sudo rm -f "$file"
+ sudo mv "$file.before-nix-darwin" "$file"
fi🤖 Prompt for AI Agents
In `@nix/packages/setup-darwin-linux-builder.nix` around lines 27 - 33, The
revert() function currently skips restoration when the target file is a symlink;
update revert() so it restores backups even if /etc files are symlinks: for each
file in the loop, check if the backup "$file.before-nix-darwin" exists ( -f )
and if the target is a symlink ( -L ), remove the symlink (sudo rm "$file")
before moving the backup into place (sudo mv "$file.before-nix-darwin" "$file");
keep the existing branch for non-symlink files but ensure both cases handle
presence of the backup and use sudo for removals/moves to avoid permission
issues in the revert() function.
Running NixOS tests on macOS requires a Linux VM capable of building NixOS VMs. This adds a nix-darwin configuration that provisions an ephemeral QEMU linux-builder with support for aarch64-linux and x86_64-linux builds.
Usage:
Enables running NixOS integration tests from macOS development machines (see #1989).
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.