home.nix depends on nix-colors (colorScheme), lazyvim, and walker HM modules; previously every host wired them by hand via `modules`, which external consumers couldn't know to do. Inject them in mkSystem so any host built through it gets them; re-importing from a host is a no-op. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
185 lines
6.8 KiB
Nix
185 lines
6.8 KiB
Nix
# mksystem — uniform NixOS host constructor.
|
|
#
|
|
# Inspired by mitchellh/nixos-config's lib/mksystem.nix, adapted for our
|
|
# context. Replaces the boilerplate of repeated `nixpkgs.lib.nixosSystem`
|
|
# calls in flake.nix with a single function that:
|
|
#
|
|
# - dispatches to nixpkgs.lib.nixosSystem
|
|
# - applies overlays uniformly
|
|
# - imports `hosts/<name>.nix` (or `hosts/<name>/default.nix`) by convention
|
|
# - imports `users/<user>/nixos.nix` if it exists
|
|
# - wires home-manager and imports `users/<user>/home-manager.nix`
|
|
# - opt-in dev-env via `devEnv = true` (imports modules/dev-env)
|
|
# - exposes `currentSystemName`, `currentSystemUser`, `inputs` to every
|
|
# module via specialArgs so downstream code can introspect host context
|
|
#
|
|
# Usage in flake.nix:
|
|
#
|
|
# let
|
|
# overlays = import ./lib/overlays.nix { inherit inputs; };
|
|
# mkSystem = import ./lib/mksystem.nix { inherit nixpkgs overlays inputs; };
|
|
# in
|
|
# {
|
|
# nixosConfigurations = {
|
|
# my-laptop = mkSystem "my-laptop" {
|
|
# user = "padreug";
|
|
# devEnv = true;
|
|
# };
|
|
#
|
|
# # Multiple users on the same machine, no dev-env:
|
|
# lab-shared = mkSystem "lab-shared" {
|
|
# user = "padreug";
|
|
# };
|
|
# };
|
|
# }
|
|
#
|
|
# Differences from mitchellh's version:
|
|
#
|
|
# - NixOS only (no darwin, no WSL — we don't need those right now and
|
|
# the dispatch is easy to add later if we do).
|
|
# - dev-env module is opt-in; not every host wants it.
|
|
# - `modules` parameter lets a host inject extra modules without
|
|
# creating a wrapper file.
|
|
# - Uses specialArgs (not _module.args inside a module) so the values
|
|
# are visible to imported file paths, which is required for things
|
|
# like `(let path = currentSystemName; in ./hosts/${path})`.
|
|
|
|
{
|
|
nixpkgs,
|
|
overlays ? [ ],
|
|
inputs,
|
|
}:
|
|
|
|
name:
|
|
{
|
|
system ? "x86_64-linux",
|
|
user,
|
|
devEnv ? false,
|
|
modules ? [ ],
|
|
# Home-manager config for `user`, as a PATH. External consumers pass
|
|
# their own (e.g. `home = ./home.nix`). When null, fall back to this
|
|
# repo's users/<user>/home-manager.nix, then to Omnixient's home.nix.
|
|
home ? null,
|
|
# Extra args merged into the system-level specialArgs. Used by hosts
|
|
# whose configuration.nix expects values beyond the defaults (e.g.
|
|
# omni's configuration.nix takes `settings` from settings.nix).
|
|
extraSpecialArgs ? { },
|
|
# Same, for home-manager.extraSpecialArgs.
|
|
extraHmArgs ? { },
|
|
}:
|
|
|
|
let
|
|
# Resolve the host's config file. Prefer `hosts/<name>/default.nix`
|
|
# (lets a host have its own subdirectory for hardware files etc.),
|
|
# fall back to a flat `hosts/<name>.nix`.
|
|
hostDir = ../hosts/${name};
|
|
hostFile = ../hosts + "/${name}.nix";
|
|
# Internal hosts (this repo's hosts/<name>/) are imported automatically.
|
|
# External consumers using this flake as an input have no host dir here,
|
|
# so they pass their host config through `modules` and we add nothing.
|
|
hostConfigModules =
|
|
if builtins.pathExists hostDir then
|
|
[ hostDir ]
|
|
else if builtins.pathExists hostFile then
|
|
[ hostFile ]
|
|
else if modules != [ ] then
|
|
[ ]
|
|
else
|
|
throw "mksystem: no host config for '${name}' — add hosts/${name}/ or pass one via `modules` (looked at ${toString hostDir} and ${toString hostFile})";
|
|
|
|
userNixosConfig = ../users/${user}/nixos.nix;
|
|
hasUserNixosConfig = builtins.pathExists userNixosConfig;
|
|
|
|
# Home-manager config for `user`, resolved in priority order so both
|
|
# internal hosts and external consumers get a working home:
|
|
# 1. caller-supplied `home` (consumer override), else
|
|
# 2. this repo's users/<user>/home-manager.nix (internal hosts), else
|
|
# 3. Omnixient's default home.nix (consumer whose user isn't in this tree).
|
|
internalUserHM = ../users/${user}/home-manager.nix;
|
|
userHMConfig =
|
|
if home != null then
|
|
home
|
|
else if builtins.pathExists internalUserHM then
|
|
internalUserHM
|
|
else
|
|
../home.nix;
|
|
in
|
|
|
|
nixpkgs.lib.nixosSystem {
|
|
# specialArgs flow into every module's function signature AND can be
|
|
# used in `imports = [ ... ]` paths. _module.args cannot, which is
|
|
# why we don't use it for these.
|
|
specialArgs = {
|
|
inherit inputs;
|
|
currentSystemName = name;
|
|
currentSystemUser = user;
|
|
}
|
|
// extraSpecialArgs;
|
|
|
|
modules = [
|
|
# Apply overlays first so subsequent modules see our pinned packages.
|
|
{ nixpkgs.hostPlatform = system; }
|
|
{ nixpkgs.overlays = overlays; }
|
|
{ nixpkgs.config.allowUnfree = true; }
|
|
]
|
|
# Per-host configuration: this repo's hosts/<name>/ when present;
|
|
# external consumers supply their host through `modules`.
|
|
++ hostConfigModules
|
|
# Per-user system-level config (account, shell, sudo) — only if the
|
|
# user file exists. Skipping silently is fine; some hosts share users
|
|
# defined elsewhere (e.g. omni's users.nix).
|
|
++ nixpkgs.lib.optional hasUserNixosConfig userNixosConfig
|
|
++ [
|
|
# sops-nix — declarative age-encrypted secrets, decrypted at
|
|
# activation. Module always included; host modules opt in by
|
|
# declaring `sops.secrets.<name>`. Per-host wiring (defaultSopsFile,
|
|
# age.keyFile) lives in modules/secrets.nix.
|
|
inputs.sops-nix.nixosModules.sops
|
|
]
|
|
++ [
|
|
# Opt-in packs — always imported (so the omni.packs.<name>.* option
|
|
# namespace exists) but inert until `omni.packs.<name>.enable = true`.
|
|
# Single wire-in point; the ISO bypasses mksystem and so stays
|
|
# pack-free. See modules/packs/default.nix.
|
|
../modules/packs
|
|
]
|
|
++ [
|
|
# Home-manager wiring.
|
|
inputs.home-manager.nixosModules.home-manager
|
|
{
|
|
home-manager.useGlobalPkgs = true;
|
|
home-manager.useUserPackages = true;
|
|
home-manager.extraSpecialArgs = {
|
|
inherit inputs;
|
|
currentSystemName = name;
|
|
currentSystemUser = user;
|
|
}
|
|
// extraHmArgs;
|
|
# Omnixient's home.nix depends on these home-manager modules
|
|
# (colorScheme via nix-colors, programs.lazyvim, programs.walker).
|
|
# Inject them for every host so consumers don't wire them by hand;
|
|
# re-importing the same module from a host's `modules` is a no-op.
|
|
home-manager.sharedModules = [
|
|
inputs.nix-colors.homeManagerModules.default
|
|
inputs.lazyvim.homeManagerModules.default
|
|
inputs.walker.homeManagerModules.default
|
|
];
|
|
}
|
|
# Pre-create the home-manager activation script's expected
|
|
# directory tree. See modules/home-manager-bootstrap.nix for
|
|
# the full rationale and the bugs it fixes. Imported here
|
|
# rather than inlined so the live ISO (which bypasses
|
|
# mksystem) can import the same module and get the same
|
|
# bootstrap.
|
|
../modules/home-manager-bootstrap.nix
|
|
]
|
|
++ [
|
|
# Home config for `user` — always wired now that userHMConfig always
|
|
# resolves (caller `home`, internal shim, or Omnixient's home.nix).
|
|
{ home-manager.users.${user} = import userHMConfig; }
|
|
]
|
|
# dev-env is opt-in.
|
|
++ nixpkgs.lib.optional devEnv ../modules/dev-env
|
|
# Caller-supplied extras.
|
|
++ modules;
|
|
}
|