From 0a7998691416fdef9991d30799227ca4f04f3e8f Mon Sep 17 00:00:00 2001 From: Christoph Schmatzler Date: Mon, 23 Mar 2026 07:17:32 +0000 Subject: [PATCH] refactor --- AGENTS.md | 10 +++-- README.md | 17 +++++--- .../_parts}/michael/backups.nix | 0 .../_parts}/michael/disk-config.nix | 0 .../_parts}/michael/gitea.nix | 6 +-- .../michael/hardware-configuration.nix | 0 .../_parts}/tahani/adguardhome.nix | 0 .../{_hosts => hosts/_parts}/tahani/cache.nix | 0 .../_parts}/tahani/networking.nix | 0 .../paperless-gpt-prompts/tag_prompt.tmpl | 0 .../paperless-gpt-prompts/title_prompt.tmpl | 0 .../_parts}/tahani/paperless.nix | 0 modules/{ => hosts}/chidi.nix | 22 +--------- modules/hosts/jason.nix | 21 ++++++++++ modules/{ => hosts}/michael.nix | 22 +++------- modules/{ => hosts}/tahani.nix | 36 +++++------------ modules/{hosts.nix => inventory.nix} | 0 modules/jason.nix | 40 ------------------- modules/profiles/host/darwin-base.nix | 7 ++++ modules/profiles/host/nixos-base.nix | 8 ++++ modules/profiles/host/public-server.nix | 6 +++ modules/profiles/user/base.nix | 17 ++++++++ modules/profiles/user/darwin-laptop.nix | 12 ++++++ modules/profiles/user/minimal.nix | 11 +++++ modules/profiles/user/personal.nix | 5 +++ modules/profiles/user/workstation.nix | 8 ++++ 26 files changed, 134 insertions(+), 114 deletions(-) rename modules/{_hosts => hosts/_parts}/michael/backups.nix (100%) rename modules/{_hosts => hosts/_parts}/michael/disk-config.nix (100%) rename modules/{_hosts => hosts/_parts}/michael/gitea.nix (92%) rename modules/{_hosts => hosts/_parts}/michael/hardware-configuration.nix (100%) rename modules/{_hosts => hosts/_parts}/tahani/adguardhome.nix (100%) rename modules/{_hosts => hosts/_parts}/tahani/cache.nix (100%) rename modules/{_hosts => hosts/_parts}/tahani/networking.nix (100%) rename modules/{_hosts => hosts/_parts}/tahani/paperless-gpt-prompts/tag_prompt.tmpl (100%) rename modules/{_hosts => hosts/_parts}/tahani/paperless-gpt-prompts/title_prompt.tmpl (100%) rename modules/{_hosts => hosts/_parts}/tahani/paperless.nix (100%) rename modules/{ => hosts}/chidi.nix (51%) create mode 100644 modules/hosts/jason.nix rename modules/{ => hosts}/michael.nix (50%) rename modules/{ => hosts}/tahani.nix (65%) rename modules/{hosts.nix => inventory.nix} (100%) delete mode 100644 modules/jason.nix create mode 100644 modules/profiles/host/darwin-base.nix create mode 100644 modules/profiles/host/nixos-base.nix create mode 100644 modules/profiles/host/public-server.nix create mode 100644 modules/profiles/user/base.nix create mode 100644 modules/profiles/user/darwin-laptop.nix create mode 100644 modules/profiles/user/minimal.nix create mode 100644 modules/profiles/user/personal.nix create mode 100644 modules/profiles/user/workstation.nix diff --git a/AGENTS.md b/AGENTS.md index 68bc265..09fc9b2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,10 +33,12 @@ alejandra . # Format all Nix files ### File Structure - **Modules**: `modules/` - All configuration (flake-parts modules, auto-imported by import-tree) + - `hosts/` - Per-host composition modules + - `profiles/` - Shared host and user profile bundles - `_lib/` - Utility functions (underscore = ignored by import-tree) - `_darwin/` - Darwin-specific sub-modules - `_neovim/` - Neovim plugin configs - - `_hosts/` - Host-specific sub-files (disk-config, hardware, etc.) + - `hosts/_parts/` - Host-specific leaf files (disk-config, hardware, service fragments, etc.) - **Apps**: `apps/` - Per-system app scripts (Nushell) - **Secrets**: `secrets/` - SOPS-encrypted secrets (`.sops.yaml` for config) @@ -52,7 +54,9 @@ alejandra . # Format all Nix files - `homeManager` - Home Manager configuration - `os` - Applies to both NixOS and darwin -**Hosts**: `den.hosts..` defined in `modules/hosts.nix` +**Hosts**: `den.hosts..` declared in `modules/inventory.nix` + +**Profiles**: shared bundles live under `modules/profiles/{host,user}` and are exposed as `den.aspects.host-*` and `den.aspects.user-*` **Defaults**: `den.default.*` defined in `modules/defaults.nix` @@ -131,7 +135,7 @@ in { ### Secrets Management - Use SOPS for secrets (see `.sops.yaml`) - Never commit unencrypted secrets -- Secret definitions live in per-host modules (`modules/michael.nix`, `modules/tahani.nix`, etc.) +- Secret definitions live in per-host modules (`modules/hosts/michael.nix`, `modules/hosts/tahani.nix`, etc.) - Shared SOPS defaults (module imports, key paths) in `modules/secrets.nix` ### Aspect Composition diff --git a/README.md b/README.md index aee4521..f18ba20 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,9 @@ Personal Nix flake for four machines: ## Repository Map - `modules/` - flake-parts modules, auto-imported via `import-tree` -- `modules/_hosts/` - host-specific submodules like hardware, disks, and services +- `modules/hosts/` - per-host composition modules +- `modules/hosts/_parts/` - host-private leaf modules like hardware, disks, and services +- `modules/profiles/` - shared host and user profile bundles - `modules/_lib/` - local helper functions - `apps/` - Nushell apps exposed through the flake - `secrets/` - SOPS-encrypted secrets @@ -21,9 +23,11 @@ Personal Nix flake for four machines: This repo uses `den` and organizes configuration around aspects instead of putting everything directly in host files. -- shared behavior lives in `den.aspects..` modules -- hosts are declared in `modules/hosts.nix` -- host composition happens in `modules/.nix` +- shared behavior lives in `den.aspects..` modules under `modules/*.nix` +- the machine inventory lives in `modules/inventory.nix` +- shared bundles live in `modules/profiles/{host,user}/` +- host composition happens in `modules/hosts/.nix` +- host-private imports live in `modules/hosts/_parts//` - user-level config mostly lives in Home Manager aspects Common examples: @@ -31,8 +35,9 @@ Common examples: - `modules/core.nix` - shared Nix and shell foundation - `modules/dev-tools.nix` - VCS, language, and developer tooling - `modules/network.nix` - SSH, fail2ban, and tailscale aspects -- `modules/michael.nix` - server composition for `michael` -- `modules/tahani.nix` - server/workstation composition for `tahani` +- `modules/profiles/user/workstation.nix` - shared developer workstation user bundle +- `modules/hosts/michael.nix` - server composition for `michael` +- `modules/hosts/tahani.nix` - server/workstation composition for `tahani` ## Common Commands diff --git a/modules/_hosts/michael/backups.nix b/modules/hosts/_parts/michael/backups.nix similarity index 100% rename from modules/_hosts/michael/backups.nix rename to modules/hosts/_parts/michael/backups.nix diff --git a/modules/_hosts/michael/disk-config.nix b/modules/hosts/_parts/michael/disk-config.nix similarity index 100% rename from modules/_hosts/michael/disk-config.nix rename to modules/hosts/_parts/michael/disk-config.nix diff --git a/modules/_hosts/michael/gitea.nix b/modules/hosts/_parts/michael/gitea.nix similarity index 92% rename from modules/_hosts/michael/gitea.nix rename to modules/hosts/_parts/michael/gitea.nix index d9c93bc..1801993 100644 --- a/modules/_hosts/michael/gitea.nix +++ b/modules/hosts/_parts/michael/gitea.nix @@ -5,21 +5,21 @@ }: { sops.secrets = { michael-gitea-litestream = { - sopsFile = ../../../secrets/michael-gitea-litestream; + sopsFile = ../../../../secrets/michael-gitea-litestream; format = "binary"; owner = "gitea"; group = "gitea"; path = "/run/secrets/michael-gitea-litestream"; }; michael-gitea-restic-password = { - sopsFile = ../../../secrets/michael-gitea-restic-password; + sopsFile = ../../../../secrets/michael-gitea-restic-password; format = "binary"; owner = "gitea"; group = "gitea"; path = "/run/secrets/michael-gitea-restic-password"; }; michael-gitea-restic-env = { - sopsFile = ../../../secrets/michael-gitea-restic-env; + sopsFile = ../../../../secrets/michael-gitea-restic-env; format = "binary"; owner = "gitea"; group = "gitea"; diff --git a/modules/_hosts/michael/hardware-configuration.nix b/modules/hosts/_parts/michael/hardware-configuration.nix similarity index 100% rename from modules/_hosts/michael/hardware-configuration.nix rename to modules/hosts/_parts/michael/hardware-configuration.nix diff --git a/modules/_hosts/tahani/adguardhome.nix b/modules/hosts/_parts/tahani/adguardhome.nix similarity index 100% rename from modules/_hosts/tahani/adguardhome.nix rename to modules/hosts/_parts/tahani/adguardhome.nix diff --git a/modules/_hosts/tahani/cache.nix b/modules/hosts/_parts/tahani/cache.nix similarity index 100% rename from modules/_hosts/tahani/cache.nix rename to modules/hosts/_parts/tahani/cache.nix diff --git a/modules/_hosts/tahani/networking.nix b/modules/hosts/_parts/tahani/networking.nix similarity index 100% rename from modules/_hosts/tahani/networking.nix rename to modules/hosts/_parts/tahani/networking.nix diff --git a/modules/_hosts/tahani/paperless-gpt-prompts/tag_prompt.tmpl b/modules/hosts/_parts/tahani/paperless-gpt-prompts/tag_prompt.tmpl similarity index 100% rename from modules/_hosts/tahani/paperless-gpt-prompts/tag_prompt.tmpl rename to modules/hosts/_parts/tahani/paperless-gpt-prompts/tag_prompt.tmpl diff --git a/modules/_hosts/tahani/paperless-gpt-prompts/title_prompt.tmpl b/modules/hosts/_parts/tahani/paperless-gpt-prompts/title_prompt.tmpl similarity index 100% rename from modules/_hosts/tahani/paperless-gpt-prompts/title_prompt.tmpl rename to modules/hosts/_parts/tahani/paperless-gpt-prompts/title_prompt.tmpl diff --git a/modules/_hosts/tahani/paperless.nix b/modules/hosts/_parts/tahani/paperless.nix similarity index 100% rename from modules/_hosts/tahani/paperless.nix rename to modules/hosts/_parts/tahani/paperless.nix diff --git a/modules/chidi.nix b/modules/hosts/chidi.nix similarity index 51% rename from modules/chidi.nix rename to modules/hosts/chidi.nix index 92895e6..59e5535 100644 --- a/modules/chidi.nix +++ b/modules/hosts/chidi.nix @@ -2,34 +2,16 @@ den.hosts.aarch64-darwin.chidi.users.cschmatzler.aspect = "chidi-cschmatzler"; den.aspects.chidi-cschmatzler = { - includes = [ - den.aspects.shell - den.aspects.ssh-client - den.aspects.terminal - den.aspects.atuin - den.aspects.dev-tools - den.aspects.neovim - den.aspects.ai-tools - den.aspects.secrets - den.aspects.zellij - den.aspects.zk - den.aspects.desktop - ]; + includes = [den.aspects.user-darwin-laptop]; homeManager = {...}: { - programs.home-manager.enable = true; - fonts.fontconfig.enable = true; programs.git.settings.user.email = "christoph@tuist.dev"; }; }; den.aspects.chidi.includes = [ (den.lib.perHost { - includes = [ - den.aspects.darwin-system - den.aspects.core - den.aspects.tailscale - ]; + includes = [den.aspects.host-darwin-base]; darwin = {pkgs, ...}: { networking.hostName = "chidi"; diff --git a/modules/hosts/jason.nix b/modules/hosts/jason.nix new file mode 100644 index 0000000..af7a17b --- /dev/null +++ b/modules/hosts/jason.nix @@ -0,0 +1,21 @@ +{den, ...}: { + den.hosts.aarch64-darwin.jason.users.cschmatzler.aspect = "jason-cschmatzler"; + + den.aspects.jason-cschmatzler = { + includes = [ + den.aspects.user-darwin-laptop + den.aspects.user-personal + ]; + }; + + den.aspects.jason.includes = [ + (den.lib.perHost { + includes = [den.aspects.host-darwin-base]; + + darwin = {...}: { + networking.hostName = "jason"; + networking.computerName = "jason"; + }; + }) + ]; +} diff --git a/modules/michael.nix b/modules/hosts/michael.nix similarity index 50% rename from modules/michael.nix rename to modules/hosts/michael.nix index cadc268..62da41a 100644 --- a/modules/michael.nix +++ b/modules/hosts/michael.nix @@ -6,30 +6,20 @@ den.hosts.x86_64-linux.michael.users.cschmatzler.aspect = "michael-cschmatzler"; den.aspects.michael-cschmatzler = { - includes = [den.aspects.shell]; - - homeManager = {...}: { - programs.home-manager.enable = true; - }; + includes = [den.aspects.user-minimal]; }; den.aspects.michael.includes = [ (den.lib.perHost { - includes = [ - den.aspects.nixos-system - den.aspects.core - den.aspects.openssh - den.aspects.fail2ban - den.aspects.tailscale - ]; + includes = [den.aspects.host-public-server]; nixos = {modulesPath, ...}: { imports = [ (modulesPath + "/installer/scan/not-detected.nix") - ./_hosts/michael/backups.nix - ./_hosts/michael/disk-config.nix - ./_hosts/michael/gitea.nix - ./_hosts/michael/hardware-configuration.nix + ./_parts/michael/backups.nix + ./_parts/michael/disk-config.nix + ./_parts/michael/gitea.nix + ./_parts/michael/hardware-configuration.nix inputs.disko.nixosModules.default ]; diff --git a/modules/tahani.nix b/modules/hosts/tahani.nix similarity index 65% rename from modules/tahani.nix rename to modules/hosts/tahani.nix index 4f17b2f..40f6706 100644 --- a/modules/tahani.nix +++ b/modules/hosts/tahani.nix @@ -3,23 +3,12 @@ den.aspects.tahani-cschmatzler = { includes = [ - den.aspects.shell - den.aspects.ssh-client - den.aspects.terminal - den.aspects.atuin - den.aspects.dev-tools - den.aspects.neovim - den.aspects.ai-tools - den.aspects.secrets - den.aspects.zellij - den.aspects.zk + den.aspects.user-workstation + den.aspects.user-personal den.aspects.email ]; homeManager = { - programs.home-manager.enable = true; - programs.git.settings.user.email = "christoph@schmatzler.com"; - programs.nushell.extraConfig = '' if $nu.is-interactive and ('SSH_CONNECTION' in ($env | columns)) and ('ZELLIJ' not-in ($env | columns)) { try { @@ -35,36 +24,31 @@ den.aspects.tahani.includes = [ (den.lib.perHost { - includes = [ - den.aspects.nixos-system - den.aspects.core - den.aspects.openssh - den.aspects.tailscale - ]; + includes = [den.aspects.host-nixos-base]; nixos = {...}: { imports = [ - ./_hosts/tahani/adguardhome.nix - ./_hosts/tahani/cache.nix - ./_hosts/tahani/networking.nix - ./_hosts/tahani/paperless.nix + ./_parts/tahani/adguardhome.nix + ./_parts/tahani/cache.nix + ./_parts/tahani/networking.nix + ./_parts/tahani/paperless.nix ]; networking.hostName = "tahani"; sops.secrets = { tahani-paperless-password = { - sopsFile = ../secrets/tahani-paperless-password; + sopsFile = ../../secrets/tahani-paperless-password; format = "binary"; path = "/run/secrets/tahani-paperless-password"; }; tahani-paperless-gpt-env = { - sopsFile = ../secrets/tahani-paperless-gpt-env; + sopsFile = ../../secrets/tahani-paperless-gpt-env; format = "binary"; path = "/run/secrets/tahani-paperless-gpt-env"; }; tahani-email-password = { - sopsFile = ../secrets/tahani-email-password; + sopsFile = ../../secrets/tahani-email-password; format = "binary"; owner = "cschmatzler"; path = "/run/secrets/tahani-email-password"; diff --git a/modules/hosts.nix b/modules/inventory.nix similarity index 100% rename from modules/hosts.nix rename to modules/inventory.nix diff --git a/modules/jason.nix b/modules/jason.nix deleted file mode 100644 index fe00bb4..0000000 --- a/modules/jason.nix +++ /dev/null @@ -1,40 +0,0 @@ -{den, ...}: { - den.hosts.aarch64-darwin.jason.users.cschmatzler.aspect = "jason-cschmatzler"; - - den.aspects.jason-cschmatzler = { - includes = [ - den.aspects.shell - den.aspects.ssh-client - den.aspects.terminal - den.aspects.atuin - den.aspects.dev-tools - den.aspects.neovim - den.aspects.ai-tools - den.aspects.secrets - den.aspects.zellij - den.aspects.zk - den.aspects.desktop - ]; - - homeManager = {...}: { - programs.home-manager.enable = true; - fonts.fontconfig.enable = true; - programs.git.settings.user.email = "christoph@schmatzler.com"; - }; - }; - - den.aspects.jason.includes = [ - (den.lib.perHost { - includes = [ - den.aspects.darwin-system - den.aspects.core - den.aspects.tailscale - ]; - - darwin = {...}: { - networking.hostName = "jason"; - networking.computerName = "jason"; - }; - }) - ]; -} diff --git a/modules/profiles/host/darwin-base.nix b/modules/profiles/host/darwin-base.nix new file mode 100644 index 0000000..163e976 --- /dev/null +++ b/modules/profiles/host/darwin-base.nix @@ -0,0 +1,7 @@ +{den, ...}: { + den.aspects.host-darwin-base.includes = [ + den.aspects.darwin-system + den.aspects.core + den.aspects.tailscale + ]; +} diff --git a/modules/profiles/host/nixos-base.nix b/modules/profiles/host/nixos-base.nix new file mode 100644 index 0000000..6204bc9 --- /dev/null +++ b/modules/profiles/host/nixos-base.nix @@ -0,0 +1,8 @@ +{den, ...}: { + den.aspects.host-nixos-base.includes = [ + den.aspects.nixos-system + den.aspects.core + den.aspects.openssh + den.aspects.tailscale + ]; +} diff --git a/modules/profiles/host/public-server.nix b/modules/profiles/host/public-server.nix new file mode 100644 index 0000000..0e7bcc5 --- /dev/null +++ b/modules/profiles/host/public-server.nix @@ -0,0 +1,6 @@ +{den, ...}: { + den.aspects.host-public-server.includes = [ + den.aspects.host-nixos-base + den.aspects.fail2ban + ]; +} diff --git a/modules/profiles/user/base.nix b/modules/profiles/user/base.nix new file mode 100644 index 0000000..fc43717 --- /dev/null +++ b/modules/profiles/user/base.nix @@ -0,0 +1,17 @@ +{den, ...}: { + den.aspects.user-base = { + includes = [ + den.aspects.shell + den.aspects.ssh-client + den.aspects.terminal + den.aspects.atuin + den.aspects.secrets + den.aspects.zellij + den.aspects.zk + ]; + + homeManager = { + programs.home-manager.enable = true; + }; + }; +} diff --git a/modules/profiles/user/darwin-laptop.nix b/modules/profiles/user/darwin-laptop.nix new file mode 100644 index 0000000..67e05a7 --- /dev/null +++ b/modules/profiles/user/darwin-laptop.nix @@ -0,0 +1,12 @@ +{den, ...}: { + den.aspects.user-darwin-laptop = { + includes = [ + den.aspects.user-workstation + den.aspects.desktop + ]; + + homeManager = { + fonts.fontconfig.enable = true; + }; + }; +} diff --git a/modules/profiles/user/minimal.nix b/modules/profiles/user/minimal.nix new file mode 100644 index 0000000..7d94833 --- /dev/null +++ b/modules/profiles/user/minimal.nix @@ -0,0 +1,11 @@ +{den, ...}: { + den.aspects.user-minimal = { + includes = [ + den.aspects.shell + ]; + + homeManager = { + programs.home-manager.enable = true; + }; + }; +} diff --git a/modules/profiles/user/personal.nix b/modules/profiles/user/personal.nix new file mode 100644 index 0000000..116976c --- /dev/null +++ b/modules/profiles/user/personal.nix @@ -0,0 +1,5 @@ +{...}: { + den.aspects.user-personal.homeManager = { + programs.git.settings.user.email = "christoph@schmatzler.com"; + }; +} diff --git a/modules/profiles/user/workstation.nix b/modules/profiles/user/workstation.nix new file mode 100644 index 0000000..8491e7c --- /dev/null +++ b/modules/profiles/user/workstation.nix @@ -0,0 +1,8 @@ +{den, ...}: { + den.aspects.user-workstation.includes = [ + den.aspects.user-base + den.aspects.dev-tools + den.aspects.neovim + den.aspects.ai-tools + ]; +}