This repository has been archived on 2026-07-30. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
nixos/flake-target-refactor-spec.md
T
beatzaplentyandClaude Sonnet 5 c05e3a3821
Check NixOS configurations / eval-hosts (push) Failing after 12m2s
Refactor flake targets into platform x build-type matrix
Generates all nixosConfigurations from mkTarget(platform, buildType,
hostPath) instead of hand-written per-host blocks, so adding a new
platform or build type is a one-line addition. Per-machine identity
(hostname, hostId, secrets, stateVersion) moves into hosts/<name>/host.nix;
platform-specific config (hardware, boot, networking) into
modules/platforms/*.nix; build-type config (minimal/server/docker/gui/
nix-cache/pxe-boot) into modules/build-types/*.nix.

Old flat targets (nixos, docker, server, nix-cache, nix-minimal, pxe-boot)
are replaced by the 17-target <platform>-<buildtype> matrix; each new
target was verified to evaluate before its old counterpart was removed.
CI workflows and docs/aliases now discover hosts dynamically via
nixosConfigurations attrNames and /etc/flake-target instead of hardcoded
lists, so they can't drift from flake.nix again.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 12:03:33 +10:00

6.6 KiB
Executable File
Raw Blame History

Spec: Refactor Flake Targets into Platform × Build-Type Matrix

Context

The flake at ~/nixos currently defines these output targets (flat, ad-hoc naming):

  • docker
  • linode-minimal
  • nix-cache
  • nix-minimal
  • nixos
  • server
  • pxe-boot

Some already follow a platform-buildtype convention (linode-minimal), most don't. ~/nix-auto-installer is a related repo and should be checked for any coupling to these target names (scripts, docs, CI, or install automation that reference them by name) before renaming anything.

Goal

Restructure the flake so targets are generated from two orthogonal concepts:

Build types (what the system is for):

  • minimal
  • nix-cache
  • server
  • docker
  • pxe-boot
  • gui

Platforms (what it's deployed on):

  • linode (Linode VM)
  • proxmox (Proxmox VM)
  • lxc (Proxmox LXC container)

Final targets should be named consistently as <platform>-<buildtype>, e.g.:

linode-minimal    proxmox-minimal    lxc-minimal
linode-nix-cache  proxmox-nix-cache  lxc-nix-cache
linode-server     proxmox-server     lxc-server
linode-docker     proxmox-docker     lxc-docker
linode-pxe-boot   proxmox-pxe-boot   lxc-pxe-boot
linode-gui        proxmox-gui        lxc-gui

That's the full matrix (18 targets) if every build type applies to every platform. See Open Questions below — some combinations may not make sense and should be confirmed with me before being built out, not silently included or dropped.

Migration mapping (old → new)

Old target New target Notes
linode-minimal linode-minimal Already correct, keep as-is
nix-minimal likely proxmox-minimal or a platform-less base module Ambiguous — see Open Questions
nix-cache base module consumed by linode-nix-cache, proxmox-nix-cache, lxc-nix-cache Currently platform-less; needs to become a build-type module, not a standalone target
server base module consumed by linode-server, proxmox-server, lxc-server Same as above
docker base module consumed by linode-docker, proxmox-docker, lxc-docker Confirm docker actually makes sense as an LXC/VM guest build vs. a standalone container image — see Open Questions
pxe-boot TBD — may stay a single target rather than a per-platform one See Open Questions
nixos TBD — unclear what this maps to in the new scheme See Open Questions

Open Questions (Claude Code: raise these with me before implementing, don't guess)

  1. nixos target — what is this currently used for (bare metal install, dev shell, template)? It doesn't obviously map to any of the six build types.
  2. nix-minimal vs linode-minimal — are these two different things, or is nix-minimal a leftover/duplicate?
  3. pxe-boot and gui across all three platforms — does PXE boot make sense for an LXC container or a cloud VM (Linode), or is it inherently bare-metal/ network-boot only and should remain a single non-platform target? Does gui make sense inside an LXC container?
  4. docker as a build type — is this "a NixOS host configured to run Docker" (which would sensibly have linode/proxmox/lxc variants), or "a Docker container image built by the flake" (which wouldn't take a platform prefix at all, since it doesn't run on Linode/Proxmox/LXC as a guest OS)? These are structurally different and change how it should be wired in.
  5. Confirm whether all 18 combinations should actually exist, or whether this is meant to produce only the combinations that are genuinely useful (e.g. maybe no one needs lxc-pxe-boot).

Implementation approach

  1. Inventory first. Read the current flake.nix and any nixosConfigurations/ modules structure. Map every existing target to what module(s) it actually pulls in. Don't assume — confirm against the real file contents.
  2. Separate build-type and platform into their own module directories, e.g.:
    modules/build-types/minimal.nix
    modules/build-types/nix-cache.nix
    modules/build-types/server.nix
    modules/build-types/docker.nix
    modules/build-types/pxe-boot.nix
    modules/build-types/gui.nix
    
    modules/platforms/linode.nix
    modules/platforms/proxmox.nix
    modules/platforms/lxc.nix
    
    Build-type modules should contain only what makes a system "minimal" vs "server" vs "gui", etc. Platform modules should contain only what's specific to running as a Linode VM vs Proxmox VM vs LXC container (virtualisation guest tools, boot method, filesystem/image format, LXC-specific constraints like no kernel modules, etc).
  3. Generate the target matrix programmatically in flake.nix rather than hand-writing 18 near-identical nixosConfigurations entries — e.g. a small function that takes a platform name and build-type name, composes the two modules plus any shared base module, and produces the named output. This keeps future build types/platforms a one-line addition rather than a copy-paste job.
  4. Only build combinations we've confirmed make sense (see Open Questions) — don't emit all 18 by default if some are structurally invalid.
  5. Preserve existing working configs during the transition. Don't delete the old target names until their replacements build successfully — rename/alias at the end, not the start, so there's no window where the flake is broken.

Verification

For every new target produced:

nix flake check
nix build .#nixosConfigurations.<target>.config.system.build.toplevel

Confirm each builds without evaluation errors before considering it done. If a target fails to build, report which one and why rather than silently skipping it.

Deliverables

  • Refactored flake.nix using the composed module + generated-matrix approach.
  • New modules/build-types/*.nix and modules/platforms/*.nix files.
  • Old flat target names removed only after their replacements are verified.
  • A short README.md (or section in existing docs) listing the final target names and what each one is for.
  • A summary at the end of what changed, what was removed, and any of the Open Questions above that got resolved differently than expected.

Out of scope

  • Don't touch ~/nix-auto-installer contents beyond checking it for references to the old target names — if changes there are needed, flag them, don't make them without confirming.
  • Don't add new build types or platforms beyond the ones listed here.