Skip to content

Commit bdd5fd8

Browse files
committed
feat(darwin): add nix-darwin host and linux-builder for NixOS tests
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).
1 parent fa26b67 commit bdd5fd8

File tree

6 files changed

+247
-9
lines changed

6 files changed

+247
-9
lines changed

flake.lock

Lines changed: 44 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
flake-utils.url = "github:numtide/flake-utils";
1212
git-hooks.inputs.nixpkgs.follows = "nixpkgs";
1313
git-hooks.url = "github:cachix/git-hooks.nix";
14+
nix-darwin.url = "github:nix-darwin/nix-darwin";
1415
nix-editor.inputs.nixpkgs.follows = "nixpkgs";
1516
nix-editor.inputs.utils.follows = "flake-utils";
1617
nix-editor.url = "github:snowfallorg/nix-editor";
@@ -45,6 +46,7 @@
4546
nix/devShells.nix
4647
nix/fmt.nix
4748
nix/hooks.nix
49+
nix/hosts.nix
4850
nix/nixpkgs.nix
4951
nix/packages
5052
nix/overlays

nix/hosts.nix

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{ inputs, ... }:
2+
{
3+
flake = {
4+
darwinConfigurations = {
5+
darwin-nixostest = inputs.nix-darwin.lib.darwinSystem {
6+
modules = [ ./hosts/darwin-nixostest/darwin-configuration.nix ];
7+
};
8+
};
9+
};
10+
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
{ lib, pkgs, ... }:
2+
let
3+
start-linux-builder = pkgs.writeShellApplication {
4+
name = "start-linux-builder";
5+
text = ''
6+
echo "Starting linux-builder..."
7+
8+
if sudo launchctl list | grep -q org.nixos.linux-builder; then
9+
echo "linux-builder is already running"
10+
exit 0
11+
fi
12+
13+
# Use load instead of start to re-enable the service
14+
if sudo launchctl load -w /Library/LaunchDaemons/org.nixos.linux-builder.plist 2>/dev/null; then
15+
echo "linux-builder started successfully"
16+
else
17+
echo "Error: Could not start linux-builder"
18+
echo "Make sure nix-darwin is configured with linux-builder enabled"
19+
exit 1
20+
fi
21+
22+
# Check if it's running
23+
sleep 2
24+
if sudo launchctl list | grep -q org.nixos.linux-builder; then
25+
echo "linux-builder is now running"
26+
else
27+
echo "Warning: linux-builder may not have started properly"
28+
fi
29+
'';
30+
};
31+
stop-linux-builder = pkgs.writeShellApplication {
32+
name = "stop-linux-builder";
33+
text = ''
34+
echo "Stopping linux-builder..."
35+
36+
# Use unload instead of stop because KeepAlive=true will restart it
37+
if sudo launchctl unload -w /Library/LaunchDaemons/org.nixos.linux-builder.plist 2>/dev/null; then
38+
echo "linux-builder stopped successfully"
39+
else
40+
echo "Warning: Could not stop linux-builder (it may not be running)"
41+
fi
42+
43+
# Check if it's still running
44+
sleep 1
45+
if sudo launchctl list | grep -q org.nixos.linux-builder; then
46+
echo "Warning: linux-builder is still running"
47+
STATUS=$(sudo launchctl list | grep org.nixos.linux-builder || true)
48+
echo "Current status: $STATUS"
49+
else
50+
echo "linux-builder is not running"
51+
fi
52+
'';
53+
};
54+
in
55+
{
56+
nixpkgs.hostPlatform = "aarch64-darwin";
57+
58+
# Install builder control scripts
59+
environment.systemPackages = [
60+
start-linux-builder
61+
stop-linux-builder
62+
];
63+
64+
nix.settings = {
65+
experimental-features = [
66+
"nix-command"
67+
"flakes"
68+
];
69+
always-allow-substitutes = true;
70+
max-jobs = "auto";
71+
trusted-users = [ "@admin" ];
72+
extra-substituters = [ "https://nix-postgres-artifacts.s3.amazonaws.com" ];
73+
extra-trusted-substituters = [ "https://nix-postgres-artifacts.s3.amazonaws.com" ];
74+
extra-trusted-public-keys = [
75+
"nix-postgres-artifacts:dGZlQOvKcNEjvT7QEAJbcV6b6uk7VF/hWMjhYleiaLI="
76+
];
77+
};
78+
79+
nix.extraOptions = ''
80+
!include nix.custom.conf
81+
'';
82+
83+
# accept existing nix.custom.conf
84+
system.activationScripts.checks.text = lib.mkForce "";
85+
system.activationScripts.nix-daemon.text = lib.mkForce ''
86+
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
87+
echo "reloading nix-daemon..." >&2
88+
launchctl kill HUP system/org.nixos.nix-daemon
89+
fi
90+
max_wait=30
91+
waited=0
92+
while ! nix-store --store daemon -q --hash ${pkgs.stdenv.shell} &>/dev/null; do
93+
if [ $waited -ge $max_wait ]; then
94+
echo "ERROR: nix-daemon failed to start after $max_wait seconds" >&2
95+
exit 1
96+
fi
97+
echo "waiting for nix-daemon" >&2
98+
launchctl kickstart system/org.nixos.nix-daemon
99+
sleep 1
100+
waited=$((waited + 1))
101+
done
102+
'';
103+
104+
nix.linux-builder = {
105+
enable = true;
106+
ephemeral = true;
107+
maxJobs = 4;
108+
supportedFeatures = [
109+
"kvm"
110+
"benchmark"
111+
"big-parallel"
112+
"nixos-test"
113+
];
114+
config = {
115+
virtualisation = {
116+
darwin-builder = {
117+
diskSize = 40 * 1024;
118+
memorySize = 8 * 1024;
119+
};
120+
cores = 6;
121+
};
122+
};
123+
};
124+
125+
nix.distributedBuilds = true;
126+
127+
system.stateVersion = 6;
128+
}

nix/packages/default.nix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
cargo-pgrx_0_14_3
8585
;
8686
}
87+
// lib.optionalAttrs pkgs.stdenv.isDarwin {
88+
setup-darwin-linux-builder = pkgs.callPackage ./setup-darwin-linux-builder.nix { inherit inputs; };
89+
}
8790
// lib.filterAttrs (n: _v: n != "override" && n != "overrideAttrs" && n != "overrideDerivation") (
8891
pkgs.callPackage ../postgresql/default.nix {
8992
inherit self';
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
inputs,
3+
stdenv,
4+
writeShellApplication,
5+
}:
6+
writeShellApplication {
7+
name = "setup-darwin-linux-builder";
8+
runtimeInputs = [
9+
inputs.nix-darwin.packages.${stdenv.hostPlatform.system}.darwin-rebuild
10+
];
11+
text = ''
12+
set -euo pipefail
13+
14+
echo "Configuring nix-darwin linux-builder..."
15+
echo ""
16+
17+
# Backup files that nix-darwin will manage
18+
echo "Preparing for nix-darwin..."
19+
for file in /etc/nix/nix.conf /etc/bashrc /etc/zshrc; do
20+
if [[ -f "$file" && ! -L "$file" ]]; then
21+
echo " Backing up $file"
22+
sudo mv "$file" "$file.before-nix-darwin"
23+
fi
24+
done
25+
echo ""
26+
27+
revert() {
28+
for file in /etc/nix/nix.conf /etc/bashrc /etc/zshrc; do
29+
if [[ ! -L "$file" && -f "$file.before-nix-darwin" ]]; then
30+
echo " Restoring original $file"
31+
sudo mv "$file.before-nix-darwin" "$file"
32+
fi
33+
done
34+
}
35+
trap revert ERR SIGINT SIGTERM
36+
37+
echo "This will configure your system with:"
38+
echo " - NixOS linux-builder VM (ephemeral)"
39+
echo " - 6 cores, 8GB RAM, 40GB disk"
40+
echo " - Support for x86_64-linux and aarch64-linux builds"
41+
echo ""
42+
echo "Running darwin-rebuild switch..."
43+
echo ""
44+
45+
sudo darwin-rebuild switch --refresh --flake github:supabase/postgres/darwin-linux-builder#darwin-nixostest
46+
47+
echo ""
48+
echo "Configuration complete!"
49+
echo ""
50+
echo "The linux-builder is now configured. You can test it by:"
51+
echo " nix build --system x86_64-linux nixpkgs#hello"
52+
echo " nix build --system aarch64-linux nixpkgs#hello"
53+
echo ""
54+
echo "To control the linux builder vm, you can use:"
55+
echo " stop-linux-builder # to stop the linux builder vm"
56+
echo " start-linux-builder # to start the linux builder vm"
57+
echo ""
58+
echo "If this is the first install, you may need to restart your shell to use these scripts."
59+
'';
60+
}

0 commit comments

Comments
 (0)