a flake module to ease creating and managing multiple hosts in your nix flake.

feat: add tags and perTag options to flake-module

This works like `class` and `perClass`, but allows for setting multiple
of them, this way you can do something like:

```nix
{
easy-hosts.hosts.lemon = {
class = "nixos";
tags = ["laptop" "gaming" "work"];
};
easy-hosts.perTag =
let
tagModule = {
gaming = ./modules/gaming;
laptop = ./modules/laptop;
work = ./modules/work;
};
in
tag: {
modules = [tagModule.${tag}];
};
}
```

authored by Jalil David Salamé Messina and committed by isabelroses.com 72dc72f9 867059dd

Changed files
+81 -10
examples
multi
hosts
aarch64-nixos
test2
x86_64-nixos
test3
test4
+5
README.md
··· 37 37 - `modules`: A list of modules that will be included in all the hosts of the given class. 38 38 - `specialArgs`: A list of special arguments that will be passed to all the hosts of the given class. 39 39 40 + - `easy-hosts.perTag`: This provides you with the `tag` argument such that you can specify what tags get which modules. 41 + - `modules`: A list of modules that will be included in all the hosts with the given tag. 42 + - `specialArgs`: A list of special arguments that will be passed to all the hosts with the given tag. 43 + 40 44 - `easy-hosts.additionalClasses`: This is an attrset of strings with mappings to any of [ "nixos", "darwin", "iso" ]. The intention here to provide a nicer api for `perClass` to operate, you may find yourself including `wsl` as a class because of this. 41 45 42 46 - `easy-hosts.hosts.<host>`: The options for the given host. ··· 44 48 - `arch`: The architecture of the host. 45 49 - `modules`: A list of modules that will be included in the host. 46 50 - `class`: the class of the host, this can be one of [ "nixos", "darwin", "iso" ] or anything defined by `easy-hosts.additionalClasses`. 51 + - `tags`: tags that apply to the host, you can use this like `class`, but it allows for multiple of them to be present. 47 52 - `specialArgs`: A list of special arguments that will be passed to the host. 48 53 - `deployable`: this was added for people who may want to consume a deploy-rs or colmena flakeModule. 49 54
+17
examples/multi/flake.nix
··· 20 20 easy-hosts = { 21 21 autoConstruct = true; 22 22 path = ./hosts; 23 + 24 + # Reduce size of the image 25 + hosts.test3.tags = [ "minimal" ]; 26 + 27 + perTag = 28 + let 29 + tags = { 30 + minimal = 31 + { modulesPath, ... }: 32 + { 33 + imports = [ "${modulesPath}/profiles/minimal.nix" ]; 34 + }; 35 + }; 36 + in 37 + tag: { 38 + modules = [ tags.${tag} ]; 39 + }; 23 40 }; 24 41 }; 25 42 }
examples/multi/hosts/aarch64-linux/test2/default.nix examples/multi/hosts/aarch64-nixos/test2/default.nix
examples/multi/hosts/x86_64-linux/test3/default.nix examples/multi/hosts/x86_64-nixos/test3/default.nix
examples/multi/hosts/x86_64-linux/test4/default.nix examples/multi/hosts/x86_64-nixos/test4/default.nix
+42
flake-module.nix
··· 93 93 description = "Per class settings"; 94 94 }; 95 95 96 + perTag = mkOption { 97 + default = _: { 98 + modules = [ ]; 99 + specialArgs = { }; 100 + }; 101 + defaultText = '' 102 + tag: { 103 + modules = [ ]; 104 + specialArgs = { }; 105 + }; 106 + ''; 107 + 108 + type = types.functionTo ( 109 + types.submodule { 110 + options = mkBasicParams "Per tag"; 111 + } 112 + ); 113 + 114 + example = literalExpression '' 115 + let 116 + tagModule = { 117 + laptop = ./modules/laptop; 118 + gaming = ./modules/gaming; 119 + }; 120 + in 121 + tag: { 122 + modules = [ tagModule.''${tag} ]; 123 + 124 + specialArgs = { }; 125 + } 126 + ''; 127 + 128 + description = "Per tag settings"; 129 + }; 130 + 96 131 additionalClasses = mkOption { 97 132 default = { }; 98 133 type = types.attrsOf types.str; ··· 162 197 default = "nixos"; 163 198 example = "darwin"; 164 199 description = "The class of the host"; 200 + }; 201 + 202 + tags = mkOption { 203 + type = types.listOf types.str; 204 + default = [ ]; 205 + example = [ "laptop" ]; 206 + description = "Extra tags for the host"; 165 207 }; 166 208 167 209 system = mkOption {
+17 -10
lib.nix
··· 363 363 let 364 364 # memoize the class and perClass values so we don't have to recompute them 365 365 perClass = easyHostsConfig.perClass hostConfig.class; 366 + perTag = builtins.map (easyHostsConfig.perTag) hostConfig.tags; 366 367 class = redefineClass easyHostsConfig.additionalClasses hostConfig.class; 367 368 in 368 369 toHostOutput { ··· 378 379 nix-darwin 379 380 ; 380 381 381 - modules = concatLists [ 382 - hostConfig.modules 383 - easyHostsConfig.shared.modules 384 - perClass.modules 385 - ]; 382 + modules = concatLists ( 383 + [ 384 + hostConfig.modules 385 + easyHostsConfig.shared.modules 386 + perClass.modules 387 + ] 388 + ++ (builtins.map ({ modules, ... }: modules) perTag) 389 + ); 386 390 387 - specialArgs = foldAttrsMergeRec [ 388 - hostConfig.specialArgs 389 - easyHostsConfig.shared.specialArgs 390 - perClass.specialArgs 391 - ]; 391 + specialArgs = foldAttrsMergeRec ( 392 + [ 393 + hostConfig.specialArgs 394 + easyHostsConfig.shared.specialArgs 395 + perClass.specialArgs 396 + ] 397 + ++ (builtins.map ({ specialArgs, ... }: specialArgs) perTag) 398 + ); 392 399 }; 393 400 } 394 401 ))