Combined Manager: New structure for personal NixOS configs

Combined Manager

Combined Manager provides a new structure for personal NixOS configurations.

This is a very new project, and so any kind of feedback is welcome!

No separation

Combined Manager’s main feature is to break separation. If you want, you should be able to keep everything in a single module.
Most NixOS configuration structures are designed to separate related things into multiple files.

Most prominent separations:

  • Dividing modules into system and home categories. These categories are then further maintained in separate files.
  • All flake inputs must be in the same file in flake.nix.

Combined Manager breaks this pattern by allowing modules to add inputs, overlays and Home Manager and Nixpkgs options as if they are simple options.

Examples

Full configurations

Modules

I like to use https://github.com/FlafyDev/nixos-config/blob/5e5e595480a63567840c2764f0a37dd9385bb902/modules/display/hyprland/default.nix as an example for the capabilities of this structure.

  1. The module shows that it’s possible to add Home Manager and System modules and options within the same file.

  2. Additionally the module shows how you can use an option to make a flake input follow “nixpkgs” and disable a cachix.

Context for 2
inputs =
  if cfg.followNixpkgs
  then {
    hyprland = {
      url = "github:hyprwm/Hyprland/v0.25.0";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  }
  else {
    hyprland.url = "github:hyprwm/Hyprland/v0.25.0";
  };

...

os = {
  # No use to add Hyprland's cachix if we use our own Nixpkgs
  nix.settings = mkIf (!cfg.followNixpkgs) {
    trusted-public-keys = [
      "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
    ];
    substituters = [
      "https://hyprland.cachix.org"
    ];
  };
  xdg.portal.enable = true;
  programs.hyprland.enable = true;
};

Module options

Nix code
{
  lib,
  pkgs,
  osConfig,
  hmConfig,
  inputs,
  ...
}: {
  config = {
    # Adding inputs
    inputs = { name.url = "..."; };

    # Importing system modules
    osModules = [ ];

    # Importing Home Manager modules
    hmModules = [ ];

    # Setting overlays
    os.nixpkgs.overlays = [ ];

    # Using `os` to set Nixpkgs options.
    os = { };

    # Set Home Manager username
    hmUsername = username;

    # Using `hm` to set Home Manager options.
    hm = { };
  };
}
7 Likes

The totally-insignificant tiny problem of having to patch Nix should maybe feature more prominently in the blurb.

7 Likes

It’s says so in the Setup section in the README. But I just added a note at the top of the README as well

2 Likes

From the README I’m wondering if there is a possibility to apply combined-manager to just a nixos module (e.g. hyprland) but keep the rest of my configuration outside of combined-manager to e.g. work around the 1 user per system limitation ?

Yeah, you can use combined manager for your system and add modules not related to combined-manager with osModules and hmModules.

are you certain a patch is necessary (not sure I fully understand your code yet)? I have, many times before, just passed in flake inputs via the extraSpecialArgs option to the eval-config.nix function.

1 Like

The nix patch I think is because the flake inputs are set based on information passed to combined-manager, so you need to get around the fact that nix doesn’t allow complex evaluations outside of outputs in a flake.

1 Like

As @Pacman99 said, Nix does not normally allow evaluating inputs in flake.nix. This makes it impossible for combined-manager to allow inputs to be added in files other than flake.nix.

I guess I’m just not clear what you mean by “files” exactly in this context. I mean I know what a file is, but to Nix a file is just another Nix expression that can be imported and evaluated so I’m not understanding why you can’t just pass inputs around.

Obviously there is the module boundary and most people typically do one module per file, so that’s where my brain went. I know there is no computation allowed on flake inputs so I guess I’m just trying to figure out how you are computing inputs and why that is necessary.

Just like you said, nix will not evaluate anything in the inputs attribute of flake.nix. This is why the patch is needed, to allow that attribute to be evaluable and have the ability to separate it into multiple files(or modules). This way you can Add inputs in files other than flake.nix (not possible in vanilla Nix).

If you’re asking why make it possible to add inputs in files other than flake.nix: This is part of the main point of this structure, to separate as much as possible into its own modules. Having all the inputs in the same file is the opposite of that.

I’m not understanding why you can’t just pass inputs around.

I don’t see how this is a solution to Adding more inputs in different files other than flake.nix. I can’t just pass “inputs”(I am guessing you mean the result of the inputs you get in output?) to different modules through extraSpecialArgs and expect it to work.

My guess is that you are confusing between using the result of inputs and Adding more inputs.

If you think I misunderstood what you mean please let me know and elaborate.

I was referring to the other way around - using combined-manager to write a nixosModule which is included in a system config w/o combined-manager

EDIT: For this particular use-case I wouldn’t need comined-manager to merge my inputs.

Actually I was confused about what the problem statement even was, and I think this clarifies it. Thanks, I get it now :+1:

1 Like