How to import different files based on hostname

Hi!
How can I import different files based on hostname in home-manager as a nixos module? This is what I was trying to do:

{ config, lib, osConfig, ... }:

lib.mkMerge [
  (lib.mkIf (osConfig.networking.hostName == "dell-1") {
    imports = [ ./dell-1.nix ];
  })
  (lib.mkIf (osConfig.networking.hostName == "dell-2") {
    imports = [ ./dell-2.nix ];
  })
  (lib.mkIf (osConfig.networking.hostName == "dell-3") {
    imports = [ ./dell-3.nix ];
  })
]

But that gives me this error:

[root@dell-1:/etc/nixos]# nixos-rebuild switch 
building the system configuration...
error:
       … while calling the 'head' builtin
         at /nix/store/32dh0g41x5w9zkqxqka3rj7h18blqhyh-source/lib/attrsets.nix:1574:11:
         1573|         || pred here (elemAt values 1) (head values) then
         1574|           head values
             |           ^
         1575|         else

       … while evaluating the attribute 'value'
         at /nix/store/32dh0g41x5w9zkqxqka3rj7h18blqhyh-source/lib/modules.nix:846:9:
          845|     in warnDeprecation opt //
          846|       { value = addErrorContext "while evaluating the option `${showOption loc}':" value;
             |         ^
          847|         inherit (res.defsFinal') highestPrio;

       … while evaluating the option `system.build.toplevel':

       … while evaluating definitions from `/nix/store/32dh0g41x5w9zkqxqka3rj7h18blqhyh-source/nixos/modules/system/activation/top-level.nix':

       … while evaluating the option `assertions':

       … while evaluating definitions from `/nix/store/9hhihnwyflj1m47f23yja31mnxckp3ph-source/nixos/common.nix':

       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: The option `home-manager.users.kazimierzkrauze.imports' does not exist. Definition values:
       - In `/nix/store/diyr1y8nlqs4cii0vky1wx87y851yh7r-source/home-manager/kazimierzkrauze/syncthing/syncthing.nix':
           {
             _type = "if";
             condition = true;
             content = [
               /nix/store/diyr1y8nlqs4cii0vky1wx87y851yh7r-source/home-manager/kazimierzkrauze/syncthing/dell-1.nix
           ...

[root@dell-1:/etc/nixos]# 

Don’t use conditional imports, it’s a maintenance and debugging mess. Create separate configs per host, import the common stuff in all, and import the host-specific config in the individual configs.

2 Likes

I went about it a bit differently, I am using “global variables” file(meta.nix). and use a variable for each host(in the flake.nix) file.

This way I don"t duplicate files for each host, but I am able to use common files as templates, with each host having its own global variables that change based on the host name.

For each host there is a machineName variable

      nixosConfigurations = {
        kvm-nixos-server = lib.nixosSystem {
          inherit system;
          specialArgs = {
            inherit inputs;
            machineName = "kvm-nixos-server";
          };
          modules = [
            ./machines/kvm-nixos-server/configuration.nix
            inputs.home-manager.nixosModules.home-manager
            inputs.nix-index-database.nixosModules.nix-index
            inputs.sops-nix.nixosModules.sops
            inputs.disko.nixosModules.disko
          ];
        };

then in the meta file(at the bottom)

  config = lib.mkMerge [
    (lib.mkIf (machineName == "${config.userDefinedGlobalVariables.machines.kvm-nixos-server}") {
      userDefinedGlobalVariables.primeUsername = "drone";
      userDefinedGlobalVariables.hostConfigurationName = "${config.userDefinedGlobalVariables.machines.kvm-nixos-server
      }";
      userDefinedGlobalVariables.systemStateVersion = "24.11";
    })
]

This idea started as a way to avoid repeating variables across the the configurations. E.g:

      localHostIPv4 = lib.mkOption {
        default = "127.0.0.1";
        type = lib.types.str;
        description = "Defines the static IP used by the homelab machine";
      };

and ended up to mange host specific configs.

my repository for reference with files of interest being

  • meta.nix
  • flake.nix

I have solved it quite simply with an option’s default value:

  options.custom = {
    llm.enable = mkOption {
      default =
        if (vars.hostName == "ThinkPad")
        then true
        else false;
      description = "Enable LLMs (ollama, open-webui, lmstudio)";
      type = types.bool;
    };
  };