Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 44 additions & 9 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
flake-utils.url = "github:numtide/flake-utils";
git-hooks.inputs.nixpkgs.follows = "nixpkgs";
git-hooks.url = "github:cachix/git-hooks.nix";
nix-darwin.url = "github:nix-darwin/nix-darwin";
nix-editor.inputs.nixpkgs.follows = "nixpkgs";
nix-editor.inputs.utils.follows = "flake-utils";
nix-editor.url = "github:snowfallorg/nix-editor";
Expand Down Expand Up @@ -45,6 +46,7 @@
nix/devShells.nix
nix/fmt.nix
nix/hooks.nix
nix/hosts.nix
nix/nixpkgs.nix
nix/packages
nix/overlays
Expand Down
10 changes: 10 additions & 0 deletions nix/hosts.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{ inputs, ... }:
{
flake = {
darwinConfigurations = {
darwin-nixostest = inputs.nix-darwin.lib.darwinSystem {
modules = [ ./hosts/darwin-nixostest/darwin-configuration.nix ];
};
};
};
}
128 changes: 128 additions & 0 deletions nix/hosts/darwin-nixostest/darwin-configuration.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{ lib, pkgs, ... }:
let
start-linux-builder = pkgs.writeShellApplication {
name = "start-linux-builder";
text = ''
echo "Starting linux-builder..."

if sudo launchctl list | grep -q org.nixos.linux-builder; then
echo "linux-builder is already running"
exit 0
fi

# Use load instead of start to re-enable the service
if sudo launchctl load -w /Library/LaunchDaemons/org.nixos.linux-builder.plist 2>/dev/null; then
echo "linux-builder started successfully"
else
echo "Error: Could not start linux-builder"
echo "Make sure nix-darwin is configured with linux-builder enabled"
exit 1
fi

# Check if it's running
sleep 2
if sudo launchctl list | grep -q org.nixos.linux-builder; then
echo "linux-builder is now running"
else
echo "Warning: linux-builder may not have started properly"
fi
'';
};
stop-linux-builder = pkgs.writeShellApplication {
name = "stop-linux-builder";
text = ''
echo "Stopping linux-builder..."

# Use unload instead of stop because KeepAlive=true will restart it
if sudo launchctl unload -w /Library/LaunchDaemons/org.nixos.linux-builder.plist 2>/dev/null; then
echo "linux-builder stopped successfully"
else
echo "Warning: Could not stop linux-builder (it may not be running)"
fi

# Check if it's still running
sleep 1
if sudo launchctl list | grep -q org.nixos.linux-builder; then
echo "Warning: linux-builder is still running"
STATUS=$(sudo launchctl list | grep org.nixos.linux-builder || true)
echo "Current status: $STATUS"
else
echo "linux-builder is not running"
fi
'';
};
in
{
nixpkgs.hostPlatform = "aarch64-darwin";

# Install builder control scripts
environment.systemPackages = [
start-linux-builder
stop-linux-builder
];
Comment on lines +56 to +62
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 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"
fi

Repository: 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.

Suggested change
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.settings = {
experimental-features = [
"nix-command"
"flakes"
];
always-allow-substitutes = true;
max-jobs = "auto";
trusted-users = [ "@admin" ];
extra-substituters = [ "https://nix-postgres-artifacts.s3.amazonaws.com" ];
extra-trusted-substituters = [ "https://nix-postgres-artifacts.s3.amazonaws.com" ];
extra-trusted-public-keys = [
"nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI="
];
};

nix.extraOptions = ''
!include nix.custom.conf
'';

# accept existing nix.custom.conf
system.activationScripts.checks.text = lib.mkForce "";
system.activationScripts.nix-daemon.text = lib.mkForce ''
if ! diff /etc/nix/nix.conf /run/current-system/etc/nix/nix.conf &> /dev/null || ! diff /etc/nix/machines /run/current-system/etc/nix/machines &> /dev/null; then
echo "reloading nix-daemon..." >&2
launchctl kill HUP system/org.nixos.nix-daemon
fi
max_wait=30
waited=0
while ! nix-store --store daemon -q --hash ${pkgs.stdenv.shell} &>/dev/null; do
if [ $waited -ge $max_wait ]; then
echo "ERROR: nix-daemon failed to start after $max_wait seconds" >&2
exit 1
fi
echo "waiting for nix-daemon" >&2
launchctl kickstart system/org.nixos.nix-daemon
sleep 1
waited=$((waited + 1))
done
'';

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;
};
};
};
Comment on lines +104 to +123
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's explore the repository structure
git ls-files | head -20

Repository: supabase/postgres

Length of output: 796


🏁 Script executed:

# Find files related to darwin-builder or linux-builder
fd "darwin" --type f

