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

docs for MicroVM template

+257 -16
+60 -15
README.md
··· 56 56 57 57 [noflake](https://den.oeiuwq.com/tutorials/noflake): -flakes +npins +lib.evalModules +nix-maid 58 58 59 + [microvm](https://den.oeiuwq.com/tutorials/microvm): MicroVM runnable-pkg and guests. custom ctx-pipeline. 60 + 59 61 [example](https://den.oeiuwq.com/tutorials/example): cross-platform 60 62 61 63 [ci](https://den.oeiuwq.com/tutorials/ci): Each feature tested as code examples ··· 98 100 99 101 ## Code example (OS configuration domain) 100 102 103 + ### Defining hosts, users and homes. 104 + 101 105 ```nix 102 - # Define hosts, users & homes 103 106 den.hosts.x86_64-linux.lap.users.vic = {}; 104 107 den.hosts.aarch64-darwin.mac.users.vic = {}; 105 108 den.homes.aarch64-darwin.vic = {}; ··· 111 114 $ home-manager switch --flake .#vic 112 115 ``` 113 116 117 + ### Extensible Schemas for hosts, users and homes. 118 + 114 119 ```nix 115 120 # extensible base modules for common, typed schemas 116 121 den.schema.user = { user, lib, ... }: { ··· 122 127 }; 123 128 ``` 124 129 130 + ### Dendritic Multi-Platform Hosts 131 + 125 132 ```nix 126 133 # modules/my-laptop.nix 127 134 { den, inputs, ... }: { 128 135 den.aspects.my-laptop = { 129 - # re-usable configuration aspects 130 - includes = [ den.aspects.work-vpn ]; 136 + # re-usable configuration aspects. Den batteries and yours. 137 + includes = [ den.provides.hostname den.aspects.work-vpn ]; 131 138 132 139 # regular nixos/darwin modules or any other Nix class 133 140 nixos = { pkgs, ... }: { imports = [ inputs.disko.nixosModules.disko ]; }; 134 141 darwin = { pkgs, ... }: { imports = [ inputs.nix-homebrew.darwinModules.nix-homebrew ]; }; 135 142 136 - # Den `os` Nix class forwards to both nixos and darwin 143 + # Custom Nix classes. `os` applies to both nixos and darwin. contributed by @Risa-G. 144 + # See https://den.oeiuwq.com/guides/custom-classes/#user-contributed-examples 137 145 os = { pkgs, ... }: { 138 - networking.hostName = "yavanna"; 139 - environment.packages = [ pkgs.direnv ]; 146 + environment.systemPackages = [ pkgs.direnv ]; 140 147 }; 141 148 142 - # host can contribute to its users' environment 149 + # host can contribute default home environments to all its users. 143 150 homeManager.programs.vim.enable = true; 144 151 }; 145 152 } 146 153 ``` 147 154 155 + ### Multiple User Home Environments 156 + 148 157 ```nix 149 158 # modules/vic.nix 150 159 { den, ... }: { 151 160 den.aspects.vic = { 152 - # supports multiple home environments 161 + # supports multiple home environments, eg: for migrating from homeManager. 153 162 homeManager = { pkgs, ... }: { }; 154 163 hjem.files.".envrc".text = "use flake ~/hk/home"; 155 164 maid.kconfig.settings.kwinrc.Desktops.Number = 3; 156 165 157 - # user can contribute configurations to all hosts it lives on 166 + # user can contribute OS-configurations to any host it lives on 158 167 darwin.services.karabiner-elements.enable = true; 159 168 160 169 # user class forwards into {nixos/darwin}.users.users.<userName> ··· 173 182 } 174 183 ``` 175 184 176 - ```nix 177 - # Custom Nix classes. 185 + ### Custom Dendritic Nix Classes 186 + 187 + See [custom-classes docs](https://den.oeiuwq.com/guides/custom-classes) for explanation. 178 188 189 + ```nix 179 190 # Example: A class for role-based configuration between users and hosts 180 191 181 192 roleClass = ··· 200 211 }; 201 212 202 213 den.aspects.alice = { 203 - # enabled when host supports gaming role 214 + # enabled when both support gaming role 204 215 gaming = { pkgs, ... }: { programs.steam.enable = true; }; 216 + }; 205 217 206 - # enabled when host supports devops role 218 + den.aspects.bob = { 219 + # enabled when both support devops role 207 220 devops = { pkgs, ... }: { virtualisation.podman.enable = true; }; 221 + 222 + # not enabled at igloo host (bob missing gaming role on that host) 223 + gaming = {}; 208 224 }; 209 225 ``` 210 226 211 - ```nix 212 - # Forward guards allow feature-detection without mkIf/mkMerge cluttering. 227 + ### Guarded Forwarding Classes 228 + 229 + Forward guards allow feature-detection without mkIf/mkMerge cluttering. 230 + 231 + Aspects can simply assign configurations into a class (here `persys`) 232 + from any file, without any `mkIf`/`mkMerge` cluttering. The logic for 233 + determining if the class takes effect is defined at a single place. 213 234 235 + ```nix 214 236 # Aspects use the `persys` class without any conditional. And guard guarantees 215 237 # settings are applied **only** when impermanence module has been imported. 216 238 persys = { host }: den._.forward { ··· 228 250 # aspects just attach config to custom class 229 251 den.aspects.my-laptop.persys.hideMounts = true; 230 252 ``` 253 + 254 + ### User-defined Extensions to Den Framework. 255 + 256 + See example [`template/microvm`](https://den.oeiuwq.com/tutorials/microvm) for an example 257 + of custom `den.ctx` and `den.schema` extensions for supporting 258 + Declarative [MicroVM](https://microvm-nix.github.io/microvm.nix/declarative.html) guests with automatic host-shared `/nix/store`. 259 + 260 + ```nix 261 + den.hosts.x86_64-linux.guest = {}; 262 + den.hosts.x86_64-linux.host = { 263 + microvm.guests = [ den.hosts.x86_64-linux.guest ]; 264 + }; 265 + 266 + den.aspects.guest = { 267 + # propagated into host.nixos.microvm.vms.<name>; 268 + microvm.autostart = true; 269 + 270 + # guest supports all Den features. 271 + includes = [ den.provides.hostname ]; 272 + # As MicroVM guest propagated into host.nixos.microvm.vms.<name>.config; 273 + nixos = { pkgs, ... }: { environment.systemPackages = [ pkgs.hello ]; }; 274 + }; 275 + ```
+2 -1
docs/astro.config.mjs
··· 50 50 { label: 'Overview', slug: 'tutorials/overview' }, 51 51 { label: 'Minimal', slug: 'tutorials/minimal' }, 52 52 { label: 'Default', slug: 'tutorials/default' }, 53 + { label: 'No-Flake', slug: 'tutorials/noflake' }, 54 + { label: 'MicroVM', slug: 'tutorials/microvm' }, 53 55 { label: 'Example', slug: 'tutorials/example' }, 54 - { label: 'No-Flake', slug: 'tutorials/noflake' }, 55 56 { label: 'Bug Reproduction', slug: 'tutorials/bogus' }, 56 57 { label: 'CI Tests', slug: 'tutorials/ci' }, 57 58 ],
+195
docs/src/content/docs/tutorials/microvm.md
··· 1 + --- 2 + title: "Template: MicroVM" 3 + description: Feature showcase MicroVM integration with custom context pipelines and custom classes. 4 + --- 5 + 6 + The MicroVM template demonstrates Den's extensibility: custom `den.ctx` and `den.schema` extensions for integrating other Nix libraries. MicroVM shows two patterns for building VMs with Den. 7 + 8 + ## Two MicroVM Patterns 9 + 10 + ### 1. Runnable MicroVM as Package 11 + 12 + A standalone NixOS configuration that runs as a portable package using QEMU. 13 + 14 + - Den example: [runnable-example.nix](https://github.com/vic/den/tree/main/templates/microvm/modules/runnable-example.nix) 15 + - Den support: [microvm-runners.nix](https://github.com/vic/den/tree/main/templates/microvm/modules/microvm-runners.nix) 16 + 17 + ```console 18 + nix run .#runnable-microvm 19 + ``` 20 + 21 + See [MicroVM Docs on Package Runners](https://microvm-nix.github.io/microvm.nix/packages.html) 22 + 23 + ### 2. Declarative Guest VMs on Host 24 + 25 + Guest MicroVMs declared on a host and managed together. 26 + 27 + - Den example: [guests-example.nix](https://github.com/vic/den/tree/main/templates/microvm/modules/guests-example.nix) 28 + - Den support: [microvm-integration.nix](https://github.com/vic/den/tree/main/templates/microvm/modules/microvm-integration.nix) 29 + 30 + ```console 31 + nixos-rebuild build --flake .#server 32 + ``` 33 + 34 + See [MicroVM Docs on Declarative MicroVMs](https://microvm-nix.github.io/microvm.nix/declarative.html) 35 + 36 + ## Initialize 37 + 38 + ```console 39 + mkdir my-nix && cd my-nix 40 + nix flake init -t github:vic/den#microvm 41 + nix flake update den 42 + ``` 43 + 44 + ## Project Structure 45 + 46 + ``` 47 + flake.nix 48 + modules/ 49 + den.nix # Enable Den + hostname for all hosts 50 + 51 + runnable-example.nix # Standalone NixOS MicroVM with QEMU 52 + microvm-runners.nix # Auto-expose runnable VMs as flake packages 53 + 54 + guests-example.nix # Server host with declarative guest VMs 55 + microvm-integration.nix # Schema extensions + context pipelines 56 + ``` 57 + 58 + ## Key Features Demonstrated 59 + 60 + ### Standalone Runnable MicroVM 61 + 62 + Any runnable MicroVM with `declaredRunner` is auto-exposed as a flake package: 63 + 64 + ```nix 65 + # modules/microvm-runners.nix 66 + flake.packages = { 67 + x86_64-linux.runnable-microvm = <runner>; 68 + }; 69 + ``` 70 + 71 + ### Schema Extensions for MicroVM Options 72 + 73 + `microvm-integration.nix` extends `den.schema.host` with MicroVM-specific options: 74 + 75 + ```nix 76 + options.microvm.guests = lib.mkOption { 77 + type = lib.types.listOf lib.types.raw; 78 + description = "List of Den hosts to run as guest VMs"; 79 + }; 80 + 81 + options.microvm.sharedNixStore = lib.mkEnableOption "Auto share nix store"; 82 + ``` 83 + 84 + ### Host with Declarative Guests 85 + 86 + ```nix 87 + # modules/guests-example.nix 88 + 89 + # Server host with guest VM 90 + den.hosts.x86_64-linux.server.microvm.guests = [ 91 + den.hosts.x86_64-linux.guest-microvm 92 + ]; 93 + 94 + # Guest VM declaration (no top-level nixosConfiguration) 95 + den.hosts.x86_64-linux.guest-microvm.intoAttr = []; 96 + 97 + # Server config 98 + den.aspects.server = { 99 + nixos.microvm.host.startupTimeout = 300; 100 + }; 101 + 102 + # Guest config (forwarded to server's microvm.vms.guest-microvm.config) 103 + den.aspects.guest-microvm = { 104 + nixos = { pkgs, ... }: { 105 + environment.systemPackages = [ pkgs.cowsay ]; 106 + }; 107 + 108 + # Forwarded to server's microvm.vms.guest-microvm 109 + microvm.autostart = true; 110 + }; 111 + ``` 112 + 113 + ### Custom Context Pipeline 114 + 115 + Three-stage pipeline for MicroVM host and guests: 116 + 117 + ```nix 118 + # Stage 1: host → microvm-host (only if guests is non-empty) 119 + ctx.host.into.microvm-host = { host }: 120 + lib.optional (host.microvm.guests != []) { inherit host; }; 121 + 122 + # microvm-host provides Host configuration 123 + ctx.microvm-host.provides.microvm-host = { host }: { 124 + ${host.class}.imports = [ host.microvm.hostModule ]; 125 + }; 126 + 127 + # Stage 2: microvm-host → microvm-guest 128 + ctx.microvm-host.into.microvm-guest = { host }: 129 + map (vm: { inherit host vm; }) host.microvm.guests; 130 + 131 + # Guest configuration forwarded to host 132 + ctx.microvm-host.provides.microvm-guest = { host, vm }: { 133 + includes = [ 134 + # Auto-share nix store if enabled 135 + sharedNixStore, 136 + 137 + # Den resolved NixOS forwarded to <host>.nixos.microvm.vms.${vm.name}.config 138 + (den.provides.forward { ... }), 139 + 140 + # Forward guest microvm class to <host>.nixos.microvm.vms.${vm.name} 141 + (den.provides.forward { ... }), 142 + ]; 143 + }; 144 + ``` 145 + 146 + ## Data Flow 147 + 148 + ```mermaid 149 + graph TD 150 + D1["server host"] 151 + D2["den.ctx.host<br/>normal pipeline"] 152 + D3["server nixos config"] 153 + D5["host.microvm.host<br/>loaded"] 154 + 155 + D6["guest-microvm host"] 156 + D7["den.ctx.host<br/>NORMAL PIPELINE"] 157 + D8["guest nixos config<br/>+ microvm class<br/>all Den features supported"] 158 + 159 + D9["forward to host:<br/>microvm.vms.guest-microvm.config"] 160 + D10["forward to host:<br/>microvm.vms.guest-microvm"] 161 + D11["server nixosConfiguration"] 162 + 163 + D1 -->|Den transforms to| D2 164 + D2 -->|microvm.guests != empty<br/>triggers microvm-host| D5 165 + D2 -->|produces| D3 166 + 167 + D6 -->|Uses normal Den pipeline<br/>den.ctx.host host=guest| D7 168 + D7 -->|produces| D8 169 + 170 + D8 -->|forward nixos| D9 171 + D8 -->|forward microvm| D10 172 + D3 --> D11 173 + D5 --> D11 174 + D9 --> D11 175 + D10 --> D11 176 + ``` 177 + 178 + ## What It Provides 179 + 180 + | Feature | Provided | 181 + |---------|:--------:| 182 + | Custom context pipelines | ✓ | 183 + | Schema extensions | ✓ | 184 + | Forward providers | ✓ | 185 + | Standalone runnable VMs | ✓ | 186 + | Host-guest architecture | ✓ | 187 + | Declarative MicroVM | ✓ | 188 + | Auto nix store sharing | ✓ | 189 + 190 + ## Next Steps 191 + 192 + - Read [MicroVM Documentation](https://microvm-nix.github.io/microvm.nix/) 193 + - Check [Package Runners](https://microvm-nix.github.io/microvm.nix/packages.html) 194 + - Explore [Host Configuration](https://microvm-nix.github.io/microvm.nix/host.html) 195 + - Learn [Declarative VMs](https://microvm-nix.github.io/microvm.nix/declarative.html)