Fix dev/prod split and dev ISOs; consolidate zero-touch installer
- 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
This commit is contained in:
@@ -2,10 +2,19 @@
|
||||
|
||||
## 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 input (from gitea.radiantwavetech.com).
|
||||
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 `radiantwave` input (`?ref=main`) and auto-upgrade from `KioskConfig.git#<config>` on `main`.
|
||||
- `-dev` variants consume the `radiantwave-dev` input (`?ref=dev`) and auto-upgrade from `KioskConfig.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
|
||||
|
||||
```bash
|
||||
@@ -18,7 +27,7 @@ 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
|
||||
# Push build result to Attic cache (not currently wired into any config)
|
||||
attic push kiosk ./result
|
||||
|
||||
# Evaluate available config names
|
||||
@@ -27,48 +36,79 @@ nix eval .#nixosConfigurations --apply builtins.attrNames
|
||||
|
||||
## Config variants
|
||||
|
||||
| Name | Target hardware | Disk device | Notes |
|
||||
| Name | Target hardware | Disk device | App input |
|
||||
|---|---|---|---|
|
||||
| `radiantwavekiosk` | Intel NUC 14 (NVMe) | `/dev/nvme0n1` | Production, uses `radiantwave-legacy` |
|
||||
| `radiantwavekiosk-dev` | Intel NUC 14 (NVMe) | `/dev/nvme0n1` | Dev, uses `radiantwave` `?ref=dev` |
|
||||
| `radiantwavekiosk-commercial` | Commercial HW (SATA) | `/dev/sda` | Production, uses `radiantwave-legacy` |
|
||||
| `radiantwavekiosk-commercial-dev` | Commercial HW (SATA) | `/dev/sda` | Dev, uses `radiantwave` `?ref=dev` |
|
||||
| `radiantwavekiosk-android` | Intel NUC 14 | `/dev/nvme0n1` | + rotated display (portrait), uses `radiantwave-legacy` |
|
||||
| `radiantwavekiosk-rpi` | Raspberry Pi 5 | — | Uses `nixos-raspberrypi`, uses `radiantwave-legacy` |
|
||||
| `radiantwavekiosk-rpi-dev` | Raspberry Pi 5 | — | Dev, uses `radiantwave` `?ref=dev` |
|
||||
| `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) |
|
||||
|
||||
ISOs: `usb-iso`, `commercial-usb-iso`, `android-iso`, `dev-iso` — each bakes in the corresponding system closure for zero-touch install.
|
||||
Every variant sets its own `networking.hostName` (same as the config name) and `system.configurationRevision`, so `tools/find_systems.zsh` can identify fleet members.
|
||||
|
||||
## Branching model
|
||||
### USB images (zero-touch installers)
|
||||
|
||||
Single branch (`main`). Production vs. dev split is at the **flake input** level (`radiantwave-legacy` vs `radiantwave` `?ref=dev`), not at the branch level.
|
||||
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:
|
||||
|
||||
1. Boot that hardware from any NixOS live image (the kiosk installers work).
|
||||
2. With real peripherals attached (display(s), audio), run:
|
||||
```bash
|
||||
sudo nix shell nixpkgs#nixos-facter -c nixos-facter -o facter-<model>.json
|
||||
```
|
||||
3. Commit `facter-<model>.json` to the repo root.
|
||||
4. Wire it up at the marked spot in `flake.nix` (`facter.reportPath` inside `mkKioskSystem`) 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-dev.yml` — triggered by `workflow_dispatch`. Updates `radiantwave` input (dev branch), builds dev closure + ISO, commits updated `flake.lock`. Runs on `build-server`.
|
||||
`.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.nix` uses `/dev/nvme0n1`, `commercial-disk-config.nix` uses `/dev/sda`. Don't mix them up.
|
||||
- **ISO configs reference specific system closures**: `iso-config.nix` hardcodes `radiantwavekiosk`, `dev-iso.nix` hardcodes `radiantwavekiosk-dev`, `commercial-iso-config.nix` hardcodes `radiantwavekiosk-commercial`, `android-iso.nix` hardcodes `radiantwavekiosk-android`. Changing a config name in `flake.nix` requires updating the corresponding ISO config.
|
||||
- **Attic cache token**: ISO configs embed a JWT token for Attic in `/etc/nix/netrc`. If builds fail with auth errors, the token may have expired (expiry in the JWT payload).
|
||||
- **`rotated_display.nix` uses `mkForce`** on `loginShellInit` — it replaces the entire kiosk startup script from `configuration.nix`, don't edit both.
|
||||
- **SOPS**: `.sops.yaml` configures age-based encryption for `secrets.yaml`. You'll need the private key matching `age1t2wpzv...` to decrypt.
|
||||
- **Flake inputs**: `radiantwave` tracks main, `radiantwave-dev` tracks `?ref=dev`. Updating them independently is intentional.
|
||||
- **Disk device differs by variant**: `disk-config.nix` uses `/dev/nvme0n1`, `commercial-disk-config.nix` uses `/dev/sda`. `mkIso` pairs each ISO with the correct layout automatically — keep new ISOs paired correctly.
|
||||
- **Changing a config name** requires updating that config's `upgradeFlakeRef` in `flake.nix` (it embeds the name).
|
||||
- **`rotated_display.nix` uses `mkForce`** on `loginShellInit` — it replaces the entire kiosk startup script from `configuration.nix`; don't edit both.
|
||||
- **Auto-update**: `system.autoUpgrade` runs every 10 min (`*:00/10`) with `--refresh`, operation `switch`, no auto-reboot. A `radiantwave-backup` rsync runs before each attempt. The health-check/rollback service is written but commented out in `configuration.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-tokens` in `configuration.nix`.
|
||||
- **Flake inputs**: `radiantwave` tracks main, `radiantwave-dev` tracks `?ref=dev`; prod and `-dev` configs consume them respectively. Updating them independently is intentional.
|
||||
- **SSH keys on machines are inbound-only** (`authorizedKeys` for admin access); outbound git is HTTPS. The root key in `zero-touch-installer.nix` must stay in sync with `myKey` in `configuration.nix`.
|
||||
|
||||
## File map
|
||||
|
||||
- `flake.nix` — all system definitions, entry point
|
||||
- `flake.nix` — entry point: inputs, builders (`mkKioskSystem`, `mkRpiKioskSystem`, `mkIso`), all system definitions, facter report wiring
|
||||
- `configuration.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 ISOs
|
||||
- `disk-config.nix` — NVMe disk layout (NUC)
|
||||
- `commercial-disk-config.nix` — SATA disk layout (commercial HW)
|
||||
- `iso-config.nix` — production ISO + zero-touch installer
|
||||
- `dev-iso.nix` — dev ISO + zero-touch installer
|
||||
- `commercial-iso-config.nix` — commercial ISO + zero-touch installer
|
||||
- `android-iso.nix` — android ISO + zero-touch installer
|
||||
- `rotated_display.nix` — portrait display override for Android variant
|
||||
- `facter.json` — hardware facter report (NUC 14)
|
||||
- `14rvk.json`, `pn54.json` — additional hardware facter reports
|
||||
- `assets/` — logo and splash image
|
||||
- `plymouth-theme/` — boot splash theme
|
||||
- `commands.md` — quick-reference for build/deploy commands
|
||||
- `tools/find_systems.zsh` — subnet sweep for fleet inventory over SSH
|
||||
- `build-rpi.sh` — containerized RPi SD-image build helper
|
||||
- `PLAN-*.md`, `report.md`, `timeline.csv`, `kiosk-url-changes.csv` — planning/history notes, not configuration
|
||||
|
||||
Reference in New Issue
Block a user