Files
KioskConfig/flake.nix
T
NeilClack d661162676
Build Dev ISOs / build-dev-android (push) Successful in 1m48s
Build Dev ISOs / build-dev-kiosk (push) Successful in 1m37s
Build Dev ISOs / build-dev-commercial (push) Successful in 1m46s
Add live RadiantWave updater (dev variants)
Add a radiantwave-updater NixOS module that polls a manifest on the
fileserver and swaps the app pointer /var/lib/radiantwave/current to new
closures fetched from the dev Attic cache. Closures are fetched with
'nix copy --from', never built from source; the swap is atomic via
mv -T.

Enable it on the -dev variants only for now: the login shell launches
from /var/lib/radiantwave/current/bin/radiantwave when enabled, and from
the immutable system path otherwise, so prod behavior is unchanged. The
pointer is seeded on first boot to the baseline copy already baked into
the closure (no duplication).
2026-08-27 20:58:07 -05:00

300 lines
12 KiB
Nix

{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
disko.url = "github:nix-community/disko";
disko.inputs.nixpkgs.follows = "nixpkgs";
nixos-facter-modules.url = "github:numtide/nixos-facter-modules";
radiantwave.url = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/radiantwave.git?ref=main";
radiantwave-dev.url = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/radiantwave.git?ref=dev";
nixos-raspberrypi.url = "github:nvmd/nixos-raspberrypi/main";
};
outputs =
{
self,
nixpkgs,
disko,
nixos-facter-modules,
radiantwave,
radiantwave-dev,
nixos-raspberrypi,
...
}@inputs:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
# Plymouth theme: renders the RadiantWave SVG to a full-HD splash.png
# at build time (librsvg), so the theme is hermetic and resolution-
# independent. The .plymouth file's /usr paths are rewritten to $out
# (the NixOS module's initrd fixup rewrites store paths again).
radiantwavePlymouth = pkgs.stdenv.mkDerivation {
pname = "radiantwave-plymouth";
version = "1.0.0";
nativeBuildInputs = [ pkgs.librsvg ];
src = ./assets/RWT-Circular-Color-ForOnDark.svg;
dontUnpack = true;
buildPhase = ''
mkdir -p $out/share/plymouth/themes/radiantwave
rsvg-convert \
--keep-aspect-ratio \
--background-color=#111318 \
--width=1280 \
--height=720 \
--output=$out/share/plymouth/themes/radiantwave/splash.png \
$src
sed 's,/usr/,'"$out"'/,g' ${./plymouth-theme/radiantwave.plymouth} \
> $out/share/plymouth/themes/radiantwave/radiantwave.plymouth
cp ${./plymouth-theme/radiantwave.script} \
$out/share/plymouth/themes/radiantwave/radiantwave.script
'';
};
revision = self.rev or self.dirtyRev or null;
# Live app-update side channel, dev-only for now. The manifest is
# served by the fileserver; closures are fetched (never built) from the
# dev Attic cache. Promotes to prod once validated.
radiantwaveDevUpdaterModule = { baseline }: {
services.radiantwaveUpdater = {
enable = true;
manifestUrl = "https://files.radiantwavetech.com/radiantwave-dev/manifest.json";
atticUrl = "https://attic.radiantwavetech.com/radiantwave-dev";
baselinePackage = baseline;
};
};
mkKioskSystem = {
system,
radiantwave,
upgradeFlakeRef,
hostName,
diskModule,
extraModules ? [],
}:
nixpkgs.lib.nixosSystem {
inherit system;
specialArgs = {
inherit radiantwave;
inherit upgradeFlakeRef;
inherit radiantwavePlymouth;
};
modules = [
{ nixpkgs.config.allowUnfree = true; }
{
networking.hostName = hostName;
system.configurationRevision = revision;
}
./configuration.nix
./radiantwave-updater.nix
disko.nixosModules.disko
diskModule
nixos-facter-modules.nixosModules.facter
# Hardware facter report. This is a NUC 14 report currently
# applied to every x86 variant (including commercial SATA
# hardware). To use per-model reports: generate them on each
# hardware target (procedure in AGENTS.md), commit them as
# facter-<model>.json, and select per variant here, e.g.:
# { facter.reportPath = ./facter-commercial.json; }
{ facter.reportPath = ./facter.json; }
radiantwave.nixosModules.default
] ++ extraModules;
};
mkRpiKioskSystem = {
radiantwave,
upgradeFlakeRef,
hostName,
extraModules ? [],
}:
nixos-raspberrypi.lib.nixosSystem {
specialArgs = {
inherit radiantwave upgradeFlakeRef;
inherit nixos-raspberrypi;
inherit radiantwavePlymouth;
};
modules = [
({ ... }: {
imports = with nixos-raspberrypi.nixosModules; [
sd-image
raspberry-pi-5.base
raspberry-pi-5.page-size-16k
raspberry-pi-5.display-vc4
];
})
./configuration.nix
./radiantwave-updater.nix
radiantwave.nixosModules.default
{
networking.hostName = hostName;
system.configurationRevision = revision;
boot.loader.systemd-boot.enable = nixpkgs.lib.mkForce false;
boot.loader.efi.canTouchEfiVariables = nixpkgs.lib.mkForce false;
boot.loader.raspberry-pi.bootloader = "kernel";
nix.settings.extra-substituters = [
"https://nixos-raspberrypi.cachix.org"
];
nix.settings.extra-trusted-public-keys = [
"nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
];
}
] ++ extraModules;
};
# Zero-touch USB installer image. `targetConfig` names the kiosk system
# to install: the closure comes from the packages output below and the
# partitioning script from the paired disk module, so the ISO always
# installs the matching system for its hardware.
mkIso = { targetConfig, diskModule }:
nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs = {
inherit inputs;
inherit self;
};
modules = [
"${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix"
disko.nixosModules.disko
(import ./zero-touch-installer.nix { inherit targetConfig; })
diskModule
({ pkgs, ... }: {
environment.systemPackages = [
disko.packages.${system}.default
];
isoImage.storeContents = [
self.packages.x86_64-linux.${targetConfig}
];
environment.etc."disko-config.nix".source = diskModule;
})
];
};
in
{
packages.x86_64-linux.radiantwavekiosk = self.nixosConfigurations.radiantwavekiosk.config.system.build.toplevel;
packages.x86_64-linux.radiantwavekiosk-dev = self.nixosConfigurations.radiantwavekiosk-dev.config.system.build.toplevel;
packages.x86_64-linux.radiantwavekiosk-commercial = self.nixosConfigurations.radiantwavekiosk-commercial.config.system.build.toplevel;
packages.x86_64-linux.radiantwavekiosk-commercial-dev = self.nixosConfigurations.radiantwavekiosk-commercial-dev.config.system.build.toplevel;
packages.x86_64-linux.radiantwavekiosk-android = self.nixosConfigurations.radiantwavekiosk-android.config.system.build.toplevel;
packages.x86_64-linux.radiantwavekiosk-android-dev = self.nixosConfigurations.radiantwavekiosk-android-dev.config.system.build.toplevel;
packages.x86_64-linux.radiantwavekiosk-rpi = self.nixosConfigurations.radiantwavekiosk-rpi.config.system.build.toplevel;
packages.x86_64-linux.radiantwavekiosk-rpi-dev = self.nixosConfigurations.radiantwavekiosk-rpi-dev.config.system.build.toplevel;
# Kiosk systems.
#
# Production variants consume the `radiantwave` input (?ref=main);
# `-dev` variants consume `radiantwave-dev` (?ref=dev) and track the
# dev branch of this repo via their autoUpgrade flake refs.
nixosConfigurations = {
radiantwavekiosk = mkKioskSystem {
system = "x86_64-linux";
radiantwave = radiantwave;
hostName = "radiantwavekiosk";
diskModule = ./disk-config.nix;
upgradeFlakeRef = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig.git#radiantwavekiosk";
};
radiantwavekiosk-dev = mkKioskSystem {
system = "x86_64-linux";
radiantwave = radiantwave-dev;
hostName = "radiantwavekiosk-dev";
diskModule = ./disk-config.nix;
upgradeFlakeRef = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig.git?ref=dev#radiantwavekiosk-dev";
extraModules = [
(radiantwaveDevUpdaterModule { baseline = radiantwave-dev.packages.x86_64-linux.default; })
];
};
radiantwavekiosk-commercial = mkKioskSystem {
system = "x86_64-linux";
radiantwave = radiantwave;
hostName = "radiantwavekiosk-commercial";
diskModule = ./commercial-disk-config.nix;
upgradeFlakeRef = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig.git#radiantwavekiosk-commercial";
};
radiantwavekiosk-commercial-dev = mkKioskSystem {
system = "x86_64-linux";
radiantwave = radiantwave-dev;
hostName = "radiantwavekiosk-commercial-dev";
diskModule = ./commercial-disk-config.nix;
upgradeFlakeRef = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig.git?ref=dev#radiantwavekiosk-commercial-dev";
extraModules = [
(radiantwaveDevUpdaterModule { baseline = radiantwave-dev.packages.x86_64-linux.default; })
];
};
# Rotated screen for android-style displays.
radiantwavekiosk-android = mkKioskSystem {
system = "x86_64-linux";
radiantwave = radiantwave;
hostName = "radiantwavekiosk-android";
diskModule = ./disk-config.nix;
upgradeFlakeRef = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig.git#radiantwavekiosk-android";
extraModules = [
./rotated_display.nix
];
};
radiantwavekiosk-android-dev = mkKioskSystem {
system = "x86_64-linux";
radiantwave = radiantwave-dev;
hostName = "radiantwavekiosk-android-dev";
diskModule = ./disk-config.nix;
upgradeFlakeRef = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig.git?ref=dev#radiantwavekiosk-android-dev";
extraModules = [
./rotated_display.nix
(radiantwaveDevUpdaterModule { baseline = radiantwave-dev.packages.x86_64-linux.default; })
];
};
# Raspberry Pi 5.
radiantwavekiosk-rpi = mkRpiKioskSystem {
radiantwave = radiantwave;
hostName = "radiantwavekiosk-rpi";
upgradeFlakeRef = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig.git#radiantwavekiosk-rpi";
};
radiantwavekiosk-rpi-dev = mkRpiKioskSystem {
radiantwave = radiantwave-dev;
hostName = "radiantwavekiosk-rpi-dev";
upgradeFlakeRef = "git+https://gitea.radiantwavetech.com/RadiantWaveTech/KioskConfig.git?ref=dev#radiantwavekiosk-rpi-dev";
extraModules = [
(radiantwaveDevUpdaterModule { baseline = radiantwave-dev.packages.aarch64-linux.default; })
];
};
# === USB Images ===
# Each ISO installs exactly the named system closure using that
# system's disk layout. NVMe layouts pair with ./disk-config.nix,
# SATA with ./commercial-disk-config.nix — don't cross them.
kiosk-iso = mkIso {
targetConfig = "radiantwavekiosk";
diskModule = ./disk-config.nix;
};
commercial-iso = mkIso {
targetConfig = "radiantwavekiosk-commercial";
diskModule = ./commercial-disk-config.nix;
};
android-iso = mkIso {
targetConfig = "radiantwavekiosk-android";
diskModule = ./disk-config.nix;
};
dev-iso = mkIso {
targetConfig = "radiantwavekiosk-dev";
diskModule = ./disk-config.nix;
};
commercial-dev-iso = mkIso {
targetConfig = "radiantwavekiosk-commercial-dev";
diskModule = ./commercial-disk-config.nix;
};
android-dev-iso = mkIso {
targetConfig = "radiantwavekiosk-android-dev";
diskModule = ./disk-config.nix;
};
};
};
}