Curious about system.nix

Hello,
With 26.05 there is this release note about nixos-rebuild having support for a system.nix file:

The system.nix file has been added as an alternative entry point to configuration.nix (and flake.nix) that allows to configure NixOS without using nix-channel

As someone that has almost exclusively used Nix with flakes, I am a bit curious about this. Is this mainly intended for use with pinning frameworks such as niv and nixtamal? What are the pros and cons compared with flakes?

5 Likes

While I do remember the release notes entry, I can’t find anything in the manual :person_shrugging:

Is this mainly intended for use with pinning frameworks such as niv and nixtamal?

Not really, but you can certainly use those now. The main motivation was to make building a NixOS configuration with an empty NIX_PATH possible. It means that you can get rid of nix-channel and declare which Nixpkgs you need to evaluate it. This change also makes nixos-rebuild behave more similarly to nix-build with respect to the --attr flag.

What are the pros and cons compared with flakes?

If you’re already using flakes you probably have no use for this.

While I do remember the release notes entry, I can’t find anything in the manual :person_shrugging:

Yeah, it’s documented in the man pages for nixos-rebuild and nixos-install, but I didn’t have time to write some examples in the NixOS manual.

4 Likes

i used it once. with channels. i didn’t want to use nixpkgs.lib.nixosSystem, i wanted to use a different entry point lib.finixSystem. it worked well in my case.

3 Likes

I think this previous statement by infinisil gives good context to why system.nix is desirable as a means to canonicalize a configuration file that defines a NixOS system (as opposed to the NixOS module) and making it more ergonomic to use with nixos-rebuild

From Pinning configuration.nix with niv - #4 by Infinisil

5 Likes

This system.nix thing was a huge surprise for me. As I haven’t migrated to flakes yet (because they’re not stable), I was intrigued. I’m about 95% done with moving to system.nix; I still have to figure out how to get my standalone Home Manager to see my pinned nixpkgs. I’m calling it with -I in the meantime.

5 Likes

You can’t (automatically), because it’s going to look for a channel called nixpkgs (or more accurately, a path entry in NIX_PATH called nixpkgs), so you’ll need to continue using -I.

The alternative would be setting NIX_PATH globally, if you’re happy with that route.

1 Like

Yeah, this is what I’m leaning towards. With nix.nixPath in my NixOS configuration.nix.

I deal with NIX_PATH like this:

let
  nixpkgs = builtins.fetchTarball { ... };
in
  import "${nixpkgs}/nixos" {
    configuration = {
      imports = [ ./configuration.nix ];
      nix.nixPath = [
        "nixos-config=${toString ./configuration.nix}"
        "nixos-system=${toString ./system.nix}"
        "nixpkgs=/run/current-system/nixpkgs"
      ];
      system.systemBuilderCommands = "ln -s ${nixpkgs} $out/nixpkgs";
    };
  }
  • nixos-config so that nixos-rebuild edit works,
  • nixos-system so I can run nixos-rebuild anywhere,
  • nixpkgs so Nix uses the same Nixpkgs that was used to build the system,
  • and the link to /run/current-system so it doesn’t get gc’ed.
4 Likes

As system.nix now provides a path to specify a NixOS system derivation instead of a module for nixos-rebuild, I think so too would a path need to be implemented to declare a home-manager derivation/activationProfile instead of a module for the home-manager tool.

For now, I think you can “cheat” by making a wrapper that you use to call home-manager with --args to specify the nixpkgs. In other words, the wrapper would call something like home-manager switch --arg pkgs "import (import $(pwd)/npins).nixpkgs {}". If not an npins user, replace the import invocation with something like builtins.fetchTarball or other pinning tool of choice.