Archived
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>
144 lines
6.6 KiB
Markdown
Executable File
144 lines
6.6 KiB
Markdown
Executable File
# 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:
|
||
```bash
|
||
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.
|