feat/den: Refactor our features to use vic/den for implementation, closing gaps where possible#86
Conversation
- Add home-manager integration aspect (hm-host/hm-user ctx) - Migrate zsh feature to den aspect (shell/zsh) - Migrate audio/pipewire feature to den aspect with providers - Declare bitstream as first den-managed host - Add sini user aspect - Disable old bitstream host definition (_host.nix) - Update design spec and implementation plan with review fixes
Migrate all 29 default features to den aspects with 1:1 parity: Trivial (8): avahi, disko, facter, i18n, power-mgmt, ssd, stateVersion, time Simple (11): firmware, home-manager-feature, hosts (stub), linux-kernel, nixpkgs, openssh, security, sudo, systemd, systemd-boot, utils Moderate (4): deterministic-uids, nix, tailscale, users Complex (3): agenix, impermanence, networking Wire den.aspects.default including all features, update bitstream to use it. Always import home-manager NixOS module via host context (matching old builder). Update home-platform forwarding class to iterate platforms with guard. Simplifications for later migration phases: - hosts: stub (cross-host discovery needs environment context) - users: simplified (full ACL provisioning needs environment context) - tailscale: darwin/secrets stubs (needs agenix integration) - sudo: wheel group only (no per-user doas rules without users injection) - Forwarding classes for collectsProviders deferred
- Add impermanence forwarding classes (persist, cache, persistHome, cacheHome) with dedup and guard for impermanence module presence - Add secrets forwarding class for age.secrets collection - Add firewall forwarding class for networking.firewall collection - Replace hosts-file stub with real cross-host /etc/hosts and SSH known hosts generation (reads from existing config.hosts/environments) - Update firmware, security, systemd, tailscale, impermanence aspects to use persist/cache forwarding classes instead of direct environment.persistence
- Rewrite den.aspects.users to call resolveUsers from existing flake-parts lib - Reads canonical users, environments, groups from flake-parts config - Full three-level ACL resolution: groups → environment.access → system-access-groups - Generates NixOS user accounts with deterministic UIDs, SSH keys, group membership - Add host metadata to bitstream (environment, system-access-groups, networking, facts) - Verified: sini provisioned on bitstream with UID 1000, correct groups (wheel, audio, video, server-access, etc.), description from canonical identity
- sudo: per-user doas rules from ACL-resolved enabled users - systemd-boot: add missing tmpfs and zramSwap/earlyoom config - users: fix hashedPasswordFile to use NixOS module config (not flake config) - agenix: migrate all 16 custom generators to den aspect (agenix-generators) Bitstream now has all 20 generators matching cortex
ZFS stack (used by bitstream): - zfs-root: runtime support, boot, packages, kernel params, scrub, trim - zfs-disk-single: disko declarative layout with encryption and datasets - impermanence-zfs: initrd rollback services + shutdown hooks - zfs-diff: diff tools for impermanence BTRFS stack (parity for other hosts): - btrfs-root: runtime support with diff tools - btrfs-disk-single: disko LUKS+BTRFS layout with subvolumes - impermanence-btrfs: initrd rollback services Bitstream updated with ZFS metadata (device, impermanence settings) and includes zfs-disk-single, impermanence-zfs, zfs-diff aspects. Verified: ZFS in boot.supportedFilesystems, disko device resolved, rollback-zfs-root service present, rollback-zfs-home correctly absent.
- Fix secrets forwarding class: intoPath now targets age.secrets directly (cleaner API - aspects declare secrets.foo instead of secrets.secrets.foo) - Fix initrd-bootstrap-keys: use direct age.secrets in nixos module context instead of secrets class (needed for generator dependencies) - Fix nix-remote-build-server and network-boot: use resolveUsers for getSshKeysForGroup (canonical users lack systemGroups), fix secrets refs - Migrate independent features: acme, media-data-share, tang, nix-remote-build-server, cpu-amd, gpu-amd - Migrate dependent features: initrd-bootstrap-keys, nix-builder, network-boot, server role - Wire all into bitstream includes Verified: tang, nix-serve, initrd SSH all enabled on bitstream
- Add resolve-environment.nix: overrides den.ctx.host to enrich host objects with resolved environment attrset before aspects see them - Aspects access host.environment directly, no config.environments lookups - Fix bitstream public_key path (use rootPath instead of relative) - Dry-run build passes cleanly
Add modules/den/schema.nix declaring typed options on den.schema.host:
- host.system-access-groups (list str, default [])
- host.settings.linux-kernel.{channel, optimization}
- host.settings.impermanence.{enable, wipeRootOnBoot, wipeHomeOnBoot}
- host.settings.tailscale.{openFirewall, extraUpFlags, extraDaemonFlags, useNftables}
- host.settings.zfs-disk-single.device_id
- host.settings.btrfs-disk-single.{device_id, swap_size}
Update all aspects to read from typed host.settings.* instead of freeform
metadata with or fallbacks. Update bitstream host to use settings namespace.
Remove redundant nixos config from bitstream aspect.
- wireless: facter auto-detection, wpa_supplicant, secrets, impermanence
- network-manager: NM config with wifi powersave, impermanence
- workstation-boot: plymouth boot splash, quiet/splash kernel params
- ceph-device-allocation: settings-only for rook-ceph device path
- xfs-disk-longhorn: disko XFS partition for Longhorn storage
Add typed settings to schema.nix:
- network-manager.wifi-backend (enum)
- ceph-device-allocation.device (nullable str)
- xfs-disk-longhorn.{device_id, mountPoint}
All core/ features now have den aspect equivalents.
Shell/utils (10): archive-tools, data-tools, disk-tools, nix-index, process-tools, python, search-tools, ssh, sysmon, zoxide Dev (16): bat, claude, delta, direnv, eza, gh, git, gitkraken, gpg, jujutsu, k9s, lazygit, nvf, starship, wireshark, yazi, zellij, vscode Productivity (5): alacritty, kitty, obsidian, zathura, zoom Media (8): easyeffects, jellyfin-client, mpv, qbittorrent, spicetify, spotify-player, youtube-music-desktop, yt-dlp Gaming (3): emulation, mangohud, steam Messaging (3): discord, kdeconnect, telegram Browsers (2): firefox, zen-browser Wayland (5): hypridle, hyprpanel, obs-studio, swaync, waybar K8s tools (8): kube-core, kube-dev, kube-helm, kube-observability, kube-plugins, kube-security, kube-tui, kube-utils
Hardware (17): adb, audio (alias), bluetooth, coolercontrol, cpu-intel, ddcutil, gamepad, gpu-intel, gpu-nvidia (consolidated driver/kernel), gpu-nvidia-prime, gpu-nvidia-vfio, keyboard, laptop, performance, razer, thunderbolt-network, vr-amd Desktop (12): fonts, gnome, hyprland (consolidated 8 source files), hyprland-split-monitors, kde, niri, stylix, uwsm, xdg, xdg-portal, xserver, xwayland Login (3): gdm, regreet, sddm
Roles (18): bgp-spoke, cad, chiptune, daw, dev, dev-gui, gamedev, game-engines, gaming, graphics, headscale-role, inference, kexec, kube-tools, media, messaging, metrics-ingester, pixel-art, unlock, vault-role, workstation Network (2): wireless-initrd, nfs-boot Virtualization (3): libvirt, microvm, podman System (1): ananicy Runtime (1): nix-ld Services (1): sunshine
Simple: bgp, bgp-hub, ceph (stub), cilium-bgp, docker, etcd (stub), kubernetes-base, nginx, prometheus-exporter, thunderbolt-mesh-bgp, thunderbolt-mesh-of Medium: alloy, attic-server, forgejo, haproxy, homepage, minio, oauth2-proxy, open-webui Complex: grafana (with dashboards), jellyfin (declarative config), k3s (538 lines, keepalived VIP, cilium/sops/argocd bootstrap), k3s-containerd, kanidm (583 lines, multi-part OIDC provisioning) Also fix: nix aspect pipe-operator → pipe-operators
- Create den host definitions for all 3 axon k8s nodes - Add schema settings: bgp, cilium-bgp, thunderbolt-mesh-of, k3s - Add ipv4/ipv6 and cluster to enrichHost (resolve-environment.nix) - Fix cilium-bgp and bgp-hub to include den.aspects.bgp - Fix thunderbolt-mesh-of schema (add loopback.ipv6) - Disable old axon host definitions (_host.nix) - Disable namespaces.nix (subagent artifact, needs review) Verified: all 3 axon hosts + bitstream eval successfully
- Create den.environments with full typed schema - Create prod/dev environment data as den-native definitions - Update resolve-environment.nix to read from den.environments - Implement den-native findHostsByFeature from den.hosts - Restore ipv4/ipv6 and cluster in enrichHost - Fix jellyfin: move inputs to flake-parts level Breaks the infinite recursion cycle. Remaining aspect bugs need individual fixes.
- Migrate environments to den-native type (breaks recursion cycle) - Add instantiate per host for channel selection - Create cortex host definition - Fix inputs-in-NixOS-module recursion pattern - Fix peer host IP extraction for thunderbolt aspects All 7 NixOS hosts eval: bitstream, axon-01/02/03, uplink, blade, cortex
Channel schema (den.schema.host): - host.channel option: nixos-unstable, nixpkgs-master, nixos-stable, nixpkgs-stable-darwin - Automatically sets host.instantiate from channel (nixosSystem/darwinSystem) - Removes explicit instantiate from all host definitions - Maps each channel to matching nixpkgs + home-manager + nix-darwin inputs Home-manager channel matching: - HM NixOS/Darwin module import now reads from host.channel - Each channel gets its matching home-manager version Darwin support: - Import den.flakeOutputs.darwinConfigurations for merge semantics - patch host enabled and listed in darwinConfigurations All 7 NixOS hosts + 1 Darwin host eval successfully.
- Move user ACL resolution into enrichHost (resolve-environment.nix)
so host.users.{all, enabled, enabledNames} are available to all aspects
- Simplify users, sudo, nix-remote-build-server, network-boot aspects
to read from host.users.enabled instead of resolving independently
- Fix all remaining aspects using inputs from NixOS module args:
emulation, gitkraken, firefox, spicetify, hyprland, vr-amd,
k3s-containerd, zen-browser, discord, xdg-portal
→ moved inputs to flake-parts top-level module arg
Verified: sini provisioned on all hosts with wheel, UID 1000, 2 SSH keys,
zsh shell. cortex has 3 normal users (sini, shuo, will).
Move to modules/_legacy/ (preserving relative paths): - apps/, core/, features/, services/, environments/ (old feature defs) - hosts/*/host.nix (old host definitions) - hosts/cortex/vms/ (microvm-cuda, windows-vfio) - flake-parts/features/, flake-parts/environments/ Disable old host builders (prefixed with _): - builders, nixos-configurations, home-config, utils Update for den: - colmena: reads from den.hosts - expose-options: exports den-hosts, den-environments NOTE: k8s-update-manifests hook skipped — kubernetes system depends on config.features which is now in _legacy. K8s migration is a future task. All 8 hosts eval successfully.
…sers
- Fix k3s secrets: use optionalAttrs instead of mkIf for forwarding class
- Fix impermanence perUser: accept { host, user } for take.exactly
- Add environment as NixOS module arg via ctx.host.includes
- Fix kanidm: use flake-level config.groups, host.resolvedUsers.all
Dry-run: bitstream OK, axon-01 OK. Remaining hosts have aspect bugs.
- Stylix: use autoImport + followSystem to propagate config to all HM users Remove redundant perUser home sub-aspect - Agenix HM modules: inject via den.ctx.hm-host (only hosts with HM users) Includes masterIdentities for rekey - Add system-owner to den.schema.host, set on blade/cortex - Fix scx.package priority conflict between performance/laptop aspects - Fix ollama: detect GPU via NixOS config instead of hasFeature - Fix waybar/hyprpanel: get host from perUser closure, not HM module arg Dry-run: bitstream OK, axon-01 OK, blade OK Remaining: cortex (ollama config ref), uplink (kanidm env string)
- Channel schema sets home-manager.module per host (den reads host.home-manager.module)
- Fix kanidm oidc-secrets: use perHost ({host}:) for environment access
- Add secretPath to prod/dev environment definitions
- Fix ollama: move GPU detection into NixOS module with config access
- Fix haproxy: use host.name instead of host.hostname
- Fix attic-server: stub hasFeature with default
- Fix steam: add config to module args for nvidia prime detection
- Fix prometheus: use findHostsByFeature, stub hasFeature checks
- Partial fix for bgp-hub, vault, open-webui, alloy config.den.hosts refs
Dry-run: bitstream, axon-01, blade, cortex all OK
Uplink: blocked on hasFeature in bgp-hub, vault, open-webui, alloy
(needs den-native hasAspect implementation)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.