- Wire -dev variants to the radiantwave-dev input (?ref=dev); prod keeps main - Fix android-dev upgradeFlakeRef (was upgrading into production config) - Parameterize one installer module (zero-touch-installer.nix); replace the four near-duplicate ISO configs; mkIso pairs each ISO with its closure + disk layout, fixing commercial-dev/android-dev ISO eval errors - Add missing packages outputs (commercial-dev, android-dev, rpi, rpi-dev) - Set networking.hostName + system.configurationRevision per variant - Remove gitea access token and dead netrc/JWT config (repos are public) - Drop flake.lock update step from CI (lock updates are manual) - Refresh AGENTS.md: variants/ISO tables, facter report procedure, gotchas
7.0 KiB
AGENTS.md
What this repo is
NixOS flake that defines kiosk systems running the RadiantWave app. Not application code — this is the OS image and deployment configuration. The actual app lives in the radiantwave flake inputs (from gitea.radiantwavetech.com).
Hosted on Gitea: https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig
Prod/dev split
Single branch (main) for this repo. The production vs. dev split is at the flake input + upgrade ref level:
- Production variants consume the
radiantwaveinput (?ref=main) and auto-upgrade fromKioskConfig.git#<config>onmain. -devvariants consume theradiantwave-devinput (?ref=dev) and auto-upgrade fromKioskConfig.git?ref=dev#<config>-dev.
Both gitea repos are public: all git access is plain HTTPS (git+https://...), no SSH keys or access tokens on the kiosks. Don't reintroduce git+ssh URLs in flake/upgrade refs.
Key commands
# Build a system closure (any config name from flake.nix)
nix build .#nixosConfigurations.<name>.config.system.build.toplevel
# Build a bootable ISO
nix build .#nixosConfigurations.<name>.config.system.build.isoImage
# Deploy to a remote kiosk over SSH
nixos-rebuild switch --flake .#<name> --target-host root@<host>
# Push build result to Attic cache (not currently wired into any config)
attic push kiosk ./result
# Evaluate available config names
nix eval .#nixosConfigurations --apply builtins.attrNames
Config variants
| Name | Target hardware | Disk device | App input |
|---|---|---|---|
radiantwavekiosk |
Intel NUC 14 (NVMe) | /dev/nvme0n1 |
radiantwave (main) |
radiantwavekiosk-dev |
Intel NUC 14 (NVMe) | /dev/nvme0n1 |
radiantwave-dev (dev) |
radiantwavekiosk-commercial |
Commercial HW (SATA) | /dev/sda |
radiantwave (main) |
radiantwavekiosk-commercial-dev |
Commercial HW (SATA) | /dev/sda |
radiantwave-dev (dev) |
radiantwavekiosk-android |
Intel NUC 14, rotated display | /dev/nvme0n1 |
radiantwave (main) |
radiantwavekiosk-android-dev |
Intel NUC 14, rotated display | /dev/nvme0n1 |
radiantwave-dev (dev) |
radiantwavekiosk-rpi |
Raspberry Pi 5 (SD image) | — | radiantwave (main) |
radiantwavekiosk-rpi-dev |
Raspberry Pi 5 (SD image) | — | radiantwave-dev (dev) |
Every variant sets its own networking.hostName (same as the config name) and system.configurationRevision, so tools/find_systems.zsh can identify fleet members.
USB images (zero-touch installers)
Each ISO installs exactly one closure using that closure's disk layout (mkIso in flake.nix derives both from the target config name):
| ISO | Installs | Disk layout |
|---|---|---|
kiosk-iso |
radiantwavekiosk |
NVMe (disk-config.nix) |
dev-iso |
radiantwavekiosk-dev |
NVMe |
commercial-iso |
radiantwavekiosk-commercial |
SATA (commercial-disk-config.nix) |
commercial-dev-iso |
radiantwavekiosk-commercial-dev |
SATA |
android-iso |
radiantwavekiosk-android |
NVMe |
android-dev-iso |
radiantwavekiosk-android-dev |
NVMe |
The installer lives once in zero-touch-installer.nix and is parameterized by targetConfig. Adding a new variant = add the nixosConfigurations.* entry, a matching packages.x86_64-linux.* line, and an ISO if needed.
Raspberry Pi systems are built as SD images, not ISOs:
nix build .#nixosConfigurations.radiantwavekiosk-rpi.config.system.build.sdImage (see build-rpi.sh).
Hardware facter reports
facter.json is a hardware report captured on a NUC 14. It is currently applied to every x86 variant, including the commercial SATA hardware — acceptable until per-model reports exist.
To generate a report for a hardware model:
- Boot that hardware from any NixOS live image (the kiosk installers work).
- With real peripherals attached (display(s), audio), run:
sudo nix shell nixpkgs#nixos-facter -c nixos-facter -o facter-<model>.json - Commit
facter-<model>.jsonto the repo root. - Wire it up at the marked spot in
flake.nix(facter.reportPathinsidemkKioskSystem) by selecting the right file per variant.
Regenerate when major hardware changes, not on a schedule — reports are snapshots. RPi configs don't use the facter module, so no report is needed there.
CI (Gitea)
.gitea/workflows/build-*.yml — all triggered by workflow_dispatch on the build-server runner. They only build and publish what is committed. flake.lock is updated manually: commit an updated lock (e.g. after nix flake update radiantwave-dev) and dispatching the workflow is the release trigger.
Important gotchas
- Disk device differs by variant:
disk-config.nixuses/dev/nvme0n1,commercial-disk-config.nixuses/dev/sda.mkIsopairs each ISO with the correct layout automatically — keep new ISOs paired correctly. - Changing a config name requires updating that config's
upgradeFlakeRefinflake.nix(it embeds the name). rotated_display.nixusesmkForceonloginShellInit— it replaces the entire kiosk startup script fromconfiguration.nix; don't edit both.- Auto-update:
system.autoUpgraderuns every 10 min (*:00/10) with--refresh, operationswitch, no auto-reboot. Aradiantwave-backuprsync runs before each attempt. The health-check/rollback service is written but commented out inconfiguration.nix. - No binary cache: kiosks fetch from cache.nixos.org only and compile RadiantWave itself from source during upgrades. Attic integration was planned (see
PLAN-update-system.md) but never wired; the old netrc/JWT setup has been removed. - Secrets: none in-tree anymore (gitea repos are public). If either repo goes private, re-add auth via
nix.settings.access-tokensinconfiguration.nix. - Flake inputs:
radiantwavetracks main,radiantwave-devtracks?ref=dev; prod and-devconfigs consume them respectively. Updating them independently is intentional. - SSH keys on machines are inbound-only (
authorizedKeysfor admin access); outbound git is HTTPS. The root key inzero-touch-installer.nixmust stay in sync withmyKeyinconfiguration.nix.
File map
flake.nix— entry point: inputs, builders (mkKioskSystem,mkRpiKioskSystem,mkIso), all system definitions, facter report wiringconfiguration.nix— shared NixOS config (packages, services, kiosk user, auto-upgrade, health check, VM variant)zero-touch-installer.nix— parameterized USB installer module used by all six ISOsdisk-config.nix— NVMe disk layout (NUC)commercial-disk-config.nix— SATA disk layout (commercial HW)rotated_display.nix— portrait display override for Android variantfacter.json— hardware facter report (NUC 14)assets/— logo and splash imageplymouth-theme/— boot splash themetools/find_systems.zsh— subnet sweep for fleet inventory over SSHbuild-rpi.sh— containerized RPi SD-image build helperPLAN-*.md,report.md,timeline.csv,kiosk-url-changes.csv— planning/history notes, not configuration