feat(lib): mksystem builder and nixpkgs overlays
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d37ac719d3
commit
87bfc4cc31
2 changed files with 198 additions and 0 deletions
154
lib/mksystem.nix
Normal file
154
lib/mksystem.nix
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
# 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 ? [ ],
|
||||||
|
# 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";
|
||||||
|
hostConfig =
|
||||||
|
if builtins.pathExists hostDir then
|
||||||
|
hostDir
|
||||||
|
else if builtins.pathExists hostFile then
|
||||||
|
hostFile
|
||||||
|
else
|
||||||
|
throw "mksystem: no host config for '${name}' (looked at ${toString hostDir} and ${toString hostFile})";
|
||||||
|
|
||||||
|
userNixosConfig = ../users/${user}/nixos.nix;
|
||||||
|
userHMConfig = ../users/${user}/home-manager.nix;
|
||||||
|
|
||||||
|
hasUserNixosConfig = builtins.pathExists userNixosConfig;
|
||||||
|
hasUserHMConfig = builtins.pathExists userHMConfig;
|
||||||
|
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.
|
||||||
|
hostConfig
|
||||||
|
]
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
|
# 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
|
||||||
|
]
|
||||||
|
++ nixpkgs.lib.optional hasUserHMConfig {
|
||||||
|
home-manager.users.${user} = import userHMConfig;
|
||||||
|
}
|
||||||
|
# dev-env is opt-in.
|
||||||
|
++ nixpkgs.lib.optional devEnv ../modules/dev-env
|
||||||
|
# Caller-supplied extras.
|
||||||
|
++ modules;
|
||||||
|
}
|
||||||
44
lib/overlays.nix
Normal file
44
lib/overlays.nix
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Overlays applied uniformly across every host built by mksystem.
|
||||||
|
#
|
||||||
|
# Pin select fast-moving packages to nixpkgs-unstable while keeping
|
||||||
|
# everything else on the stable channel. This is the mitchellh pattern:
|
||||||
|
# stable for stability, unstable for the handful of things that move
|
||||||
|
# faster than we want to wait.
|
||||||
|
#
|
||||||
|
# To use, the flake.nix needs both inputs:
|
||||||
|
#
|
||||||
|
# inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
|
||||||
|
# inputs.nixpkgs-unstable.url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||||
|
#
|
||||||
|
# Then:
|
||||||
|
#
|
||||||
|
# overlays = import ./lib/overlays.nix { inherit inputs; };
|
||||||
|
# mkSystem = import ./lib/mksystem.nix { inherit nixpkgs overlays inputs; };
|
||||||
|
|
||||||
|
{ inputs }:
|
||||||
|
|
||||||
|
[
|
||||||
|
# Pinned-to-unstable packages.
|
||||||
|
#
|
||||||
|
# Add a package here when stable is too slow for your needs (claude-code
|
||||||
|
# ships weekly, gh fixes are frequent, direnv has churn). Remove when
|
||||||
|
# stable catches up. Keep the list small — every entry is a divergence
|
||||||
|
# from the rest of the stable closure.
|
||||||
|
(
|
||||||
|
final: prev:
|
||||||
|
let
|
||||||
|
unstable = import inputs.nixpkgs-unstable {
|
||||||
|
system = prev.stdenv.hostPlatform.system;
|
||||||
|
config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
claude-code = unstable.claude-code;
|
||||||
|
pi-coding-agent = unstable.pi-coding-agent;
|
||||||
|
gh = unstable.gh;
|
||||||
|
direnv = unstable.direnv;
|
||||||
|
nix-direnv = unstable.nix-direnv;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue