refactor(flake): user registry, multi-user hosts, and portable home outputs (#49)
CI / flake (push) Successful in 3m26s
CI / flake (push) Successful in 3m26s
## 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."<user>@<system>"` (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 <emma.thorpe@citrix.com> Reviewed-on: #49
This commit was merged in pull request #49.
This commit is contained in:
@@ -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";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user