From 128deca2e3c918a5eead69e0ee15dbe312117d87 Mon Sep 17 00:00:00 2001 From: lyrathorpe Date: Mon, 29 Jun 2026 13:06:23 +0100 Subject: [PATCH] refactor(flake): user registry, multi-user hosts, and portable home outputs (#49) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Separates user identity (data) from the reusable Nix modules and lets a host declare any number of users, replacing the previous one-user-per-host structure. Also restructures the tree and exposes the home config for use off these hosts. ## Changes - **User registry** (`users/registry.nix`): per-user identity (name, email, groups, authorized + signing keys) as the single source of truth; no user data hardcoded in modules. - **Multi-user `mkHost`**: a host declares a `users` set keyed by username; per-user identity is injected into each home config via the `identity` module arg. - **Restructured layout**: `users/`, `home/`, `modules/`, `hosts/`, `lib/` replace the former `lyrathorpe/` and `system/` trees. - **Portable outputs**: standalone `homeConfigurations."@"` (the portable subset — shell, git, editor, claude) plus an exported `homeModules` for use on machines not managed by this flake, or as an input to other flakes. - Docs (`README.md`, `home/README.md`) and `.gitignore` updated for the new paths. ## Fixes - Closes #46 — shared user module authorized one user's SSH key for every account. - Closes #47 — git committer identity hardcoded as defaults instead of per-user. - Closes #48 — EDaaS systemd linger hardcoded to a literal username. ## Verification - `nix flake check` passes: treefmt, deadnix, statix, pre-commit, and evaluation of all NixOS hosts + Darwin + homeConfigurations. - Derivation-path comparison vs `main`: `lyrathorpe-mbp` and `emmathorpe-edaas` are byte-identical; `lyrathorpe-t400`, `lyrathorpe-macpro31` and `lyrathorpe-rpi5` differ only by de-duplicating a repeated `authorized_keys` entry (confirmed with nix-diff — no other change). - Standalone `homeConfigurations."lyrathorpe@x86_64-linux".activationPackage` builds. ## Notes - `emmathorpe` has no personal authorized key yet (it previously inherited Lyra's key via the bug in #46); the registry entry is intentionally empty — add a real key if SSH login as `emmathorpe` is wanted (moot on the WSL host). - A two-repo (public dotfiles / private systems) split is deferred by design; this internal restructure is the prerequisite for it. --------- Co-authored-by: Emma Thorpe Reviewed-on: https://code.emmathe.dev/lyrathorpe/nixfiles/pulls/49 --- .gitignore | 2 +- README.md | 69 ++++-- flake.nix | 208 +++++++++++------- {lyrathorpe/home => home}/KEYBINDINGS.md | 0 {lyrathorpe/home => home}/README.md | 30 +-- {lyrathorpe/home => home}/claude.nix | 0 {lyrathorpe/home => home}/claude/CLAUDE.md | 0 .../home => home}/claude/memory/MEMORY.md | 0 .../claude/memory/dev_clusters_disposable.md | 0 .../claude/memory/docs_keep_updated.md | 0 .../claude/memory/feedback_sandbox_prompts.md | 0 .../claude/memory/git_check_state.md | 0 .../claude/memory/git_commit_signing.md | 0 .../claude/memory/git_conventions.md | 0 .../claude/memory/git_network_ops.md | 0 .../claude/memory/jira_tooling.md | 0 .../claude/memory/persona_soviet_engineer.md | 0 .../home => home}/claude/memory/user_name.md | 0 .../memory/workflow_review_and_comments.md | 0 .../claude/output-styles/soviet-engineer.md | 0 {lyrathorpe/home => home}/default.nix | 0 {lyrathorpe/home => home}/desktop.nix | 9 +- {lyrathorpe/home => home}/editor.nix | 0 {lyrathorpe/home => home}/git.nix | 25 +-- {lyrathorpe/home => home}/shell.nix | 5 +- {lyrathorpe/home => home}/sway.nix | 11 +- .../Darwin/configuration.nix | 2 +- .../machine => hosts}/EDaaS/configuration.nix | 11 +- .../MBP-Asahi/configuration.nix | 0 .../MBP-Asahi/hardware-configuration.nix | 0 {system/machine => hosts}/MacPro31/README.md | 0 .../MacPro31/configuration.nix | 2 +- .../MacPro31/hardware-configuration.nix | 0 {system/machine => hosts}/RPi5/README.md | 0 .../machine => hosts}/RPi5/configuration.nix | 2 +- {system/machine => hosts}/RPi5/docker.nix | 0 .../RPi5/hardware-configuration.nix | 0 .../machine => hosts}/RPi5/reverse-proxy.nix | 0 {system/machine => hosts}/T400/README.md | 0 {system/machine => hosts}/T400/boot-bios.nix | 0 .../T400/boot-coreboot-grub.nix | 0 .../T400/boot-coreboot-uefi.nix | 0 .../machine => hosts}/T400/configuration.nix | 0 .../T400/hardware-configuration.nix | 0 {lyrathorpe => lib}/catppuccin-mocha.nix | 2 +- lyrathorpe/user.nix | 31 --- {system/modules => modules}/common-nixos.nix | 0 {system/modules => modules}/desktop.nix | 2 +- {system/modules => modules}/features.nix | 4 +- .../firmware/all_firmware.tar.gz | Bin .../firmware/kernelcache.release.mac14j | Bin {system/modules => modules}/laptop.nix | 2 +- modules/ssh.nix | 11 + lyrathorpe/swaywm.nix => modules/sway.nix | 4 +- modules/users.nix | 38 ++++ {system/modules => modules}/workstation.nix | 0 system/modules/ssh.nix | 19 -- .../emmathorpe}/renovate-review.nix | 0 .../home => users/emmathorpe}/work.nix | 15 +- users/lyrathorpe/home.nix | 17 ++ users/registry.nix | 28 +++ 61 files changed, 329 insertions(+), 220 deletions(-) rename {lyrathorpe/home => home}/KEYBINDINGS.md (100%) rename {lyrathorpe/home => home}/README.md (92%) rename {lyrathorpe/home => home}/claude.nix (100%) rename {lyrathorpe/home => home}/claude/CLAUDE.md (100%) rename {lyrathorpe/home => home}/claude/memory/MEMORY.md (100%) rename {lyrathorpe/home => home}/claude/memory/dev_clusters_disposable.md (100%) rename {lyrathorpe/home => home}/claude/memory/docs_keep_updated.md (100%) rename {lyrathorpe/home => home}/claude/memory/feedback_sandbox_prompts.md (100%) rename {lyrathorpe/home => home}/claude/memory/git_check_state.md (100%) rename {lyrathorpe/home => home}/claude/memory/git_commit_signing.md (100%) rename {lyrathorpe/home => home}/claude/memory/git_conventions.md (100%) rename {lyrathorpe/home => home}/claude/memory/git_network_ops.md (100%) rename {lyrathorpe/home => home}/claude/memory/jira_tooling.md (100%) rename {lyrathorpe/home => home}/claude/memory/persona_soviet_engineer.md (100%) rename {lyrathorpe/home => home}/claude/memory/user_name.md (100%) rename {lyrathorpe/home => home}/claude/memory/workflow_review_and_comments.md (100%) rename {lyrathorpe/home => home}/claude/output-styles/soviet-engineer.md (100%) rename {lyrathorpe/home => home}/default.nix (100%) rename {lyrathorpe/home => home}/desktop.nix (94%) rename {lyrathorpe/home => home}/editor.nix (100%) rename {lyrathorpe/home => home}/git.nix (76%) rename {lyrathorpe/home => home}/shell.nix (99%) rename {lyrathorpe/home => home}/sway.nix (98%) rename {system/machine => hosts}/Darwin/configuration.nix (98%) rename {system/machine => hosts}/EDaaS/configuration.nix (88%) rename {system/machine => hosts}/MBP-Asahi/configuration.nix (100%) rename {system/machine => hosts}/MBP-Asahi/hardware-configuration.nix (100%) rename {system/machine => hosts}/MacPro31/README.md (100%) rename {system/machine => hosts}/MacPro31/configuration.nix (96%) rename {system/machine => hosts}/MacPro31/hardware-configuration.nix (100%) rename {system/machine => hosts}/RPi5/README.md (100%) rename {system/machine => hosts}/RPi5/configuration.nix (98%) rename {system/machine => hosts}/RPi5/docker.nix (100%) rename {system/machine => hosts}/RPi5/hardware-configuration.nix (100%) rename {system/machine => hosts}/RPi5/reverse-proxy.nix (100%) rename {system/machine => hosts}/T400/README.md (100%) rename {system/machine => hosts}/T400/boot-bios.nix (100%) rename {system/machine => hosts}/T400/boot-coreboot-grub.nix (100%) rename {system/machine => hosts}/T400/boot-coreboot-uefi.nix (100%) rename {system/machine => hosts}/T400/configuration.nix (100%) rename {system/machine => hosts}/T400/hardware-configuration.nix (100%) rename {lyrathorpe => lib}/catppuccin-mocha.nix (87%) delete mode 100644 lyrathorpe/user.nix rename {system/modules => modules}/common-nixos.nix (100%) rename {system/modules => modules}/desktop.nix (91%) rename {system/modules => modules}/features.nix (75%) rename {system/modules => modules}/firmware/all_firmware.tar.gz (100%) rename {system/modules => modules}/firmware/kernelcache.release.mac14j (100%) rename {system/modules => modules}/laptop.nix (94%) create mode 100644 modules/ssh.nix rename lyrathorpe/swaywm.nix => modules/sway.nix (97%) create mode 100644 modules/users.nix rename {system/modules => modules}/workstation.nix (100%) delete mode 100644 system/modules/ssh.nix rename {lyrathorpe/home => users/emmathorpe}/renovate-review.nix (100%) rename {lyrathorpe/home => users/emmathorpe}/work.nix (77%) create mode 100644 users/lyrathorpe/home.nix create mode 100644 users/registry.nix diff --git a/.gitignore b/.gitignore index 73c4e0f..596783b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -system/modules/firmware/* +modules/firmware/* # vim swap files *.swp diff --git a/README.md b/README.md index 61e43ac..bb1a1bb 100644 --- a/README.md +++ b/README.md @@ -7,22 +7,51 @@ single flake. Defined in the host table in [`flake.nix`](./flake.nix): -| Configuration | System | Machine | -| --------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------- | -| `lyrathorpe-mbp` | `aarch64-linux` | MacBook Pro (Apple Silicon, Asahi) | -| `lyrathorpe-t400` | `x86_64-linux` | ThinkPad T400 — [install notes](./system/machine/T400/README.md) | -| `lyrathorpe-macpro31` | `x86_64-linux` | Mac Pro 3,1, desktop — [install notes](./system/machine/MacPro31/README.md) | -| `emmathorpe-edaas` | `x86_64-linux` | Work WSL box (NixOS-WSL) | -| `lyrathorpe-rpi5` | `aarch64-linux` | Raspberry Pi 5 headless server: Docker host + nginx reverse proxy — [install notes](./system/machine/RPi5/README.md) | -| `lyrathorpe-mac` | `aarch64-darwin` | macOS (nix-darwin) | +| Configuration | System | Machine | +| --------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------- | +| `lyrathorpe-mbp` | `aarch64-linux` | MacBook Pro (Apple Silicon, Asahi) | +| `lyrathorpe-t400` | `x86_64-linux` | ThinkPad T400 — [install notes](./hosts/T400/README.md) | +| `lyrathorpe-macpro31` | `x86_64-linux` | Mac Pro 3,1, desktop — [install notes](./hosts/MacPro31/README.md) | +| `emmathorpe-edaas` | `x86_64-linux` | Work WSL box (NixOS-WSL) | +| `lyrathorpe-rpi5` | `aarch64-linux` | Raspberry Pi 5 headless server: Docker host + nginx reverse proxy — [install notes](./hosts/RPi5/README.md) | +| `lyrathorpe-mac` | `aarch64-darwin` | macOS (nix-darwin) | -Shared layers: `lyrathorpe/home` (home-manager: shell, git, editor), -`system/modules/common-nixos.nix` (all NixOS hosts: fonts, nix-ld, caches), -`system/modules/workstation.nix` (physical graphical hosts: audio, thermald, -earlyoom, fwupd), `system/modules/laptop.nix` (laptops: Wi-Fi, Bluetooth, power, -lid), and `system/modules/ssh.nix` (key-only sshd). The x86 hosts also pull +Shared layers: `home` (home-manager: shell, git, editor), +`modules/common-nixos.nix` (all NixOS hosts: fonts, nix-ld, caches), +`modules/workstation.nix` (physical graphical hosts: audio, thermald, +earlyoom, fwupd), `modules/laptop.nix` (laptops: Wi-Fi, Bluetooth, power, +lid), and `modules/ssh.nix` (key-only sshd). The x86 hosts also pull `nixos-hardware` profiles. +## Users + +Identity is data, kept separate from the reusable modules: + +- [`users/registry.nix`](./users/registry.nix) — one entry per user (display + name, email, supplementary groups, authorized + signing keys). This is the + single source of identity; no user data is hardcoded in the modules. +- Each host's table entry declares a `users` set keyed by username; every entry + lists that user's home-module composition (the shared `./home` bundle plus any + per-user modules, e.g. [`users/emmathorpe/work.nix`](./users/emmathorpe/work.nix)) + and optional per-host-user system bits such as `linger`. +- `mkHost` builds each account from the registry and injects the matching + identity into that user's home config as the `identity` module arg. A host can + therefore declare any number of users. + +### Portable home (off-NixOS / external consumers) + +The home config is also exposed for use beyond these hosts: + +- `homeConfigurations."@"` — a standalone home-manager profile + (the portable subset: shell + git + editor + claude) that can be activated on a + machine this flake does **not** manage: + `home-manager switch --flake .#"lyrathorpe@x86_64-linux"`. The desktop/sway + modules are intentionally excluded (they rely on a NixOS-provided Sway/Firefox + binary). +- `homeModules` — the reusable modules exported so another flake can import them + (`inputs..homeModules.default`). Consumers must supply the module args + these expect: `inputs` always, `identity` for git/desktop, `portable` for sway. + ## Applying ```sh @@ -35,25 +64,25 @@ darwin-rebuild switch --flake .#lyrathorpe-mac ## Shell environment & keybindings - Interactive shell features (zsh, tmux, git, ssh, CLI tools, auto-tmux): - [`lyrathorpe/home/README.md`](./lyrathorpe/home/README.md). + [`home/README.md`](./home/README.md). - All Sway / tmux / foot / zsh keyboard shortcuts: - [`lyrathorpe/home/KEYBINDINGS.md`](./lyrathorpe/home/KEYBINDINGS.md). + [`home/KEYBINDINGS.md`](./home/KEYBINDINGS.md). ## Login / greeter Graphical (Sway) hosts log in through a Wayland greeter — `greetd` running ReGreet inside the `cage` kiosk compositor — implemented in -[`lyrathorpe/swaywm.nix`](./lyrathorpe/swaywm.nix), gated on +[`modules/sway.nix`](./modules/sway.nix), gated on `features.swayDesktop.enable` (the option is declared in -[`system/modules/features.nix`](./system/modules/features.nix), so headless hosts -can leave it off without importing `swaywm.nix`). The greeter is forced to Dvorak +[`modules/features.nix`](./modules/features.nix), so headless hosts +can leave it off without importing `modules/sway.nix`). The greeter is forced to Dvorak to match the console and Sway session. Headless hosts (the WSL work box and the Raspberry Pi server) keep plain TTY login. The target account needs a password (`passwd `) before it can log in. ## MacBook (Asahi) firmware -The MBP host references `system/modules/firmware/` for Apple peripheral +The MBP host references `modules/firmware/` for Apple peripheral firmware (Wi-Fi/Bluetooth). These blobs are **committed** (tracked) even though `.gitignore` lists the directory: the flake is `git+file`, so it only sees tracked files — untracking them breaks `lyrathorpe-mbp` evaluation (and the CI @@ -63,7 +92,7 @@ redistributable; the repo is private. To refresh them, copy the firmware extracted during the Asahi install (from `/etc/nixos/firmware`, or re-extract per the [Asahi NixOS docs](https://github.com/tpwrules/nixos-apple-silicon)) into -`system/modules/firmware/` and commit with `git add -f`. +`modules/firmware/` and commit with `git add -f`. ## Development diff --git a/flake.nix b/flake.nix index 3f8f634..2f6a4dd 100644 --- a/flake.nix +++ b/flake.nix @@ -23,7 +23,7 @@ # Provides mkFlake: the systems/perSystem scaffolding used below. flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; - # Declarative Firefox add-ons (e.g. the Catppuccin theme); see lyrathorpe/user.nix. + # Declarative Firefox add-ons (e.g. the Catppuccin theme); see modules/users.nix. firefox-addons = { url = "gitlab:rycee/nur-expressions?dir=pkgs/firefox-addons"; inputs.nixpkgs.follows = "nixpkgs"; @@ -46,7 +46,7 @@ url = "github:cachix/git-hooks.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; - # Declarative Neovim (the editor; see lyrathorpe/home/editor.nix). Release + # Declarative Neovim (the editor; see home/editor.nix). Release # branch matched to the pinned nixpkgs (26.05); follows our nixpkgs to keep a # single nixpkgs in the closure. editor.nix sets programs.nixvim.nixpkgs.source # to this same input so the home module doesn't warn about the pin. @@ -97,6 +97,9 @@ "lens-desktop" ]; + # Per-user identity, keyed by username. See README "Users". + userRegistry = import ./users/registry.nix; + # nixpkgs + nix-daemon settings shared by NixOS and Darwin hosts. commonModule = { nixpkgs.overlays = overlays; @@ -112,9 +115,9 @@ # Shared scaffolding for every NixOS host: common user, settings, home-manager. baseModules = [ - ./lyrathorpe/user.nix - ./system/modules/common-nixos.nix - ./system/modules/features.nix + ./modules/users.nix + ./modules/common-nixos.nix + ./modules/features.nix commonModule home-manager.nixosModules.home-manager { @@ -126,18 +129,13 @@ } ]; - # mkHost :: { system, username, fullName, modules, homeModules } -> nixosSystem - # Builds one machine by appending its host-specific modules to the shared - # baseModules. The user identity (username/fullName) is threaded through - # specialArgs so user.nix and the home modules stay host-agnostic, and the - # home-manager profile is keyed by the host's username. + # Build one NixOS host. `users` is an attrset keyed by username (home + # modules + optional per-user system bits). See README "Users". mkHost = { system, - username, - fullName, modules, - homeModules, + users, # Host form factor. Laptops inherit the default; a desktop host sets # `portable = false` to drop mobile components (battery block, # brightness keys) from the home-manager Sway config. @@ -148,8 +146,7 @@ specialArgs = { inherit inputs - username - fullName + userRegistry portable ; }; @@ -157,16 +154,15 @@ baseModules ++ modules ++ [ + { _module.args.hostUsers = users; } { - home-manager.extraSpecialArgs = { - inherit - inputs - username - fullName - portable - ; - }; - home-manager.users.${username}.imports = homeModules; + home-manager.extraSpecialArgs = { inherit inputs portable; }; + home-manager.users = lib.mapAttrs (name: spec: { + imports = spec.homeModules; + _module.args.identity = userRegistry.${name} // { + username = name; + }; + }) users; } ]; }; @@ -185,19 +181,17 @@ } ]; - # mkDarwinHost :: { system, username, fullName, modules, homeModules } -> darwinSystem - # Darwin counterpart of mkHost. macOS already owns the login user, so we - # only attach the platform and home-manager; no NixOS user module here. + # Darwin counterpart of mkHost: single-user (macOS owns the account), + # identity still from the registry. See README "Users". mkDarwinHost = { system, username, - fullName, modules, homeModules, }: nix-darwin.lib.darwinSystem { - specialArgs = { inherit inputs username fullName; }; + specialArgs = { inherit inputs username; }; modules = darwinBaseModules ++ modules @@ -206,40 +200,41 @@ nixpkgs.hostPlatform = system; # macOS owns the account; point home-manager at its home dir. users.users.${username}.home = "/Users/${username}"; - home-manager.extraSpecialArgs = { inherit inputs username fullName; }; - home-manager.users.${username}.imports = homeModules; + home-manager.extraSpecialArgs = { inherit inputs; }; + home-manager.users.${username} = { + imports = homeModules; + _module.args.identity = userRegistry.${username} // { + inherit username; + }; + }; } ]; }; - # Host table — declarative registry of every machine. To add a host: - # give it a name, its `system`, the owning user, and the module lists. - # mapAttrs below turns each entry into a nixosConfiguration of the same name. + # Host table — one entry per machine, realised into a nixosConfiguration + # of the same name below. See README "Hosts" / "Users". hosts = { lyrathorpe-mbp = { system = "aarch64-linux"; - username = "lyrathorpe"; - fullName = "Lyra Thorpe"; modules = [ - ./system/machine/MBP-Asahi/configuration.nix - ./system/modules/laptop.nix + ./hosts/MBP-Asahi/configuration.nix + ./modules/laptop.nix nixos-apple-silicon.nixosModules.default - ./lyrathorpe/swaywm.nix + ./modules/sway.nix ]; - homeModules = [ - ./lyrathorpe/home - ./lyrathorpe/home/desktop.nix + users.lyrathorpe.homeModules = [ + ./home + ./users/lyrathorpe/home.nix + ./home/desktop.nix ]; }; lyrathorpe-t400 = { system = "x86_64-linux"; - username = "lyrathorpe"; - fullName = "Lyra Thorpe"; modules = [ - ./system/machine/T400/configuration.nix - ./system/modules/laptop.nix - ./system/modules/ssh.nix + ./hosts/T400/configuration.nix + ./modules/laptop.nix + ./modules/ssh.nix # No t400-specific profile exists; compose the generic ThinkPad + # laptop/SSD/Intel building blocks (tp_smapi/acpi_call for battery # thresholds, SSD + microcode defaults). @@ -247,78 +242,82 @@ inputs.nixos-hardware.nixosModules.common-pc-laptop inputs.nixos-hardware.nixosModules.common-pc-laptop-ssd inputs.nixos-hardware.nixosModules.common-cpu-intel - ./lyrathorpe/swaywm.nix + ./modules/sway.nix ]; - homeModules = [ - ./lyrathorpe/home - ./lyrathorpe/home/desktop.nix + users.lyrathorpe.homeModules = [ + ./home + ./users/lyrathorpe/home.nix + ./home/desktop.nix ]; }; lyrathorpe-macpro31 = { system = "x86_64-linux"; - username = "lyrathorpe"; - fullName = "Lyra Thorpe"; portable = false; modules = [ - ./system/machine/MacPro31/configuration.nix - ./system/modules/desktop.nix - ./system/modules/ssh.nix + ./hosts/MacPro31/configuration.nix + ./modules/desktop.nix + ./modules/ssh.nix inputs.nixos-hardware.nixosModules.common-pc-ssd inputs.nixos-hardware.nixosModules.common-cpu-intel - ./lyrathorpe/swaywm.nix + ./modules/sway.nix ]; - homeModules = [ - ./lyrathorpe/home - ./lyrathorpe/home/desktop.nix + users.lyrathorpe.homeModules = [ + ./home + ./users/lyrathorpe/home.nix + ./home/desktop.nix ]; }; emmathorpe-edaas = { system = "x86_64-linux"; - username = "emmathorpe"; - fullName = "Emma Thorpe"; modules = [ - ./system/machine/EDaaS/configuration.nix + ./hosts/EDaaS/configuration.nix nixos-wsl.nixosModules.default - ./lyrathorpe/swaywm.nix - ]; - homeModules = [ - ./lyrathorpe/home - ./lyrathorpe/home/work.nix + ./modules/sway.nix ]; + users.emmathorpe = { + homeModules = [ + ./home + ./users/emmathorpe/work.nix + ]; + # Keep the systemd --user instance alive without a login session so + # the renovate-review home timer fires on schedule. + linger = true; + }; }; lyrathorpe-rpi5 = { system = "aarch64-linux"; - username = "lyrathorpe"; - fullName = "Lyra Thorpe"; portable = false; - # Headless server: Docker host + nginx reverse proxy. No swaywm.nix + # Headless server: Docker host + nginx reverse proxy. No sway.nix # (no desktop); the raspberry-pi-5 profile supplies kernel/firmware, # ssh.nix adds key-only sshd. modules = [ - ./system/machine/RPi5/configuration.nix + ./hosts/RPi5/configuration.nix inputs.nixos-hardware.nixosModules.raspberry-pi-5 - ./system/modules/ssh.nix + ./modules/ssh.nix + ]; + users.lyrathorpe.homeModules = [ + ./home + ./users/lyrathorpe/home.nix ]; - homeModules = [ ./lyrathorpe/home ]; }; }; # Darwin host table — macOS machines built via mkDarwinHost. The shared - # ./lyrathorpe/home modules (shell, git, editor) are reused; the Linux-only + # ./home bundle (shell, git, editor) is reused directly; the Linux-only # desktop/sway modules are intentionally left out. darwinHosts = { lyrathorpe-mac = { system = "aarch64-darwin"; username = "lyrathorpe"; - fullName = "Lyra Thorpe"; modules = [ - ./system/machine/Darwin/configuration.nix + ./hosts/Darwin/configuration.nix ]; homeModules = [ - ./lyrathorpe/home + ./home + ./users/lyrathorpe/home.nix ]; }; }; @@ -409,6 +408,59 @@ # Realise the host tables: each entry becomes a {nixos,darwin}Configuration. flake.nixosConfigurations = lib.mapAttrs (_name: mkHost) hosts; flake.darwinConfigurations = lib.mapAttrs (_name: mkDarwinHost) darwinHosts; + + # Reusable home modules, exported for use off these hosts. See README + # "Portable home" for the consumer module-arg expectations. + flake.homeModules = { + default = ./home; + shell = ./home/shell.nix; + git = ./home/git.nix; + editor = ./home/editor.nix; + claude = ./home/claude.nix; + desktop = ./home/desktop.nix; + sway = ./home/sway.nix; + }; + + # Standalone home-manager configs (portable bundle) for machines not + # managed by this flake. See README "Portable home". + flake.homeConfigurations = + let + mkHome = + { + system, + name, + }: + home-manager.lib.homeManagerConfiguration { + pkgs = import nixpkgs { + inherit system overlays; + config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) unfreePackages; + }; + extraSpecialArgs = { + inherit inputs; + portable = true; + identity = userRegistry.${name} // { + username = name; + }; + }; + modules = [ + ./home + { + home.username = name; + home.homeDirectory = "/home/${name}"; + } + ]; + }; + in + { + "lyrathorpe@x86_64-linux" = mkHome { + system = "x86_64-linux"; + name = "lyrathorpe"; + }; + "lyrathorpe@aarch64-linux" = mkHome { + system = "aarch64-linux"; + name = "lyrathorpe"; + }; + }; } ); } diff --git a/lyrathorpe/home/KEYBINDINGS.md b/home/KEYBINDINGS.md similarity index 100% rename from lyrathorpe/home/KEYBINDINGS.md rename to home/KEYBINDINGS.md diff --git a/lyrathorpe/home/README.md b/home/README.md similarity index 92% rename from lyrathorpe/home/README.md rename to home/README.md index b6a9fa9..e100128 100644 --- a/lyrathorpe/home/README.md +++ b/home/README.md @@ -15,8 +15,10 @@ Keyboard shortcuts have their own reference: [`KEYBINDINGS.md`](./KEYBINDINGS.md | GUI apps, GTK/Firefox theming, cursor | [`desktop.nix`](./desktop.nix) (graphical hosts only) | Shared by every host via [`default.nix`](./default.nix); the work box also layers -[`work.nix`](./work.nix) on top (work email, its own ssh config, extra packages, -and the C#/Helm language servers). +[`work.nix`](../users/emmathorpe/work.nix) on top (its own ssh config, extra +packages, and the C#/Helm language servers). The committer identity (name, email, +signing key) comes from the user registry +([`../users/registry.nix`](../users/registry.nix)), not this module. --- @@ -55,7 +57,7 @@ and the C#/Helm language servers). | `hyperfine` / `sd` | command-line benchmarking; saner find-and-replace than sed | **Theming:** `fzf`, `bat`, `btop`, `lazygit` and `git`'s `delta` pager are all -Catppuccin Mocha, driven from the shared `../catppuccin-mocha.nix` palette / the +Catppuccin Mocha, driven from the shared `../lib/catppuccin-mocha.nix` palette / the catppuccin upstream themes. **Env & defaults:** `xdg.enable` on; `PAGER`/`MANPAGER` (bat) set in `default.nix` @@ -147,17 +149,17 @@ current (`gc`/`fetch.writeCommitGraph`) so `lg` stays fast. | `lg` | graph log, all branches | | `cz` `cc` | `git cz ` (e.g. `git cz c`) and `git cc` → commitizen prompt | -| Behaviour | | -| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| Pulls | rebase, with autostash + autosquash | -| Fetch | prune deleted remote branches | -| Conflicts | `zdiff3` (shows the common ancestor) | -| Diffs | histogram algorithm, colour-moved | -| `rerere` | remembers + replays conflict resolutions | -| Commit editor | full diff shown (`commit.verbose`) | -| Misc | branches sorted by date, `column.ui = auto`, `help.autocorrect = prompt`, `push.autoSetupRemote` | -| Global ignores | `result`, `result-*`, `.direnv`, `*.swp`, `.DS_Store` | -| Signing | SSH commit + tag signing (`mkDefault`, so a host without the key in its agent can disable it). Personal email `iam@emmathe.dev`; the work box overrides email + signing. | +| Behaviour | | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Pulls | rebase, with autostash + autosquash | +| Fetch | prune deleted remote branches | +| Conflicts | `zdiff3` (shows the common ancestor) | +| Diffs | histogram algorithm, colour-moved | +| `rerere` | remembers + replays conflict resolutions | +| Commit editor | full diff shown (`commit.verbose`) | +| Misc | branches sorted by date, `column.ui = auto`, `help.autocorrect = prompt`, `push.autoSetupRemote` | +| Global ignores | `result`, `result-*`, `.direnv`, `*.swp`, `.DS_Store` | +| Signing | SSH commit + tag signing (`mkDefault`, so a host without the key in its agent can disable it). Name, email and signing key all come from the per-user `identity` (the user registry, `../users/registry.nix`). | ## ssh diff --git a/lyrathorpe/home/claude.nix b/home/claude.nix similarity index 100% rename from lyrathorpe/home/claude.nix rename to home/claude.nix diff --git a/lyrathorpe/home/claude/CLAUDE.md b/home/claude/CLAUDE.md similarity index 100% rename from lyrathorpe/home/claude/CLAUDE.md rename to home/claude/CLAUDE.md diff --git a/lyrathorpe/home/claude/memory/MEMORY.md b/home/claude/memory/MEMORY.md similarity index 100% rename from lyrathorpe/home/claude/memory/MEMORY.md rename to home/claude/memory/MEMORY.md diff --git a/lyrathorpe/home/claude/memory/dev_clusters_disposable.md b/home/claude/memory/dev_clusters_disposable.md similarity index 100% rename from lyrathorpe/home/claude/memory/dev_clusters_disposable.md rename to home/claude/memory/dev_clusters_disposable.md diff --git a/lyrathorpe/home/claude/memory/docs_keep_updated.md b/home/claude/memory/docs_keep_updated.md similarity index 100% rename from lyrathorpe/home/claude/memory/docs_keep_updated.md rename to home/claude/memory/docs_keep_updated.md diff --git a/lyrathorpe/home/claude/memory/feedback_sandbox_prompts.md b/home/claude/memory/feedback_sandbox_prompts.md similarity index 100% rename from lyrathorpe/home/claude/memory/feedback_sandbox_prompts.md rename to home/claude/memory/feedback_sandbox_prompts.md diff --git a/lyrathorpe/home/claude/memory/git_check_state.md b/home/claude/memory/git_check_state.md similarity index 100% rename from lyrathorpe/home/claude/memory/git_check_state.md rename to home/claude/memory/git_check_state.md diff --git a/lyrathorpe/home/claude/memory/git_commit_signing.md b/home/claude/memory/git_commit_signing.md similarity index 100% rename from lyrathorpe/home/claude/memory/git_commit_signing.md rename to home/claude/memory/git_commit_signing.md diff --git a/lyrathorpe/home/claude/memory/git_conventions.md b/home/claude/memory/git_conventions.md similarity index 100% rename from lyrathorpe/home/claude/memory/git_conventions.md rename to home/claude/memory/git_conventions.md diff --git a/lyrathorpe/home/claude/memory/git_network_ops.md b/home/claude/memory/git_network_ops.md similarity index 100% rename from lyrathorpe/home/claude/memory/git_network_ops.md rename to home/claude/memory/git_network_ops.md diff --git a/lyrathorpe/home/claude/memory/jira_tooling.md b/home/claude/memory/jira_tooling.md similarity index 100% rename from lyrathorpe/home/claude/memory/jira_tooling.md rename to home/claude/memory/jira_tooling.md diff --git a/lyrathorpe/home/claude/memory/persona_soviet_engineer.md b/home/claude/memory/persona_soviet_engineer.md similarity index 100% rename from lyrathorpe/home/claude/memory/persona_soviet_engineer.md rename to home/claude/memory/persona_soviet_engineer.md diff --git a/lyrathorpe/home/claude/memory/user_name.md b/home/claude/memory/user_name.md similarity index 100% rename from lyrathorpe/home/claude/memory/user_name.md rename to home/claude/memory/user_name.md diff --git a/lyrathorpe/home/claude/memory/workflow_review_and_comments.md b/home/claude/memory/workflow_review_and_comments.md similarity index 100% rename from lyrathorpe/home/claude/memory/workflow_review_and_comments.md rename to home/claude/memory/workflow_review_and_comments.md diff --git a/lyrathorpe/home/claude/output-styles/soviet-engineer.md b/home/claude/output-styles/soviet-engineer.md similarity index 100% rename from lyrathorpe/home/claude/output-styles/soviet-engineer.md rename to home/claude/output-styles/soviet-engineer.md diff --git a/lyrathorpe/home/default.nix b/home/default.nix similarity index 100% rename from lyrathorpe/home/default.nix rename to home/default.nix diff --git a/lyrathorpe/home/desktop.nix b/home/desktop.nix similarity index 94% rename from lyrathorpe/home/desktop.nix rename to home/desktop.nix index c278b5f..3780577 100644 --- a/lyrathorpe/home/desktop.nix +++ b/home/desktop.nix @@ -1,12 +1,13 @@ # Graphical desktop layer: GUI apps, Wayland session env, and cursor theme. # Imported only on hosts that run Sway (MBP, T400, Mac Pro); never pulled onto # the headless WSL host. Login (and the Sway session launch) is handled by the -# greetd/ReGreet greeter -- see ../swaywm.nix -- so there is no tty1 autostart. +# greetd/ReGreet greeter -- see ../modules/sway.nix -- so there is no tty1 +# autostart. { pkgs, config, inputs, - username, + identity, ... }: { @@ -89,7 +90,7 @@ }; # Firefox is themed at the browser level (it does not follow the GTK theme). - # The system installs the binary (programs.firefox in ../user.nix); here + # The system installs the binary (programs.firefox in ../modules/users.nix); here # home-manager owns only the profile, hence package = null. Apply the # Catppuccin Mocha theme add-on (only the mauve accent is packaged upstream; # the rest of the desktop uses blue) and make content + UI dark. @@ -101,7 +102,7 @@ # stateVersion<26.05 default-change warning (the new XDG path depends on # Firefox's own profile support). configPath = ".mozilla/firefox"; - profiles.${username} = { + profiles.${identity.username} = { id = 0; isDefault = true; extensions = { diff --git a/lyrathorpe/home/editor.nix b/home/editor.nix similarity index 100% rename from lyrathorpe/home/editor.nix rename to home/editor.nix diff --git a/lyrathorpe/home/git.nix b/home/git.nix similarity index 76% rename from lyrathorpe/home/git.nix rename to home/git.nix index 9300ecf..9bdad1c 100644 --- a/lyrathorpe/home/git.nix +++ b/home/git.nix @@ -1,13 +1,13 @@ -# Version control: git + delta pager + commitizen + lazygit. The work host -# layers commit signing and an email override on top (see work.nix). +# Version control: git + delta + commitizen + lazygit. Committer identity comes +# from the per-user `identity` arg (the registry). See README "Users". { pkgs, lib, - fullName, + identity, ... }: let - ctp = import ../catppuccin-mocha.nix; + ctp = import ../lib/catppuccin-mocha.nix; in { home.packages = [ @@ -18,10 +18,9 @@ in enable = true; package = pkgs.gitFull; settings = { - user.name = fullName; - # Personal identity. mkDefault so the work module overrides it on the work - # host (and to merge cleanly with that plain definition there). - user.email = lib.mkDefault "iam@emmathe.dev"; + user.name = identity.fullName; + # mkDefault so a host-specific module can still override it. + user.email = lib.mkDefault identity.email; push.autoSetupRemote = true; init.defaultBranch = "main"; @@ -77,14 +76,10 @@ in cc = "!cz commit"; }; - # SSH commit signing. This personal key is the default; the work module - # (work.nix) overrides it with the work key on the EDaaS host, the same way - # user.email is overridden -- so mkDefault here lets that plain definition - # win instead of conflicting. gpgsign is mkDefault too, so a host without - # the key in its ssh-agent can override it to false rather than fail every - # commit. + # SSH signing, key from the registry. mkDefault so a host lacking the key + # in its agent can set gpgsign = false instead of failing every commit. gpg.format = "ssh"; - user.signingkey = lib.mkDefault "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA"; + user.signingkey = lib.mkDefault identity.signingKey; commit.gpgsign = lib.mkDefault true; tag.gpgsign = lib.mkDefault true; }; diff --git a/lyrathorpe/home/shell.nix b/home/shell.nix similarity index 99% rename from lyrathorpe/home/shell.nix rename to home/shell.nix index b47f80c..c539dc2 100644 --- a/lyrathorpe/home/shell.nix +++ b/home/shell.nix @@ -8,7 +8,7 @@ }: let # Shared Catppuccin Mocha palette: raw 6-hex strings, no leading "#". - ctp = import ../catppuccin-mocha.nix; + ctp = import ../lib/catppuccin-mocha.nix; in { imports = [ @@ -341,9 +341,6 @@ in IdentityFile = "~/.ssh/code.emmathe.dev"; IdentitiesOnly = true; }; - "dockerpi.inf.cbg.emmaisvery.gay" = { - User = "emmathorpe"; - }; }; }; diff --git a/lyrathorpe/home/sway.nix b/home/sway.nix similarity index 98% rename from lyrathorpe/home/sway.nix rename to home/sway.nix index f250716..6374608 100644 --- a/lyrathorpe/home/sway.nix +++ b/home/sway.nix @@ -2,7 +2,7 @@ # Imported via ./desktop.nix, so only graphical hosts get it. # # The compositor binary, PAM and the polkit *daemon* come from the system-level -# programs.sway (see ../swaywm.nix); package = null below reuses it instead of +# programs.sway (see ../modules/sway.nix); package = null below reuses it instead of # pulling a second Sway. The polkit authentication *agent* (the thing that draws # the GUI auth dialog) is a user service started here. home-manager owns the user # config (~/.config/sway) and wires the systemd user session (sway-session.target), @@ -20,7 +20,7 @@ let # Catppuccin Mocha (shared with the ReGreet greeter). Raw hex; prefix "#" # where a consumer needs it -- Sway/i3status/dunst want "#", foot/swaylock do # not. - ctp = import ../catppuccin-mocha.nix; + ctp = import ../lib/catppuccin-mocha.nix; # Focused-window screenshot -> swappy editor (the dotfiles' grimshot.sh logic). # Full store paths so it needs nothing on PATH. @@ -334,13 +334,12 @@ in ]; }; - # Night light. Manual location (no geoclue dependency); adjust the coordinates - # to taste. Warmer at night, neutral by day. + # Night light. Manual location (no geoclue dependency); warmer at night, + # neutral by day. Coordinates come from the per-user module (e.g. + # users/lyrathorpe/home.nix), not this shared module. services.gammastep = { enable = true; provider = "manual"; - latitude = 51.5; - longitude = -0.13; # London-ish; set to your actual location temperature = { day = 6500; night = 3700; diff --git a/system/machine/Darwin/configuration.nix b/hosts/Darwin/configuration.nix similarity index 98% rename from system/machine/Darwin/configuration.nix rename to hosts/Darwin/configuration.nix index 6cf40c3..630e784 100644 --- a/system/machine/Darwin/configuration.nix +++ b/hosts/Darwin/configuration.nix @@ -1,5 +1,5 @@ # Default nix-darwin host. Minimal macOS baseline; the user environment -# (shell, git, editor) is carried by the shared ./lyrathorpe/home modules, +# (shell, git, editor) is carried by the shared ./home modules, # the same ones used by the Linux hosts. nixpkgs.hostPlatform is set by # mkDarwinHost in flake.nix. { pkgs, username, ... }: diff --git a/system/machine/EDaaS/configuration.nix b/hosts/EDaaS/configuration.nix similarity index 88% rename from system/machine/EDaaS/configuration.nix rename to hosts/EDaaS/configuration.nix index 35adc8f..89da4eb 100644 --- a/system/machine/EDaaS/configuration.nix +++ b/hosts/EDaaS/configuration.nix @@ -62,12 +62,11 @@ features.swayDesktop.enable = false; - # Keep this user's systemd --user instance running without an open login - # session, so the home-manager user timer (renovate-review.nix) fires on - # schedule even when no terminal is attached. On WSL the timer still only runs - # while the distro itself is up; Persistent=true catches up a missed run at - # next start. - users.users.emmathorpe.linger = true; + # NOTE: this user's systemd --user lingering -- so the home-manager renovate + # timer fires without an open login session -- is enabled from the host table + # in flake.nix (users.emmathorpe.linger = true) and applied by + # modules/users.nix. + # programs.nix-ld is enabled for all NixOS hosts in common-nixos.nix. # This value determines the NixOS release from which the default # settings for stateful data, like file locations and database versions diff --git a/system/machine/MBP-Asahi/configuration.nix b/hosts/MBP-Asahi/configuration.nix similarity index 100% rename from system/machine/MBP-Asahi/configuration.nix rename to hosts/MBP-Asahi/configuration.nix diff --git a/system/machine/MBP-Asahi/hardware-configuration.nix b/hosts/MBP-Asahi/hardware-configuration.nix similarity index 100% rename from system/machine/MBP-Asahi/hardware-configuration.nix rename to hosts/MBP-Asahi/hardware-configuration.nix diff --git a/system/machine/MacPro31/README.md b/hosts/MacPro31/README.md similarity index 100% rename from system/machine/MacPro31/README.md rename to hosts/MacPro31/README.md diff --git a/system/machine/MacPro31/configuration.nix b/hosts/MacPro31/configuration.nix similarity index 96% rename from system/machine/MacPro31/configuration.nix rename to hosts/MacPro31/configuration.nix index 66b0834..77b1a16 100644 --- a/system/machine/MacPro31/configuration.nix +++ b/hosts/MacPro31/configuration.nix @@ -42,7 +42,7 @@ # - ATI Radeon HD 2600 XT -> "radeon" (older) or "amdgpu" KMS # - NVIDIA GeForce 8800 GT -> "nouveau" KMS # These come up automatically via the in-tree drivers + KMS, and the graphics - # stack itself is enabled by swaywm.nix. If a card needs to be forced, add it + # stack itself is enabled by modules/sway.nix. If a card needs to be forced, add it # here, e.g. `services.xserver.videoDrivers = [ "radeon" ];` (or "nouveau"), # and/or `boot.initrd.kernelModules = [ "radeon" ];` in # hardware-configuration.nix for early KMS. diff --git a/system/machine/MacPro31/hardware-configuration.nix b/hosts/MacPro31/hardware-configuration.nix similarity index 100% rename from system/machine/MacPro31/hardware-configuration.nix rename to hosts/MacPro31/hardware-configuration.nix diff --git a/system/machine/RPi5/README.md b/hosts/RPi5/README.md similarity index 100% rename from system/machine/RPi5/README.md rename to hosts/RPi5/README.md diff --git a/system/machine/RPi5/configuration.nix b/hosts/RPi5/configuration.nix similarity index 98% rename from system/machine/RPi5/configuration.nix rename to hosts/RPi5/configuration.nix index 0ab4c72..632c6da 100644 --- a/system/machine/RPi5/configuration.nix +++ b/hosts/RPi5/configuration.nix @@ -15,7 +15,7 @@ # (which selects by the local hostname) resolves without an explicit -H flag. networking.hostName = "lyrathorpe-rpi5"; - # Headless server: the Sway desktop is intentionally not set up. swaywm.nix is + # Headless server: the Sway desktop is intentionally not set up. modules/sway.nix is # not imported and features.swayDesktop.enable defaults to false (declared in # system/modules/features.nix), so this host keeps plain TTY/SSH login. diff --git a/system/machine/RPi5/docker.nix b/hosts/RPi5/docker.nix similarity index 100% rename from system/machine/RPi5/docker.nix rename to hosts/RPi5/docker.nix diff --git a/system/machine/RPi5/hardware-configuration.nix b/hosts/RPi5/hardware-configuration.nix similarity index 100% rename from system/machine/RPi5/hardware-configuration.nix rename to hosts/RPi5/hardware-configuration.nix diff --git a/system/machine/RPi5/reverse-proxy.nix b/hosts/RPi5/reverse-proxy.nix similarity index 100% rename from system/machine/RPi5/reverse-proxy.nix rename to hosts/RPi5/reverse-proxy.nix diff --git a/system/machine/T400/README.md b/hosts/T400/README.md similarity index 100% rename from system/machine/T400/README.md rename to hosts/T400/README.md diff --git a/system/machine/T400/boot-bios.nix b/hosts/T400/boot-bios.nix similarity index 100% rename from system/machine/T400/boot-bios.nix rename to hosts/T400/boot-bios.nix diff --git a/system/machine/T400/boot-coreboot-grub.nix b/hosts/T400/boot-coreboot-grub.nix similarity index 100% rename from system/machine/T400/boot-coreboot-grub.nix rename to hosts/T400/boot-coreboot-grub.nix diff --git a/system/machine/T400/boot-coreboot-uefi.nix b/hosts/T400/boot-coreboot-uefi.nix similarity index 100% rename from system/machine/T400/boot-coreboot-uefi.nix rename to hosts/T400/boot-coreboot-uefi.nix diff --git a/system/machine/T400/configuration.nix b/hosts/T400/configuration.nix similarity index 100% rename from system/machine/T400/configuration.nix rename to hosts/T400/configuration.nix diff --git a/system/machine/T400/hardware-configuration.nix b/hosts/T400/hardware-configuration.nix similarity index 100% rename from system/machine/T400/hardware-configuration.nix rename to hosts/T400/hardware-configuration.nix diff --git a/lyrathorpe/catppuccin-mocha.nix b/lib/catppuccin-mocha.nix similarity index 87% rename from lyrathorpe/catppuccin-mocha.nix rename to lib/catppuccin-mocha.nix index d621b95..0b51f7c 100644 --- a/lyrathorpe/catppuccin-mocha.nix +++ b/lib/catppuccin-mocha.nix @@ -1,6 +1,6 @@ # Catppuccin Mocha palette. Raw 6-digit hex (no leading "#"); consumers add a # "#" where their format needs it. Shared by the Sway desktop theming -# (home/sway.nix) and the ReGreet greeter (swaywm.nix) so the two stay in sync. +# (home/sway.nix) and the ReGreet greeter (modules/sway.nix) so the two stay in sync. { base = "1e1e2e"; mantle = "181825"; diff --git a/lyrathorpe/user.nix b/lyrathorpe/user.nix deleted file mode 100644 index 4482115..0000000 --- a/lyrathorpe/user.nix +++ /dev/null @@ -1,31 +0,0 @@ -{ - config, - pkgs, - lib, - username, - fullName, - ... -}: - -{ - programs.zsh.enable = true; - users.users.${username} = { - isNormalUser = true; - home = "/home/${username}"; - description = fullName; - extraGroups = [ - "wheel" - "docker" - ]; - openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA" - ]; - shell = pkgs.zsh; - }; - programs.firefox = lib.mkIf (config.features.swayDesktop.enable == true) { - enable = true; - }; - programs.thunderbird = lib.mkIf (config.features.swayDesktop.enable == true) { - enable = true; - }; -} diff --git a/system/modules/common-nixos.nix b/modules/common-nixos.nix similarity index 100% rename from system/modules/common-nixos.nix rename to modules/common-nixos.nix diff --git a/system/modules/desktop.nix b/modules/desktop.nix similarity index 91% rename from system/modules/desktop.nix rename to modules/desktop.nix index f103ca7..072da84 100644 --- a/system/modules/desktop.nix +++ b/modules/desktop.nix @@ -2,7 +2,7 @@ # shared ./workstation.nix base and swaps the mobile Wi-Fi backend for wired # NetworkManager. A desktop host also sets `portable = false` in its host-table # entry (flake.nix), which drops the battery block and brightness keybindings -# from the Sway bar -- see lyrathorpe/home/sway.nix. +# from the Sway bar -- see home/sway.nix. { ... }: { imports = [ ./workstation.nix ]; diff --git a/system/modules/features.nix b/modules/features.nix similarity index 75% rename from system/modules/features.nix rename to modules/features.nix index 486c4b8..0d0de92 100644 --- a/system/modules/features.nix +++ b/modules/features.nix @@ -2,9 +2,9 @@ # baseModules in flake.nix). Declaring the flags here -- rather than inside the # module that implements them -- means a host can read or set a flag without # importing the (often large) implementation module. In particular, -# features.swayDesktop.enable is read by lyrathorpe/user.nix on every host, but a +# features.swayDesktop.enable is read by modules/users.nix on every host, but a # headless host (e.g. the Pi) must be able to leave it at its default without -# pulling in lyrathorpe/swaywm.nix. The implementation lives in swaywm.nix, +# pulling in modules/sway.nix. The implementation lives in modules/sway.nix, # gated on this flag. { lib, ... }: { diff --git a/system/modules/firmware/all_firmware.tar.gz b/modules/firmware/all_firmware.tar.gz similarity index 100% rename from system/modules/firmware/all_firmware.tar.gz rename to modules/firmware/all_firmware.tar.gz diff --git a/system/modules/firmware/kernelcache.release.mac14j b/modules/firmware/kernelcache.release.mac14j similarity index 100% rename from system/modules/firmware/kernelcache.release.mac14j rename to modules/firmware/kernelcache.release.mac14j diff --git a/system/modules/laptop.nix b/modules/laptop.nix similarity index 94% rename from system/modules/laptop.nix rename to modules/laptop.nix index 127dd95..7dfd6c9 100644 --- a/system/modules/laptop.nix +++ b/modules/laptop.nix @@ -2,7 +2,7 @@ # flake.nix. Shared graphical-workstation settings live in ./workstation.nix; # the only laptop-specific bit is the Wi-Fi backend. Mobile home-manager # components (battery block, brightness keys) are gated by the `portable` flag -# threaded through mkHost -- see lyrathorpe/home/sway.nix. +# threaded through mkHost -- see home/sway.nix. { ... }: { imports = [ ./workstation.nix ]; diff --git a/modules/ssh.nix b/modules/ssh.nix new file mode 100644 index 0000000..f56ec95 --- /dev/null +++ b/modules/ssh.nix @@ -0,0 +1,11 @@ +# Key-only sshd hardening, imported by hosts that run sshd (T400, Mac Pro, +# RPi5). Authorized keys are owned per-user by the registry (modules/users.nix), +# not here. +{ ... }: +{ + services.openssh.settings = { + PasswordAuthentication = false; # keys only + KbdInteractiveAuthentication = false; # no keyboard-interactive fallback + PermitRootLogin = "no"; + }; +} diff --git a/lyrathorpe/swaywm.nix b/modules/sway.nix similarity index 97% rename from lyrathorpe/swaywm.nix rename to modules/sway.nix index 22d27c5..8b01ac1 100644 --- a/lyrathorpe/swaywm.nix +++ b/modules/sway.nix @@ -7,8 +7,8 @@ let cfg = config.features.swayDesktop; - # Catppuccin Mocha (shared with the Sway desktop, see lyrathorpe/home/sway.nix). - ctp = import ./catppuccin-mocha.nix; + # Catppuccin Mocha (shared with the Sway desktop, see home/sway.nix). + ctp = import ../lib/catppuccin-mocha.nix; in { # The features.swayDesktop.enable option is declared in diff --git a/modules/users.nix b/modules/users.nix new file mode 100644 index 0000000..ab45bf4 --- /dev/null +++ b/modules/users.nix @@ -0,0 +1,38 @@ +# System user accounts, built from the registry (users/registry.nix) for the +# host's `hostUsers` set. See README "Users". +{ + config, + pkgs, + lib, + hostUsers, + userRegistry, + ... +}: + +{ + programs.zsh.enable = true; + + users.users = lib.mapAttrs ( + name: spec: + let + id = userRegistry.${name}; + in + { + isNormalUser = true; + home = "/home/${name}"; + description = id.fullName; + inherit (id) extraGroups; + openssh.authorizedKeys.keys = id.sshAuthorizedKeys; + shell = pkgs.zsh; + } + # linger opt-in (host table); left unmanaged when unset. + // lib.optionalAttrs (spec ? linger) { inherit (spec) linger; } + ) hostUsers; + + programs.firefox = lib.mkIf (config.features.swayDesktop.enable == true) { + enable = true; + }; + programs.thunderbird = lib.mkIf (config.features.swayDesktop.enable == true) { + enable = true; + }; +} diff --git a/system/modules/workstation.nix b/modules/workstation.nix similarity index 100% rename from system/modules/workstation.nix rename to modules/workstation.nix diff --git a/system/modules/ssh.nix b/system/modules/ssh.nix deleted file mode 100644 index ee2423a..0000000 --- a/system/modules/ssh.nix +++ /dev/null @@ -1,19 +0,0 @@ -# Key-only SSH hardening, imported by the hosts that run sshd (T400, Mac Pro). -# The host config still does `services.openssh.enable = true` and opens port 22 -# next to where it documents the listening service; this module only tightens -# the policy and installs the authorized key, so a host opting into sshd cannot -# accidentally ship password/root login. -{ username, ... }: -{ - services.openssh.settings = { - PasswordAuthentication = false; # keys only - KbdInteractiveAuthentication = false; # no keyboard-interactive fallback - PermitRootLogin = "no"; - }; - - # The key permitted to log in as the primary user. Add more entries here as - # new client machines are provisioned. - users.users.${username}.openssh.authorizedKeys.keys = [ - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA" - ]; -} diff --git a/lyrathorpe/home/renovate-review.nix b/users/emmathorpe/renovate-review.nix similarity index 100% rename from lyrathorpe/home/renovate-review.nix rename to users/emmathorpe/renovate-review.nix diff --git a/lyrathorpe/home/work.nix b/users/emmathorpe/work.nix similarity index 77% rename from lyrathorpe/home/work.nix rename to users/emmathorpe/work.nix index 6191c5a..049f047 100644 --- a/lyrathorpe/home/work.nix +++ b/users/emmathorpe/work.nix @@ -1,5 +1,5 @@ -# Home-manager module for the work (EDaaS/WSL) profile: corporate git signing, -# work toolchain packages and tmux tweaks. Imported only by the work host. +# Work (EDaaS/WSL) home profile: corporate toolchain + tmux tweaks. Git identity +# comes from the registry (users/registry.nix), not here. { pkgs, lib, ... }: { @@ -12,15 +12,6 @@ # programs.ssh (shell.nix) take it over. The ssh-agent below still runs. programs.ssh.enable = lib.mkForce false; - programs.git = { - settings = { - commit.gpgsign = true; - tag.gpgsign = true; - gpg.format = "ssh"; - user.signingkey = "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJMVgeRKnfX1G8coU3nAobI485aeUpGTMqH7+zbKI8o emma.thorpe@cloud.com"; - user.email = "emma.thorpe@citrix.com"; - }; - }; home.packages = [ pkgs.kubectl pkgs.argo-rollouts @@ -66,7 +57,7 @@ }; # LSP servers only relevant to work: C# (omnisharp) and Helm charts (helm_ls). - # The shared editor (lyrathorpe/home/editor.nix) carries the universal ones; + # The shared editor (home/editor.nix) carries the universal ones; # these are gated to this host so the heavy omnisharp closure stays off the # personal machines. Tree-sitter grammars (highlighting) remain global there. programs.nixvim.plugins.lsp.servers = { diff --git a/users/lyrathorpe/home.nix b/users/lyrathorpe/home.nix new file mode 100644 index 0000000..572da4f --- /dev/null +++ b/users/lyrathorpe/home.nix @@ -0,0 +1,17 @@ +# Lyra's personal home extras, imported on her hosts (not the work box). Keeps +# personal data out of the shared home/ modules. See README "Users". +{ pkgs, lib, ... }: +{ + # Personal ssh host shortcut. + programs.ssh.settings."dockerpi.inf.cbg.emmaisvery.gay" = { + User = "emmathorpe"; + }; + + # Night-light location for gammastep (the service itself is enabled by + # home/sway.nix on graphical hosts). Linux-guarded so Darwin, which imports + # this module but has no gammastep, skips it. + services.gammastep = lib.mkIf pkgs.stdenv.hostPlatform.isLinux { + latitude = 51.5; + longitude = -0.13; + }; +} diff --git a/users/registry.nix b/users/registry.nix new file mode 100644 index 0000000..7aba111 --- /dev/null +++ b/users/registry.nix @@ -0,0 +1,28 @@ +# User identity registry -- pure data, keyed by username. See README "Users". +# (`identity.username` is injected by mkHost, so it is not repeated here.) +{ + lyrathorpe = { + fullName = "Lyra Thorpe"; + email = "iam@emmathe.dev"; + extraGroups = [ + "wheel" + "docker" + ]; + sshAuthorizedKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA" + ]; + signingKey = "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDxHvdMTOzpFWUFMtCP7C/4tIOUO3GIO2QPvaifSnWH lyrathorpe@Lyra-MBA"; + }; + + emmathorpe = { + fullName = "Emma Thorpe"; + email = "emma.thorpe@citrix.com"; + extraGroups = [ + "wheel" + "docker" + ]; + # No personal key on file yet; add one if SSH login as emmathorpe is wanted. + sshAuthorizedKeys = [ ]; + signingKey = "key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJMVgeRKnfX1G8coU3nAobI485aeUpGTMqH7+zbKI8o emma.thorpe@cloud.com"; + }; +}