NixOS Specialisations - How do you use them?

Hey folks,

I am going through my yearly “try out other DEs and neovim again” exercise and decided to implement it with nixos specialisations this time: https://search.nixos.org/options?channel=20.09&from=0&size=30&sort=relevance&query=specialisation

My understanding is that these are sort of like “runtime-system-profiles” so that you can switch between different configurations within a single generation. So, maybe by default I boot without any GUI configured, and then I “switch” into my sway or gnome or plasma specialisation based on how I feel (or which ones are actually working :P).

Anyway, the exercise has me curious, how many folks use specialisations? Do you have any particularly novel use-cases?

edit: :laughing: I guess I might not be using specialisation for now: https://github.com/NixOS/nixpkgs/issues/97255

4 Likes

I use specialisation so I can easily switch to a system where dedicated graphic card is disabled, CPU undervolting and all options related to power saving are enabled, when I need to use my laptop without power supply.

1 Like

I had no idea this option existed. I’m looking forward to hearing back from now people.

4 Likes

I recently learned about specialisation too: I saw a PR in nixpkgs from someone who too rediscovered the feature and renamed it. The orignal name “nesting” was so criptic probably only a couple people knew about it.

Anyway, I have two specialisations. The first is for when I connect my computer to a tv: it sets up autologin for my user, enables wifi, sets default audio output to HDMI and starts the controller daemon. The other is similar but without the autologin, which I use when travelling but I have access to a keyboard.

I use system.nixos.tags to tag each one with same name as of specialisation.<name>, so they appear in grub menu and I can switch at boot. Btw, grub now has pasword support in NixOS so the autologin completely isn’t insecure.

5 Likes

I recently learned about specialisation too: I saw a PR in nixpkgs from someone who too rediscovered the feature and renamed it. The orignal name “nesting” was so criptic probably only a couple people knew about it.

«nesting» was also a rename from «children»… it’s a bit of a wandering feature.

Same here, it seems a very interesting idea, but unfortunately I wasn’t able to find any examples.
@rnhmjoj are your specialisations open source?

am i getting confused with nixos profiles? are these the same or something different?

am i getting confused with nixos profiles? are these the same or something different?

Profile: bunch of things to apply at once

Specialisation: a boot entry built together with the main system but with slightly different configuration

1 Like

I haven’t published my configurations yet, but here’s the specialisation bit

{
  specialisation = {
    on-the-go.configuration =
      { system.nixos.tags = [ "on-the-go" ];
        networking.wireless.enable = true;

        environment.variables.AUDIO = "hdmi1";
        systemd.services.mpd.environment.AUDIO = "hdmi1";
      };

    tv.configuration =
      { system.nixos.tags = [ "tv" ];
        networking.wireless.enable = true;

        environment.variables.AUDIO = "hdmi1";
        systemd.services.mpd.environment.AUDIO = "hdmi1";

        services.mingetty.autologinUser = "rnhmjoj";
        programs.fish.loginShellInit = ''
          if not pgrep -f sc-controller > /dev/null
            xinit &
            sleep 1
            env DISPLAY=:0 scc daemon start
          end
        '';
     };
  };

}

It’s nothing too fancy, really. The $AUDIO thing works because I have this in my asound.conf:

  pcm.!default {
    @func getenv
    vars [ AUDIO ]
    default pcm.sysdefault
  }
2 Likes

I was able to get specialisations working with flakes, and I managed to achieve what I had set out for (initial boot is just my limited “interactive” profile without any DE or GUI apps, but I have plasma/sway specialisations available to switch to).

But, how do you go back to the parent configuration? It changes /run/current-system and I can’t find any back-reference to the parent toplevel.

That’s a good question. I haven’t found a solution yet, but I haven’t really looked much. One way could be to switch using

$ sudo nix-env --switch-generation 123 -p /nix/var/nix/profiles/system

It would be good if specialisations had a link back to the parent, I don’t think it’s too difficult to do.

Another rough edge: when you nixos-rebuild ... switch the system, it switches back to the “parent” configuration instead of the current “specialisation”. Considering the implementation, it’s not surprising, but it’s not the best UX (and could potentially be very disruptive… especially if display-manager disappears from underneath you…).

Poking around, I think the specialisation module actually reaches into some boot.loader.grub.configurationName option, so if you use systemd-boot, and don’t specify this per-specialisation, it winds up being unset.

I think instead, maybe, it should be inferred from the key in the specialisation option. Then, it would be guaranteed to be available in /run/current-system/configuration-name and then a smarter script can know the current active specialisation and could switch into the built specialisation with the same name.