Modular, context-aware and aspect-oriented dendritic Nix configurations. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ den.oeiuwq.com
configurations den dendritic nix aspect oriented
at main 228 lines 7.3 kB view raw
1{ 2 inputs, 3 lib, 4 den, 5 ... 6}: 7let 8 hostsOption = lib.mkOption { 9 description = "den hosts definition"; 10 default = { }; 11 type = lib.types.attrsOf systemType; 12 }; 13 14 systemType = lib.types.submodule ( 15 { name, ... }: 16 { 17 freeformType = lib.types.attrsOf (hostType name); 18 } 19 ); 20 21 hostType = 22 system: 23 lib.types.submodule ( 24 { name, config, ... }: 25 { 26 freeformType = lib.types.attrsOf lib.types.anything; 27 imports = [ den.schema.host ]; 28 config._module.args.host = config; 29 options = { 30 name = strOpt "host configuration name" name; 31 hostName = strOpt "Network hostname" config.name; 32 system = strOpt "platform system" system; 33 class = strOpt "os-configuration nix class for host" ( 34 if lib.hasSuffix "darwin" config.system then "darwin" else "nixos" 35 ); 36 aspect = strOpt "main aspect name of <class>" config.name; 37 description = strOpt "host description" "${config.class}.${config.hostName}@${config.system}"; 38 users = lib.mkOption { 39 description = "user accounts"; 40 default = { }; 41 type = lib.types.attrsOf userType; 42 }; 43 instantiate = lib.mkOption { 44 description = '' 45 Function used to instantiate the OS configuration. 46 47 Depending on class, defaults to: 48 `darwin`: inputs.darwin.lib.darwinSystem 49 `nixos`: inputs.nixpkgs.lib.nixosSystem 50 `systemManager`: inputs.system-manager.lib.makeSystemConfig 51 52 Set explicitly if you need: 53 54 - a custom input name, eg, nixos-unstable. 55 - adding specialArgs when absolutely required. 56 ''; 57 example = lib.literalExpression "inputs.nixpkgs.lib.nixosSystem"; 58 type = lib.types.raw; 59 default = 60 { 61 nixos = inputs.nixpkgs.lib.nixosSystem; 62 darwin = inputs.darwin.lib.darwinSystem; 63 systemManager = inputs.system-manager.lib.makeSystemConfig; 64 } 65 .${config.class}; 66 }; 67 intoAttr = lib.mkOption { 68 description = '' 69 Flake attr where to add the named result of this configuration. 70 flake.<intoAttr>.<name> 71 72 Depending on class, defaults to: 73 `darwin`: darwinConfigurations 74 `nixos`: nixosConfigurations 75 `systemManager`: systemConfigs 76 ''; 77 example = lib.literalExpression ''[ "nixosConfigurations" hostName ]''; 78 type = lib.types.listOf lib.types.str; 79 default = 80 { 81 nixos = [ 82 "nixosConfigurations" 83 config.name 84 ]; 85 darwin = [ 86 "darwinConfigurations" 87 config.name 88 ]; 89 systemManager = [ 90 "systemConfigs" 91 config.name 92 ]; 93 } 94 .${config.class}; 95 }; 96 mainModule = lib.mkOption { 97 internal = true; 98 visible = false; 99 readOnly = true; 100 type = lib.types.deferredModule; 101 default = mainModule config den.ctx.host "host"; 102 }; 103 }; 104 } 105 ); 106 107 userType = lib.types.submodule ( 108 { name, config, ... }: 109 { 110 freeformType = lib.types.attrsOf lib.types.anything; 111 imports = [ den.schema.user ]; 112 config._module.args.user = config; 113 options = { 114 name = strOpt "user configuration name" name; 115 userName = strOpt "user account name" config.name; 116 classes = lib.mkOption { 117 type = lib.types.listOf lib.types.str; 118 description = "home management nix classes"; 119 default = [ "user" ]; 120 }; 121 aspect = strOpt "main aspect name" config.name; 122 }; 123 } 124 ); 125 126 strOpt = 127 description: default: 128 lib.mkOption { 129 type = lib.types.str; 130 inherit description default; 131 }; 132 133 homesOption = lib.mkOption { 134 description = "den standalone home-manager configurations"; 135 default = { }; 136 type = lib.types.attrsOf homeSystemType; 137 }; 138 139 homeSystemType = lib.types.submodule ( 140 { name, ... }: 141 { 142 freeformType = lib.types.attrsOf (homeType name); 143 } 144 ); 145 146 homeType = 147 system: 148 lib.types.submodule ( 149 { name, config, ... }: 150 { 151 freeformType = lib.types.attrsOf lib.types.anything; 152 imports = [ den.schema.home ]; 153 config._module.args.home = config; 154 options = { 155 name = strOpt "home configuration name" name; 156 userName = strOpt "user account name" config.name; 157 system = strOpt "platform system" system; 158 class = strOpt "home management nix class" "homeManager"; 159 aspect = strOpt "main aspect name" config.name; 160 description = strOpt "home description" "home.${config.userName}@${config.system}"; 161 pkgs = lib.mkOption { 162 description = '' 163 nixpkgs instance used to build the home configuration. 164 ''; 165 example = lib.literalExpression ''inputs.nixpkgs.legacyPackages.''${home.system}''; 166 type = lib.types.raw; 167 default = inputs.nixpkgs.legacyPackages.${config.system}; 168 }; 169 instantiate = lib.mkOption { 170 description = '' 171 Function used to instantiate the home configuration. 172 173 Depending on class, defaults to: 174 `homeManager`: inputs.home-manager.lib.homeManagerConfiguration 175 176 Set explicitly if you need: 177 178 - a custom input name, eg, home-manager-unstable. 179 - adding extraSpecialArgs when absolutely required. 180 ''; 181 example = lib.literalExpression "inputs.home-manager.lib.homeManagerConfiguration"; 182 type = lib.types.raw; 183 default = 184 { 185 homeManager = inputs.home-manager.lib.homeManagerConfiguration; 186 } 187 .${config.class}; 188 }; 189 intoAttr = lib.mkOption { 190 description = '' 191 Flake attr where to add the named result of this configuration. 192 flake.<intoAttr>.<name> 193 194 Depending on class, defaults to: 195 `homeManager`: homeConfigurations 196 ''; 197 example = lib.literalExpression ''[ "homeConfigurations" userName ]''; 198 type = lib.types.listOf lib.types.str; 199 default = 200 { 201 homeManager = [ 202 "homeConfigurations" 203 config.name 204 ]; 205 } 206 .${config.class}; 207 }; 208 mainModule = lib.mkOption { 209 internal = true; 210 visible = false; 211 readOnly = true; 212 type = lib.types.deferredModule; 213 default = mainModule config den.ctx.home "home"; 214 }; 215 }; 216 } 217 ); 218 219 mainModule = 220 from: intent: name: 221 let 222 asp = intent { ${name} = from; }; 223 in 224 den.lib.aspects.resolve (from.class) [ ] asp; 225in 226{ 227 inherit hostsOption homesOption; 228}