Skip to content

feat: Add nix-darwin (macOS) deployment support#319

Open
angerman wants to merge 6 commits into
nix-community:mainfrom
zw3rk:darwin-support
Open

feat: Add nix-darwin (macOS) deployment support#319
angerman wants to merge 6 commits into
nix-community:mainfrom
zw3rk:darwin-support

Conversation

@angerman

@angerman angerman commented Dec 9, 2025

Copy link
Copy Markdown

Add support for deploying to macOS machines using nix-darwin, alongside the
existing NixOS support.

Capabilities

  • SystemType (NixOS vs Darwin), threaded through evaluation, build, copy, and
    activation.
  • evalDarwinNode in eval.nix evaluates darwin nodes via nix-darwin's
    darwinSystem; meta.nix-darwin supplies the input.
  • Node system type is resolved from an explicit deployment.systemType, or
    auto-detected from a flake's darwinConfigurations.
  • Darwin-specific profile activation (sw/bin/darwin-rebuild activate), with the
    boot goal correctly reported as unsupported on darwin.
  • darwinDefaults for darwin-only defaults.
  • colmena apply-local and buildOnTarget work on macOS, including when
    connecting as root.
  • Handles macOS specifics where root's PATH (and sudo's secure_path) lack the
    nix binaries: absolute nix paths for local/remote commands, remote-program
    on the ssh-ng store, and nix copy (rather than legacy nix-copy-closure)
    for darwin targets.

Credits

The apply-local/root buildOnTarget enablement and the initial darwin test
coverage are by @sini, preserved as their own commits. Thanks!

Usage (flake)

{
  inputs.nix-darwin.url = "github:LnL7/nix-darwin";

  outputs = { nixpkgs, nix-darwin, ... }: {
    colmena = {
      meta = {
        nixpkgs = import nixpkgs { system = "aarch64-darwin"; };
        nix-darwin = nix-darwin;          # required for darwin nodes
      };

      my-mac = {
        deployment.systemType = "darwin"; # or auto-detected via darwinConfigurations
        deployment.targetHost = "my-mac.local";
        # ... darwin configuration ...
      };
    };
  };
}

Notes

  • Darwin nodes require meta.nix-darwin to be set.
  • Non-flake darwin deployments use nix copy for closure transfer (the legacy
    nix-copy-closure path cannot target nix on a macOS host without a PATH on the
    remote); flake deployments already used this path.

angerman added a commit to zw3rk/colmena that referenced this pull request Jan 21, 2026
Fix two issues causing CI failures in PR nix-community#319:

1. Code formatting: Run rustfmt to fix formatting in host module and
   profile.rs where multi-parameter function signatures weren't split
   across lines per Rust style guidelines.

2. Test compilation: Add missing system_type field to NodeConfig in
   node_filter.rs test code. The field was added as part of the darwin
   support feature but the test template wasn't updated accordingly.
@angerman

Copy link
Copy Markdown
Author

@zhaofengli let me know if this is the right direction of travel or not.

@angerman

Copy link
Copy Markdown
Author

@zhaofengli ping :-)

@sini

sini commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

I was able to test your branch and verified that that build and apply work.

There doesn't appear to be support for allowLocalDeployment as colmena apply-local doesn't seem to work.

buildOnTarget doesn't seem to work when connecting as root.

Otherwise it seems functional, sudo as a user works for buildOnTarget

stepbrobd added a commit to stepbrobd/colmena that referenced this pull request Mar 28, 2026
based on nix-community#319

- SystemType enum (NixOS vs Darwin)
- evalDarwinNode in eval.nix using nix-darwin's darwinSystem
- deployment.systemType option for explicit system type
- meta.nix-darwin option for the nix-darwin flake input
- darwinDefaults support for darwin-specific defaults
- Darwin-specific profile activation, boot ID detection, nix-env PATH
- Resolved conflicts with detached-activation patch in ssh.rs

Co-Authored-By: Moritz Angermann <moritz.angermann@gmail.com>
stepbrobd added a commit to stepbrobd/colmena that referenced this pull request Mar 28, 2026
based on nix-community#319

- SystemType enum (NixOS vs Darwin)
- evalDarwinNode in eval.nix using nix-darwin's darwinSystem
- deployment.systemType option for explicit system type
- meta.nix-darwin option for the nix-darwin flake input
- darwinDefaults support for darwin-specific defaults
- darwin-specific profile activation, boot ID detection, nix-env PATH
- resolved conflicts with detached-activation patch in ssh.rs
- use /run/current-system/sw/bin for nix binaries

Co-Authored-By: Moritz Angermann <moritz.angermann@gmail.com>
@stepbrobd

Copy link
Copy Markdown
Member

sorry for getting back so late!

a little heads up here, i plan to review this after #340 so you might need to rebase a few times

@sini

sini commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

I had added some enhancements on top of this / finished out some of the incomplete features and opened a PR here against the upstream of this PR: zw3rk#1 but with no response

I personally would really like to see this PR move forward so if nobody takes up the mantle I'd be happy to continue working on it / stop maintaining my fork. :)

@stepbrobd

Copy link
Copy Markdown
Member

if you want you can cherry pick the commits you needed and open a new PR and take over if @angerman doesn't reply soon, though remember to give proper credit in the commit msg!

@sini

sini commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

