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
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

update readme

+75 -23
+75 -23
README.md
··· 116 116 > Den is a playground for some very advanced concepts. I’m convinced that some of its ideas will play a role in future Nix areas. In my opinion there are some raw diamonds in Den.\ 117 117 > — `@Doc-Steve` - Author of [Dendritic Design Guide](https://github.com/Doc-Steve/dendritic-design-with-flake-parts) 118 118 119 - ## Code example (OS configuration domain) 119 + ## Code examples (OS configuration framework) 120 120 121 121 ### Defining hosts, users and homes. 122 + 123 + Simplest example, one-liner definitions. 122 124 123 125 ```nix 124 126 den.hosts.x86_64-linux.lap.users.vic = {}; 125 127 den.hosts.aarch64-darwin.mac.users.vic = {}; 126 - den.homes.aarch64-darwin.vic = {}; 128 + den.homes.aarch64-darwin."vic@mac" = {}; 127 129 ``` 130 + 131 + The `den.aspects.vic` aspect is shared between 132 + these two hosts and standalone home-manager. 133 + 134 + The `vic@mac` homeConfiguration has `osConfig = mac.config`. 135 + 136 + Activate with: 128 137 129 138 ```console 130 - $ nixos-rebuild switch --flake .#lap 139 + $ nixos-rebuild switch --flake .#lap 131 140 $ darwin-rebuild switch --flake .#mac 132 141 $ home-manager switch --flake .#vic 133 142 ``` 134 143 135 144 ### Extensible Schemas for hosts, users and homes. 136 145 146 + These allow meta-configuration on entities, akin to 147 + what Dendritic flake-parts users do with top-level 148 + options, but here scoped to each entity type. 149 + 150 + People use this for declaring host or user capabilities 151 + that will later be used by aspects to implement configurations. 152 + 137 153 ```nix 138 154 # extensible base modules for common, typed schemas 139 155 den.schema.user = { user, lib, ... }: { ··· 147 163 148 164 ### Dendritic Multi-Platform Hosts 149 165 166 + A single aspect like `den.aspects.workstation` can be 167 + shared between (included-at) NixOS/nix-Darwin/WSL hosts. 168 + 169 + Each aspect uses several Nix classes to define behaviour. 170 + 150 171 ```nix 151 - # modules/my-laptop.nix 172 + # modules/workstation.nix 152 173 { den, inputs, ... }: { 153 - den.aspects.my-laptop = { 174 + den.aspects.workstation = { 154 175 # re-usable configuration aspects. Den batteries and yours. 155 176 includes = [ den.provides.hostname den.aspects.work-vpn ]; 156 177 ··· 158 179 nixos = { pkgs, ... }: { imports = [ inputs.disko.nixosModules.disko ]; }; 159 180 darwin = { pkgs, ... }: { imports = [ inputs.nix-homebrew.darwinModules.nix-homebrew ]; }; 160 181 161 - # Custom Nix classes. `os` applies to both nixos and darwin. contributed by @Risa-G. 182 + # Custom Nix classes. `os` applies to both nixos and darwin. 183 + # Contributed by @Risa-G. 162 184 # See https://den.oeiuwq.com/guides/custom-classes/#user-contributed-examples 163 185 os = { pkgs, ... }: { 164 186 environment.systemPackages = [ pkgs.direnv ]; 165 187 }; 166 188 167 - # host can contribute default home environments to all its users. 168 - homeManager.programs.vim.enable = true; 189 + # host can contribute default home environments 190 + # to all its users. 191 + provides.to-users = { 192 + homeManager = { pkgs, ... }: { 193 + programs.vim.enable = true; 194 + home.packages = [ pkgs.neovide ]; 195 + }; 196 + }; 169 197 }; 170 198 } 171 199 ``` 172 200 173 201 ### Multiple User Home Environments 174 202 203 + Each user can define configurations for different 204 + home environments, aiding with migration from 205 + homeManager to hjem or others. 206 + 175 207 ```nix 176 208 # modules/vic.nix 177 209 { den, ... }: { 210 + 178 211 den.aspects.vic = { 179 - # supports multiple home environments, eg: for migrating from homeManager. 212 + # supports multiple home environments 180 213 homeManager = { pkgs, ... }: { }; 181 214 hjem.files.".envrc".text = "use flake ~/hk/home"; 182 215 maid.kconfig.settings.kwinrc.Desktops.Number = 3; 183 216 184 - # user can contribute OS-configurations to any host it lives on 217 + # user can contribute OS-configurations 218 + # to all hosts it lives on 185 219 darwin.services.karabiner-elements.enable = true; 186 220 187 - # user class forwards into {nixos/darwin}.users.users.<userName> 221 + # user can specify config for specific host 222 + provides.rog-tower = { 223 + nixos = ...; # enable CUDA and gaming profile 224 + }; 225 + 226 + # user class forwards into 227 + # {nixos/darwin}.users.users.<userName> 188 228 user = { pkgs, ... }: { 189 229 packages = [ pkgs.helix ]; 190 230 description = "oeiuwq"; ··· 202 242 203 243 ### Custom Dendritic Nix Classes 204 244 205 - [Custom classes](https://den.oeiuwq.com/guides/custom-classes) is how Den implements `homeManager`, `hjem`, `wsl`, `microvm` support. You can use the very same mechanism to create your own classes. 245 + [Custom classes](https://den.oeiuwq.com/guides/custom-classes) is how Den implements `user`, `homeManager`, `hjem`, `wsl`, `microvm` support. You can use the very same mechanism to create your own Nix classes. 246 + 247 + The `den.provides.forward` battery is the core of it. 206 248 207 249 ```nix 208 250 # Example: A class for role-based configuration between users and hosts ··· 244 286 245 287 ### Guarded Forwarding Classes 246 288 247 - Forward guards allow feature-detection without mkIf/mkMerge cluttering. 289 + Any module/file can contribute to any aspects directly 290 + into their feature-concern Nix classes, without 291 + having to deal with feature-detection or having 292 + `mkIf`/`mkMerge` clutterring on all the codebase. 248 293 249 - Aspects can simply assign configurations into a class (here `persys`) 250 - from any file, without any `mkIf`/`mkMerge` cluttering. The logic for 251 - determining if the class takes effect is defined at a single place. 294 + The logic (guard) for conditional inclusion of a 295 + forwarded-class configuration is defined at a 296 + single place. 252 297 253 298 #### Example: Platform Aware `homeManager` classes 254 299 ··· 257 302 on specific platforms. 258 303 259 304 ```nix 260 - hmPlatforms = 305 + # aspect `tux` is used on both platforms 306 + den.hosts.x86_64-linux.igloo.users.tux = { }; 307 + den.hosts.aarch64-darwin.apple.users.tux = { }; 308 + 309 + den.aspects.hmPlatforms = 261 310 { class, aspect-chain }: 262 311 den._.forward { 263 312 each = [ "Linux" "Darwin" ]; ··· 268 317 guard = { pkgs, ... }: platform: lib.mkIf pkgs.stdenv."is${platform}"; 269 318 adaptArgs = { config, ... }: { osConfig = config; }; 270 319 }; 271 - 272 - den.hosts.x86_64-linux.igloo.users.tux = { }; 273 - den.hosts.aarch64-darwin.apple.users.tux = { }; 274 320 275 321 den.aspects.tux = { 276 - includes = [ hmPlatforms ]; 322 + includes = [ den.aspects.hmPlatforms ]; 323 + 277 324 hmDarwin = { pkgs, ... }: { home.packages = [ pkgs.iterm2 ]; }; 325 + 278 326 hmLinux = { pkgs, ... }: { home.packages = [ pkgs.wl-clipboard-rs ]; }; 279 327 }; 280 328 ``` 281 329 282 330 #### Example: Class for Impermanence Capability 283 331 332 + Modules define configurations at aspects using the 333 + `persys` class directly, without any conditional. 334 + 335 + The guard guarantees they are applied **only** 336 + when impermanence module is enabled at host. 337 + 284 338 > Inspired by @Doc-Steve 285 339 286 340 ```nix 287 - # Aspects use the `persys` class without any conditional. And guard guarantees 288 - # settings are applied **only** when impermanence module has been imported. 289 341 persys = { host }: den._.forward { 290 342 each = lib.singleton true; 291 343 fromClass = _: "persys";