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).
300 lines
12 KiB
Nix
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;
|
|
};
|
|
};
|
|
};
|
|
}
|