if you want you can cherry pick the commits you needed and open a new PR and take over if @angerman doesn't reply soon, though remember to give proper credit in the commit msg!

If that happens, then yes, of course. I'll preserve the original author commit details during rebase. Hopefully though @angerman just missed the PR and this activity will motivate them. :)

angerman and others added 5 commits July 1, 2026 06:53
Add support for deploying to macOS machines using nix-darwin.

Changes:
- Add SystemType enum (NixOS vs Darwin) in mod.rs
- Add evalDarwinNode in eval.nix using nix-darwin's darwinSystem
- Add darwinDefaults support for darwin-specific defaults
- Auto-detect darwin nodes from flake's darwinConfigurations
- Add deployment.systemType option for explicit system type
- Handle darwin-specific profile activation commands
- Fix macOS PATH issues for root user:
  - Add DARWIN_NIX_BIN_PATH constant (/nix/var/nix/profiles/default/bin)
  - Use remote-program parameter for ssh-ng:// nix-daemon
  - Use full path for nix-env during profile activation

Usage in flake.nix:
  colmena = {
    meta.nix-darwin = inputs.darwin;  # Required for darwin nodes

    my-mac = {
      deployment.systemType = "darwin";
      deployment.targetHost = "my-mac.local";
      # ... darwin configuration
    };
  };
Fix two issues causing CI failures in PR nix-community#319:

1. Code formatting: Run rustfmt to fix formatting in host module and
   profile.rs where multi-parameter function signatures weren't split
   across lines per Rust style guidelines.

2. Test compilation: Add missing system_type field to NodeConfig in
   node_filter.rs test code. The field was added as part of the darwin
   support feature but the test template wasn't updated accordingly.
realize_remote() called nix-store without a full path, which fails
on macOS when connecting as root since /nix/var/nix/profiles/default/bin
is not in root's PATH. Use DARWIN_NIX_BIN_PATH for nix-store on darwin,
matching the existing pattern for nix-env in activate().
Remove the #[cfg(target_os = "linux")] gate that prevented apply-local
from compiling on macOS. Replace the NixOS-only /etc/os-release check
with a platform-aware guard: macOS is accepted directly (for
nix-darwin), Linux still validates NixOS via os-release.
Add tests for:
- systemType defaults to NixOS
- systemType parses "darwin" correctly
- darwin systemType is accepted as valid config
@angerman

Copy link
Copy Markdown
Author

🙌

Addresses issues found while reviewing the nix-darwin support. No change to
existing NixOS deployments.

Correctness:
* systemType detection now reads `deployment.systemType` through the module
  system, so function-form node modules (not just attrsets) are routed to the
  darwin evaluator; the `meta.nix-darwin` assertion is now actually forced (it
  was bound to an unreferenced `let` and never ran).
* apply-local ran `nix-store`/`nix-env` by bare name, which fails on macOS under
  sudo's `secure_path`; resolve them to an absolute path when the local machine
  is macOS. `DARWIN_NIX_BIN_PATH` is hoisted to a shared const.
* `readlink -e` (GNU-only) errors on BSD/macOS targets; use `readlink -f` with an
  `[ -e … ]` guard that preserves the CURRENT_PROFILE fallback on both.
* Non-flake darwin copies used legacy `nix-copy-closure` (relies on the remote
  PATH); force the ssh-ng `nix copy` path for darwin.

Cleanup:
* Remove dead `Profile::from_store_path_with_type` (can't be wired in — its local
  `exists()` checks would break `buildOnTarget`) and the now-unused
  `InvalidProfile`, `SystemType::is_nixos()`, and `RebootOptions::get_system_type()`.
* Add `remote_nix_bin`/`local_nix_bin` helpers; factor eval.nix's duplicated
  `specialArgs`/nixpkgs selection into `mkSpecialArgs`/`npkgsFor`; drop redundant
  Nix (`or {}`, `nullOr`, unused arg); tighten visibility; tidy darwin tests.
jonhermansen pushed a commit to jonhermansen/colmena that referenced this pull request Jul 10, 2026
Fix two issues causing CI failures in PR nix-community#319:

1. Code formatting: Run rustfmt to fix formatting in host module and
   profile.rs where multi-parameter function signatures weren't split
   across lines per Rust style guidelines.

2. Test compilation: Add missing system_type field to NodeConfig in
   node_filter.rs test code. The field was added as part of the darwin
   support feature but the test template wasn't updated accordingly.
jonhermansen pushed a commit to jonhermansen/colmena that referenced this pull request Jul 15, 2026
Fix two issues causing CI failures in PR nix-community#319:

1. Code formatting: Run rustfmt to fix formatting in host module and
   profile.rs where multi-parameter function signatures weren't split
   across lines per Rust style guidelines.

2. Test compilation: Add missing system_type field to NodeConfig in
   node_filter.rs test code. The field was added as part of the darwin
   support feature but the test template wasn't updated accordingly.
jonhermansen pushed a commit to jonhermansen/colmena that referenced this pull request Jul 22, 2026
Fix two issues causing CI failures in PR nix-community#319:

1. Code formatting: Run rustfmt to fix formatting in host module and
   profile.rs where multi-parameter function signatures weren't split
   across lines per Rust style guidelines.

2. Test compilation: Add missing system_type field to NodeConfig in
   node_filter.rs test code. The field was added as part of the darwin
   support feature but the test template wasn't updated accordingly.
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.

3 participants