Adds an unattended install option to the PXE boot menu that installs
Rocky Linux 9 and configures FreeIPA on the domain-controller.sweet.home
host without any operator interaction after selecting the menu entry.
How it works:
- fetch-rocky-pxeboot.service downloads the Rocky 9 Anaconda pxeboot
kernel and initrd from the Rocky mirror on first pxe-boot deploy
(idempotent, same pattern as fetch-debian-netboot)
- rocky-freeipa.ipxe boots Anaconda with inst.ks pointing at the
hosted Kickstart and net.ifnames=0 biosdevname=0 for stable eth0
- rocky-freeipa.ks (generated, includes vars.adminSshKey) performs:
- Minimal Rocky 9 install with ipa-server + ipa-server-dns
- Static IP 192.168.2.138 via NM connection file written in %post
- /etc/hosts fixed for FreeIPA FQDN requirement
- Random DM + admin passwords generated and saved to
/root/ipa-credentials.txt (chmod 600, never hardcoded)
- freeipa-first-boot.service oneshot enabled to run
ipa-server-install on the first real boot (~20 min)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015Jbvxx4xbHVcx1NkK3vtmK
- Correct the NFS path from /tank/proxmox/pxe-images to /tank/pxe-boot/images
(matches variables.nix's proxmoxPxeImages.subpath)
- Clarify that LXC uses NFSv3+nolock while VM uses NFSv4.2+automount
- Add explicit note that lxc-pxe-boot needs features: nesting=1,mount=nfs and
why: nesting=1 is required by systemd 260+ for userns/credential isolation
(AppArmor denies userns_create without it), mount=nfs for NFSv3 access.
pct set replaces the whole features string — include both or the container
will fail to boot.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds modules/pxe-boot/mount-pxe-images.nix, which mounts
server.sweet.home:/tank/proxmox/pxe-images at /mnt/pxe-images via NFSv4.2
(x-systemd.automount on Proxmox VMs, nofail on LXC containers — same pattern
as docker/mount-data.nix). The pxe-boot build-type now imports this module and
replaces the previous local /srv/pxe/http/images directory rule with an L+
symlink pointing to /mnt/pxe-images, so large images (ISOs, disk images) live
on the NFS share rather than the host's own root disk.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a `fetch-debian-netboot.service` oneshot that downloads the Debian
bookworm netboot kernel and initrd from deb.debian.org on first boot,
stages them under /srv/pxe/http/debian/, and serves them via a generated
debian.ipxe chain script. The service is idempotent — it skips the
download if both files are already present.
Also merges the previously split systemd.tmpfiles.rules and
systemd.services blocks into a single systemd = { ... } attrset to
satisfy statix's repeated-keys lint.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The iPXE menu's "nixos" entry actually chain-loads this flake's own
custom auto-installer image, not a stock NixOS image — rename it to
"auto-installer" (label "NixOS Auto-Installer") so the menu says what it
boots, and set networking.hostName on netbootSystem to match, so the
generated system name (nixos-system-auto-installer-*) and staged
directory (/srv/pxe/http/auto-installer) agree with the menu entry too.
Add a second, genuinely vanilla NixOS minimal netboot image
(netbootMinimalSystem in flake.nix — nixpkgs' netboot-minimal.nix on its
own, none of modules/installer/common.nix's auto-installer wiring),
built from source the same way as the auto-installer image and exposed
as packages.x86_64-linux.pxe-minimal. Staged and menu-wired the same
way, as "nixos-minimal" (item, hostname, and directory all matching).
modules/pxe-boot/stage-installer-artifacts.nix is generalized to stage
both images via a shared rule-builder instead of one hardcoded set of
paths.
Verified: nix eval confirms both images' config.system.name matches
their menu entry/directory names, the pxe-boot host itself builds
clean with the new menu.ipxe, and the new pxe-minimal image was booted
directly under QEMU (kernel+initrd, no KVM) to a working login shell
with hostname nixos-minimal, no hang.
Both check-nixos.yml workflows (GitHub + Gitea) now call
scripts/codex-maintenance.sh instead of a hand-rolled eval-only loop,
closing a real gap: CI previously enforced none of the secret grep,
nixpkgs-fmt, or statix checks that codex-maintenance.sh already runs
locally — nothing was stopping that from regressing. One script now
backs both, instead of two copies that can drift from each other.
codex-maintenance.sh itself is extended to cover buildable surface
that wasn't validated anywhere before: packages.x86_64-linux.*, plus
config.system.build.tarball (lxc-* hosts) and
config.system.build.diskoImagesScript (proxmox-*, excluding the
installer's own proxmox-lxc target, which has no disko config).
Also:
- scripts/prepare-host-key.sh: dropped the redundant
[path-to-nixos-repo] parameter — it always defaults to the repo the
script itself lives in now, so a second argument never made sense
after the nix-auto-installer migration.
- Removed prepare.sh (dead pre-disko manual parted/mkfs/mkswap
partitioning, fully superseded) and
scripts/create-linode-installer-disk.sh (incomplete draft for an
abandoned dd-via-rescue-mode approach; Linode hosts already deploy
fine through the normal auto-installer flow).
- docs/pxe-boot.md: fixed a stale `nixosConfigurations.pxe-boot` eval
command (pre-refactor flat name, not a real flake attribute
anymore) and added a cross-reference to docs/auto-installer.md.
- CLAUDE.md/README.md: full documentation pass reconciling this
session's changes — modules/installer/, modules/pxe-boot/, the
LXC/Proxmox image-building deployment paths, corrected the
password-hash/SSH-key locations in the safety-rules section (both
had drifted to reference files/paths that no longer exist), and
added session-workflow guidance to prefer targeted host evals over
full-repo sweeps for incremental changes (explicitly scoped to
interactive sessions, not CI).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01La55Nsss8jZ7ZuzUV9mfot
Adds debian@surface's existing SSH key (already used as its admin
key elsewhere in this repo) to vars.remoteBuilderAuthorizedKeys so
nix-cache will accept it as a distributed-build client once deployed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01La55Nsss8jZ7ZuzUV9mfot