Repository: supabase/postgres

Length of output: 156


🏁 Script executed:

# Look for documentation or comments about supportedFeatures
rg "supportedFeatures" -A 3 -B 3

Repository: supabase/postgres

Length of output: 559


🏁 Script executed:

# Check for any nix-darwin or linux-builder related files
fd "linux-builder\|darwin" --type f

Repository: supabase/postgres

Length of output: 43


🏁 Script executed:

cat -n nix/packages/setup-darwin-linux-builder.nix

Repository: 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 -i

Repository: 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.nix

Repository: 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 2

Repository: 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 5

Repository: 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 3

Repository: supabase/postgres

Length of output: 574


🏁 Script executed:

# Search for nixos-test or other features mentioned
rg "benchmark\|big-parallel\|nixos-test" --type nix

Repository: 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 -20

Repository: 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 -100

Repository: supabase/postgres

Length of output: 2484


🏁 Script executed:

# Search for any references to darwin-nixostest in the repo
rg "darwin-nixostest" -B 2 -A 2

Repository: 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.nix

Repository: 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 -i

Repository: 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 -10

Repository: supabase/postgres

Length of output: 136


🏁 Script executed:

# Show the commit that added this configuration
git show --stat 1c61ed9

Repository: supabase/postgres

Length of output: 45187


🏁 Script executed:

# Check the nix documentation about development workflow and darwin
cat nix/docs/development-workflow.md

Repository: 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.md

Repository: 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 -150

Repository: supabase/postgres

Length of output: 4880


🏁 Script executed:

# Look for any issues or documentation about linux-builder features
rg "supportedFeatures\|linux-builder" --type md

Repository: supabase/postgres

Length of output: 43


🏁 Script executed:

# Check the PR that added this configuration
git log --all --oneline --grep="darwin\|linux-builder" | head -20

Repository: 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 2

Repository: 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 -i

Repository: 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 -10

Repository: 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 -5

Repository: 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 -10

Repository: 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

  1. 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]
  2. darwin.linux-builder / nixpkgs docs and examples (how linux-builder is launched from macOS). [darwin.linux-builder docs]. [4]
  3. OSX‑KVM / macOS QEMU projects and notes on running macOS under QEMU on Linux/macOS. [OSX‑KVM (NixOS wiki)]. [1]
  4. 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]
  5. 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]
  6. 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.


nix.distributedBuilds = true;

system.stateVersion = 6;
}
3 changes: 3 additions & 0 deletions nix/packages/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
cargo-pgrx_0_14_3
;
}
// lib.optionalAttrs pkgs.stdenv.isDarwin {
setup-darwin-linux-builder = pkgs.callPackage ./setup-darwin-linux-builder.nix { inherit inputs; };
}
// lib.filterAttrs (n: _v: n != "override" && n != "overrideAttrs" && n != "overrideDerivation") (
pkgs.callPackage ../postgresql/default.nix {
inherit self';
Expand Down
60 changes: 60 additions & 0 deletions nix/packages/setup-darwin-linux-builder.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
inputs,
stdenv,
writeShellApplication,
}:
writeShellApplication {
name = "setup-darwin-linux-builder";
runtimeInputs = [
inputs.nix-darwin.packages.${stdenv.hostPlatform.system}.darwin-rebuild
];
text = ''
set -euo pipefail

echo "Configuring nix-darwin linux-builder..."
echo ""

# Backup files that nix-darwin will manage
echo "Preparing for nix-darwin..."
for file in /etc/nix/nix.conf /etc/bashrc /etc/zshrc; do
if [[ -f "$file" && ! -L "$file" ]]; then
echo " Backing up $file"
sudo mv "$file" "$file.before-nix-darwin"
fi
done
echo ""

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
Comment on lines +27 to +33
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

}
trap revert ERR SIGINT SIGTERM

echo "This will configure your system with:"
echo " - NixOS linux-builder VM (ephemeral)"
echo " - 6 cores, 8GB RAM, 40GB disk"
echo " - Support for x86_64-linux and aarch64-linux builds"
echo ""
echo "Running darwin-rebuild switch..."
echo ""

sudo darwin-rebuild switch --refresh --flake github:supabase/postgres/darwin-linux-builder#darwin-nixostest

echo ""
echo "Configuration complete!"
echo ""
echo "The linux-builder is now configured. You can test it by:"
echo " nix build --system x86_64-linux nixpkgs#hello"
echo " nix build --system aarch64-linux nixpkgs#hello"
echo ""
echo "To control the linux builder vm, you can use:"
echo " stop-linux-builder # to stop the linux builder vm"
echo " start-linux-builder # to start the linux builder vm"
echo ""
echo "If this is the first install, you may need to restart your shell to use these scripts."
'';
}
Loading