init new repo
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# This workflow generates dev-iso any time RadiantWave is updated.
|
||||
# When RadiantWave recieves a PR, a workflow is triggered that builds
|
||||
# the application. If that succeeds, then this workflow is triggered
|
||||
# to build the dev-iso for testing on a dev machine. The iso image is
|
||||
# spit into /ssd/radiantwave/builds/ and is timestamped.
|
||||
#
|
||||
# This action is not meant to be run any time code is pushed to
|
||||
# KioskConfig, instead, it is strictly a "response" action.
|
||||
#
|
||||
# Remember: KioskConfig only has the main branch, because
|
||||
# the split between production and development happens
|
||||
# at the system closure level, not at the branch level of
|
||||
# this repository.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
types:
|
||||
- radiantwave-dev-built
|
||||
jobs:
|
||||
update-and-build:
|
||||
runs-on: neils-server-runner
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
token: ${{ secrets.TOKEN }}
|
||||
|
||||
- name: Update rhemawave-dev
|
||||
run: |
|
||||
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
|
||||
nix flake update rhemawave-dev
|
||||
|
||||
# This builds the system closure
|
||||
- name: Build dev VM
|
||||
run: |
|
||||
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
|
||||
nix build -L .#nixosConfigurations.rhemawavekiosk-dev.config.system.build.toplevel
|
||||
|
||||
# If the closure builds, it's valid, even if incorrect and something is wrong.
|
||||
# That's why we build the ISO next, even for the dev branch, for testing
|
||||
- name: Build dev ISO
|
||||
run: |
|
||||
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
|
||||
nix build -L .#nixosConfigurations.dev-iso.config.system.build.isoImage
|
||||
cp -rL result/iso/*.iso /ssd/radiantwave/build/radiantwave-kiosk-iso-dev-$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
- name: Commit updated flake.lock
|
||||
run: |
|
||||
git config user.email "ci@radiantwavetech.com"
|
||||
git config user.name "RadiantWave CI"
|
||||
git remote set-url origin https://oauth2:${{ secrets.FORGEJO_TOKEN }}@codeberg.org/RhemaWave-Technologies/KioskConfig.git
|
||||
git add flake.lock
|
||||
git commit -m "chore: update rhemawave-dev to latest dev" || echo "Nothing to commit"
|
||||
git push
|
||||
|
||||
- name: Notify
|
||||
if: always()
|
||||
uses: https://github.com/dawidd6/action-send-mail@v3
|
||||
with:
|
||||
server_address: smtp.gmail.com
|
||||
server_port: 465
|
||||
username: ${{ secrets.MAIL_USERNAME }}
|
||||
password: ${{ secrets.MAIL_PASSWORD }}
|
||||
subject: "${{ job.status == 'success' && '✅' || '❌' }} KioskConfig dev build ${{ job.status }}"
|
||||
to: cnclack@pm.me
|
||||
from: ci@radiantwavetech.com
|
||||
body: "KioskConfig dev build ${{ job.status }} — rhemawave-dev updated and arstifacts copied to /ssd/radiantwave/build/"
|
||||
@@ -0,0 +1,6 @@
|
||||
result
|
||||
result-*
|
||||
build/out/
|
||||
.direnv
|
||||
wifi-psk.txt
|
||||
*.qcow2
|
||||
@@ -0,0 +1,7 @@
|
||||
keys:
|
||||
- &primary age1t2wpzv5rj8uqcfhev3zw4zkhckayumfahjvqwamjrn9724u6vf6qp2ayld
|
||||
creation_rules:
|
||||
- path_regex: secrets.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *primary
|
||||
+4300
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
# 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 `rhemawave` flake input (from Codeberg).
|
||||
|
||||
Hosted on Codeberg: `https://codeberg.org/RhemaWave-Technologies/KioskConfig`
|
||||
|
||||
## Key commands
|
||||
|
||||
```bash
|
||||
# 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
|
||||
attic push kiosk ./result
|
||||
|
||||
# Evaluate available config names
|
||||
nix eval .#nixosConfigurations --apply builtins.attrNames
|
||||
```
|
||||
|
||||
## Config variants
|
||||
|
||||
| Name | Target hardware | Disk device | Notes |
|
||||
|---|---|---|---|
|
||||
| `rhemawavekiosk` | Intel NUC 14 (NVMe) | `/dev/nvme0n1` | Production, uses `rhemawave` main |
|
||||
| `rhemawavekiosk-dev` | Intel NUC 14 (NVMe) | `/dev/nvme0n1` | Dev, uses `rhemawave-dev` ref |
|
||||
| `rhemawavekiosk-commercial` | Commercial HW (SATA) | `/dev/sda` | Production |
|
||||
| `rhemawavekiosk-commercial-dev` | Commercial HW (SATA) | `/dev/sda` | Dev |
|
||||
| `rhemawavekiosk-android` | Intel NUC 14 | `/dev/nvme0n1` | + rotated display (portrait) |
|
||||
| `rhemawavekiosk-rpi` | Raspberry Pi 5 | — | Uses `nixos-raspberrypi` |
|
||||
| `rhemawavekiosk-rpi-dev` | Raspberry Pi 5 | — | Dev, uses `rhemawave-dev` |
|
||||
|
||||
ISOs: `usb-iso`, `commercial-usb-iso`, `android-iso`, `dev-iso` — each bakes in the corresponding system closure for zero-touch install.
|
||||
|
||||
## Branching model
|
||||
|
||||
Single branch (`main`). Production vs. dev split is at the **flake input** level (`rhemawave` vs `rhemawave-dev`), not at the branch level.
|
||||
|
||||
## CI (Forgejo)
|
||||
|
||||
`.forgejo/workflows/build-dev.yml` — triggered by `repository_dispatch` (`radiantwave-dev-built`) from the RadiantWave repo. Updates `rhemawave-dev` input, builds dev closure + ISO, commits updated `flake.lock`. Runs on `neils-server-runner`.
|
||||
|
||||
## 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 `rhemawavekiosk`, `dev-iso.nix` hardcodes `rhemawavekiosk-dev`, `commercial-iso-config.nix` hardcodes `rhemawavekiosk-commercial`. 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**: `rhemawave` tracks main, `rhemawave-dev` tracks `?ref=dev`. Updating them independently is intentional.
|
||||
|
||||
## File map
|
||||
|
||||
- `flake.nix` — all system definitions, entry point
|
||||
- `configuration.nix` — shared NixOS config (packages, services, kiosk user, auto-upgrade, health check, VM variant)
|
||||
- `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
|
||||
- `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
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 89 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
CONFIG="rhemawavekiosk-rpi"
|
||||
VARIANT=""
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--dev) CONFIG="rhemawavekiosk-rpi-dev"; VARIANT="-dev" ;;
|
||||
*) echo "Unknown arg: $arg"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
TIMESTAMP=$(date +"%m%d%Y-%H%M")
|
||||
FILENAME="radiantwave-kiosk-rpi${VARIANT}_${TIMESTAMP}.img.zst"
|
||||
REPO="$(pwd)"
|
||||
NIX_STORE="kiosk-nix-store"
|
||||
|
||||
echo "==> Building ${CONFIG}..."
|
||||
echo "==> Output: ${REPO}/${FILENAME}"
|
||||
echo ""
|
||||
|
||||
podman volume create "${NIX_STORE}" 2>/dev/null || true
|
||||
|
||||
podman run --rm \
|
||||
-v "${REPO}:/repo" \
|
||||
-v "${NIX_STORE}:/nix/store" \
|
||||
-w /repo \
|
||||
nixos/nix:latest \
|
||||
sh -c '
|
||||
set -ex
|
||||
mkdir -p /etc/nix
|
||||
echo "experimental-features = nix-command flakes" > /etc/nix/nix.conf
|
||||
echo "accept-flake-config = true" >> /etc/nix/nix.conf
|
||||
echo "extra-substituters = https://cache.nixos.org https://nixos-raspberrypi.cachix.org" >> /etc/nix/nix.conf
|
||||
echo "extra-trusted-public-keys = nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI=" >> /etc/nix/nix.conf
|
||||
echo "max-jobs = 4" >> /etc/nix/nix.conf
|
||||
|
||||
echo "==> Building sdImage (first run slow, cached after)..."
|
||||
nix --accept-flake-config build \
|
||||
.#nixosConfigurations.'${CONFIG}'.config.system.build.sdImage \
|
||||
--fallback \
|
||||
--print-build-logs
|
||||
|
||||
echo "==> Build complete, copying..."
|
||||
cp result/sd-image/*.img* /repo/'${FILENAME}'
|
||||
echo "==> Done: ${FILENAME}"
|
||||
ls -lh /repo/'${FILENAME}'
|
||||
'
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
Build ISO installer
|
||||
nix build .#nixosConfigurations.installer-iso.config.system.build.isoImage
|
||||
|
||||
Build kiosk system and push to Attic cache
|
||||
nix build .#nixosConfigurations.rhemawavekiosk.config.system.build.toplevel
|
||||
attic push kiosk ./result
|
||||
|
||||
Deploy to a specific kiosk over SSH
|
||||
nixos-rebuild switch --flake .#rhemawavekiosk --target-host root@<host>
|
||||
|
||||
---
|
||||
|
||||
## How these build paths work
|
||||
|
||||
The build commands follow the flake output attribute tree. Start with `flake.nix`:
|
||||
|
||||
```nix
|
||||
nixosConfigurations = {
|
||||
rhemawavekiosk = nixpkgs.lib.nixosSystem { ... }; # production machine
|
||||
installer-iso = nixpkgs.lib.nixosSystem { ... }; # USB installer
|
||||
};
|
||||
```
|
||||
|
||||
Each `nixosConfiguration` is a full NixOS system. You access what you want to build
|
||||
by walking the attribute tree with dots:
|
||||
|
||||
```
|
||||
.#nixosConfigurations.<name>.config.system.build.<target>
|
||||
│ │ │ │
|
||||
│ │ │ └─ what to build:
|
||||
│ │ │ toplevel = full system closure
|
||||
│ │ │ isoImage = bootable ISO
|
||||
│ │ │
|
||||
│ │ └─ name from flake.nix (rhemawavekiosk, installer-iso)
|
||||
│ │
|
||||
│ └─ nixosConfigurations = standard flake output for NixOS systems
|
||||
│
|
||||
└─ .# = "this flake, attribute..."
|
||||
```
|
||||
|
||||
You can explore what's available with:
|
||||
nix eval .#nixosConfigurations --apply builtins.attrNames
|
||||
nix eval .#nixosConfigurations.rhemawavekiosk.config.system.build --apply builtins.attrNames
|
||||
@@ -0,0 +1,44 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
disko.devices = {
|
||||
disk.disk1 = {
|
||||
device = lib.mkDefault "/dev/sda";
|
||||
type = "disk";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
name = "boot";
|
||||
size = "1M";
|
||||
type = "EF00";
|
||||
};
|
||||
esp = {
|
||||
name = "ESP";
|
||||
size = "500M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
extraArgs = [ "-n" "EFIBOOT" ];
|
||||
};
|
||||
};
|
||||
root = {
|
||||
name = "root";
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "xfs";
|
||||
mountpoint = "/";
|
||||
extraArgs = [ "-L" "nixos" ];
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
"pquota"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
let
|
||||
# TODO: Parameterize this to combine with iso-config.nix
|
||||
# Currently hardcoded to rhemawavekiosk-commercial; should accept target config as param
|
||||
targetSystem =
|
||||
self.nixosConfigurations.rhemawavekiosk-commercial.config.system.build.toplevel;
|
||||
|
||||
diskoScript =
|
||||
self.nixosConfigurations.rhemawavekiosk-commercial.config.system.build.diskoScript;
|
||||
in
|
||||
{
|
||||
nix.settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
|
||||
substituters = [
|
||||
"https://cache.nixos.org"
|
||||
];
|
||||
|
||||
flake-registry = "";
|
||||
};
|
||||
|
||||
nix.registry.nixpkgs = pkgs.lib.mkForce {
|
||||
to = {
|
||||
type = "path";
|
||||
path = "${inputs.nixpkgs}";
|
||||
};
|
||||
};
|
||||
|
||||
environment.variables.KIOSK_FLAKE = "${self}";
|
||||
|
||||
virtualisation.vmVariant = {
|
||||
virtualisation.memorySize = 8096;
|
||||
virtualisation.diskSize = 100000;
|
||||
virtualisation.cores = 4;
|
||||
virtualisation.qemu.options = [
|
||||
# "-nic none"
|
||||
];
|
||||
virtualisation.forwardPorts = [
|
||||
{ from = "host"; host.port = 2222; guest.port = 22; }
|
||||
];
|
||||
};
|
||||
|
||||
environment.etc."nix/netrc" = {
|
||||
text = ''
|
||||
password eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjIwODgzODk2ODEsIm5iZiI6MTc3MjgxMzY4MSwic3ViIjoia2lvc2siLCJodHRwczovL2p3dC5hdHRpYy5ycy92MSI6eyJjYWNoZXMiOnsia2lvc2siOnsiciI6MX19fX0.N6Ktrmmu1LSy2PP8uNF25VHRP1dxPZJ4M0MR1kUpVi0
|
||||
'';
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
nix.extraOptions = ''
|
||||
netrc-file = /etc/nix/netrc
|
||||
'';
|
||||
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
systemd.services.NetworkManager-wait-online.enable = false;
|
||||
|
||||
nix.settings.connect-timeout = 0;
|
||||
|
||||
services.openssh.enable = true;
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB4vXx7sOOVAyxdS/N1LEI+L8wYICf+gbzs6Kz7K8Je5 cnclack@pm.me:Thinkpad"
|
||||
];
|
||||
|
||||
systemd.services.zero-touch-install = {
|
||||
description = "Zero-Touch Kiosk Installation";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
wants = [ ];
|
||||
after = [ "systemd-udev-settle.service" ];
|
||||
|
||||
path = with pkgs; [
|
||||
nix
|
||||
git
|
||||
util-linux
|
||||
nixos-install-tools
|
||||
curl
|
||||
networkmanager
|
||||
mount
|
||||
umount
|
||||
disko
|
||||
];
|
||||
|
||||
environment = {
|
||||
NIX_PATH = "nixpkgs=${inputs.nixpkgs}";
|
||||
KIOSK_FLAKE = "${self}";
|
||||
DISKO_SCRIPT = "${diskoScript}";
|
||||
};
|
||||
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
echo "Running disko script..."
|
||||
echo "Script: $DISKO_SCRIPT"
|
||||
|
||||
${diskoScript}
|
||||
|
||||
echo "Installing RhemaWave"
|
||||
echo "Closure Path: ${targetSystem}"
|
||||
|
||||
nixos-install \
|
||||
--system "${targetSystem}" \
|
||||
--no-root-passwd \
|
||||
--no-channel-copy
|
||||
|
||||
# Redirect to console and show completion message
|
||||
exec > /dev/tty1 2>&1
|
||||
echo ""
|
||||
echo "============================================="
|
||||
echo " Installation complete!"
|
||||
echo ""
|
||||
echo " Please remove the USB drive and reboot."
|
||||
echo "============================================="
|
||||
|
||||
# Wait indefinitely for user action
|
||||
sleep infinity
|
||||
''; };
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
{ pkgs, rhemawave, upgradeFlakeRef, ... }:
|
||||
|
||||
let
|
||||
rhemaApp = rhemawave.packages.${pkgs.system}.default;
|
||||
myKey = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB4vXx7sOOVAyxdS/N1LEI+L8wYICf+gbzs6Kz7K8Je5 cnclack@pm.me:Thinkpad" ];
|
||||
in
|
||||
{
|
||||
# Included packages
|
||||
environment.systemPackages = [
|
||||
pkgs.cage pkgs.rsync pkgs.dbus pkgs.mesa pkgs.git pkgs.tailscale pkgs.sqlite
|
||||
rhemaApp
|
||||
];
|
||||
|
||||
# This populates the EFI partition and tells the NUC how to start NixOS.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
# Hardware-specific: NUC 14 needs these for the NVMe and Graphics
|
||||
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "i915" "drm" "drm_kms_helper" ];
|
||||
boot.kernelParams = [ "quiet" "splash" ];
|
||||
|
||||
# --- Essential Services ---
|
||||
services.pipewire = { enable = true; alsa.enable = true; pulse.enable = true; };
|
||||
services.seatd.enable = true;
|
||||
services.openssh.enable = true;
|
||||
services.openssh.settings.PermitRootLogin = "prohibit-password";
|
||||
hardware.graphics.enable = true;
|
||||
system.autoUpgrade = {
|
||||
enable = true;
|
||||
flake = upgradeFlakeRef;
|
||||
dates = "*:00/10";
|
||||
flags = [ "--refresh" "-L" ];
|
||||
operation = "switch";
|
||||
};
|
||||
time.timeZone = "America/Chicago";
|
||||
|
||||
# Networking Network-Manager
|
||||
services.resolved.enable = false;
|
||||
networking.networkmanager.enable = true;
|
||||
systemd.services.NetworkManager-wait-online.enable = false;
|
||||
systemd.network.wait-online.enable = false;
|
||||
|
||||
# --- Users & SSH Keys ---
|
||||
users.users.root.openssh.authorizedKeys.keys = myKey;
|
||||
users.users.kiosk = {
|
||||
isNormalUser = true;
|
||||
uid = 1000;
|
||||
extraGroups = ["audio" "video" "input" "networkmanager" "wheel"];
|
||||
openssh.authorizedKeys.keys = myKey;
|
||||
password = "Fuckp@ssw0rds";
|
||||
};
|
||||
services.getty.autologinUser = "kiosk";
|
||||
|
||||
# --- Set ownership of Radiantwave files ---
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /home/kiosk/.local/share/rhemawave 0770 kiosk kiosk -"
|
||||
];
|
||||
|
||||
system.activationScripts.cleanRadiantFiles = ''
|
||||
rm -rf /home/kiosk/.local/share/rhemawave/audio
|
||||
'';
|
||||
|
||||
# --- Backup service: runs before nixos-upgrade ---
|
||||
systemd.services.rhemawave-backup = {
|
||||
description = "Backup RadiantWave user data before upgrade";
|
||||
before = [ "nixos-upgrade.service" ];
|
||||
wantedBy = [ "nixos-upgrade.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "kiosk";
|
||||
};
|
||||
script = ''
|
||||
BACKUP_DIR="/home/kiosk/.local/share/rhemawave-backup"
|
||||
SOURCE_DIR="/home/kiosk/.local/share/rhemawave"
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
${pkgs.rsync}/bin/rsync -a \
|
||||
--exclude='audio/' \
|
||||
"$SOURCE_DIR/" "$BACKUP_DIR/"
|
||||
|
||||
echo "Backup completed at $(date)" > "$BACKUP_DIR/.backup-timestamp"
|
||||
'';
|
||||
};
|
||||
|
||||
# --- Health check service: runs after nixos-upgrade ---
|
||||
systemd.services.rhemawave-healthcheck = {
|
||||
description = "Verify RadiantWave is running after upgrade, rollback if not";
|
||||
after = [ "nixos-upgrade.service" ];
|
||||
wantedBy = [ "nixos-upgrade.service" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
# Give cage time to start rhemawave after the switch
|
||||
ExecStartPre = "${pkgs.coreutils}/bin/sleep 90";
|
||||
};
|
||||
script = ''
|
||||
if ${pkgs.procps}/bin/pgrep -x rhemawave > /dev/null; then
|
||||
echo "RadiantWave is running, upgrade successful"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "RadiantWave not found after upgrade, rolling back..."
|
||||
|
||||
# Roll back to previous NixOS generation
|
||||
/run/current-system/sw/bin/nixos-rebuild switch --rollback
|
||||
|
||||
echo "Rollback completed at $(date)"
|
||||
'';
|
||||
};
|
||||
|
||||
# --- 3. The Kiosk Startup Script ---
|
||||
environment.loginShellInit = ''
|
||||
if [ "$(tty)" = "/dev/tty1" ]; then
|
||||
export GODEBUG=netdns=cgo
|
||||
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
# Smart Network Wait
|
||||
for i in {1..10}; do
|
||||
if ${pkgs.iputils}/bin/ping -c 1 8.8.8.8 &> /dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# Graphics fixes
|
||||
export SDL_VIDEODRIVER=wayland
|
||||
export QT_QPA_PLATFORM=wayland
|
||||
export XDG_SESSION_TYPE=wayland
|
||||
export WLR_RENDERER=pixman
|
||||
export WLR_NO_HARDWARE_CURSORS=1
|
||||
|
||||
# Asset sync + start app
|
||||
mkdir -p /home/kiosk/.local/share/rhemawave
|
||||
${pkgs.rsync}/bin/rsync -ru ${rhemaApp}/share/rhemawave/ /home/kiosk/.local/share/rhemawave/
|
||||
|
||||
exec dbus-run-session cage -- ${rhemaApp}/bin/rhemawave -d -s > /tmp/kiosk.log 2>&1
|
||||
fi
|
||||
'';
|
||||
|
||||
# # Tailscale Configuration
|
||||
# systemd.tmpfiles.rules = [
|
||||
# "d /etc/tailscale 0700 root root -"
|
||||
# "f /etc/tailscale/preauth-key 0600 root root - ${preAuthKey}"
|
||||
# ];
|
||||
|
||||
# services.tailscale = {
|
||||
# enable = true;
|
||||
# authKeyFile = "/etc/tailscale/preauth-key";
|
||||
# openFirewall = true;
|
||||
# authKeyParameters.preauthorized = true;
|
||||
# extraUpFlags = [
|
||||
# "--login-server" headscaleUrl
|
||||
# ];
|
||||
# };
|
||||
|
||||
# systemd.services.tailscale-set-hostname = {
|
||||
# description = "Set Tailscale hostname based on the RhemaWave license key";
|
||||
# after = [ "tailscale-autoconnect.service" ];
|
||||
# wants = [ "tailscaled.service" ];
|
||||
# wantedBy = [ "multi-user.target" ];
|
||||
# serviceConfig = {
|
||||
# Type = "oneshot";
|
||||
# RemainAfterExit = true;
|
||||
# };
|
||||
# script = ''
|
||||
# if [ -f "${licenseKeyFile}" ]; then
|
||||
# KEY=$(cat "${licenseKeyFile}" | tr -d '[:space:]')
|
||||
# if [ -n "$KEY" ]; then
|
||||
# echo "Setting Tailscale hostname to: $KEY"
|
||||
# ${pkgs.lib.getExe pkgs.tailscale} set --hostname="$KEY"
|
||||
# exit 0
|
||||
# fi
|
||||
# fi
|
||||
# echo "No license key found, skipping hostname override"
|
||||
# '';
|
||||
# };
|
||||
|
||||
# Virtual machine declaration
|
||||
virtualisation.vmVariant = {
|
||||
boot.loader.systemd-boot.enable = pkgs.lib.mkForce false;
|
||||
boot.loader.efi.canTouchEfiVariables = pkgs.lib.mkForce false;
|
||||
virtualisation.forwardPorts = [
|
||||
{ from = "host"; host.port = 2222; guest.port = 22; }
|
||||
];
|
||||
virtualisation.qemu.options = [
|
||||
"-device intel-hda"
|
||||
"-device hda-duplex"
|
||||
"-vga virtio"
|
||||
];
|
||||
virtualisation = {
|
||||
cores = 8;
|
||||
memorySize = 8192;
|
||||
};
|
||||
services.logrotate.enable = false;
|
||||
};
|
||||
virtualisation.diskSize = 10485760;
|
||||
|
||||
# NixOS settings.
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
nix.settings.accept-flake-config = true;
|
||||
system.stateVersion = "24.05";
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
let
|
||||
targetSystem =
|
||||
self.nixosConfigurations.rhemawavekiosk-dev.config.system.build.toplevel;
|
||||
|
||||
# 🔧 FIX: prebuilt disko script (restores v1.0.1 behavior)
|
||||
diskoScript =
|
||||
self.nixosConfigurations.rhemawavekiosk-dev.config.system.build.diskoScript;
|
||||
in
|
||||
{
|
||||
nix.settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
|
||||
# 🔧 FIX: restore cache (prevents massive rebuild/download cascade)
|
||||
substituters = [
|
||||
"https://cache.nixos.org"
|
||||
];
|
||||
|
||||
flake-registry = "";
|
||||
};
|
||||
|
||||
nix.registry.nixpkgs = pkgs.lib.mkForce {
|
||||
to = {
|
||||
type = "path";
|
||||
path = "${inputs.nixpkgs}";
|
||||
};
|
||||
};
|
||||
|
||||
environment.variables.KIOSK_FLAKE = "${self}";
|
||||
|
||||
virtualisation.vmVariant = {
|
||||
virtualisation.memorySize = 8096;
|
||||
virtualisation.diskSize = 100000;
|
||||
virtualisation.cores = 4;
|
||||
virtualisation.qemu.options = [
|
||||
# "-nic none"
|
||||
];
|
||||
virtualisation.forwardPorts = [
|
||||
{ from = "host"; host.port = 2222; guest.port = 22; }
|
||||
];
|
||||
};
|
||||
|
||||
environment.etc."nix/netrc" = {
|
||||
text = ''
|
||||
password eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjIwODgzODk2ODEsIm5iZiI6MTc3MjgxMzY4MSwic3ViIjoia2lvc2siLCJodHRwczovL2p3dC5hdHRpYy5ycy92MSI6eyJjYWNoZXMiOnsia2lvc2siOnsiciI6MX19fX0.N6Ktrmmu1LSy2PP8uNF25VHRP1dxPZJ4M0MR1kUpVi0
|
||||
'';
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
nix.extraOptions = ''
|
||||
netrc-file = /etc/nix/netrc
|
||||
'';
|
||||
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
systemd.services.NetworkManager-wait-online.enable = false;
|
||||
|
||||
nix.settings.connect-timeout = 0;
|
||||
|
||||
services.openssh.enable = true;
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB4vXx7sOOVAyxdS/N1LEI+L8wYICf+gbzs6Kz7K8Je5 cnclack@pm.me:Thinkpad"
|
||||
];
|
||||
|
||||
systemd.services.zero-touch-install = {
|
||||
description = "Zero-Touch Kiosk Installation";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
# 🔧 FIX: remove runtime network dependency
|
||||
wants = [ ];
|
||||
after = [ "systemd-udev-settle.service" ];
|
||||
|
||||
path = with pkgs; [
|
||||
nix
|
||||
git
|
||||
util-linux
|
||||
nixos-install-tools
|
||||
curl
|
||||
networkmanager
|
||||
mount
|
||||
umount
|
||||
disko
|
||||
];
|
||||
|
||||
environment = {
|
||||
NIX_PATH = "nixpkgs=${inputs.nixpkgs}";
|
||||
KIOSK_FLAKE = "${self}";
|
||||
DISKO_SCRIPT = "${diskoScript}";
|
||||
};
|
||||
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
DISK=/dev/vda
|
||||
|
||||
echo "Running disko script..."
|
||||
echo "Script: $DISKO_SCRIPT"
|
||||
|
||||
# 🔧 FIX: use prebuilt script instead of runtime disko eval
|
||||
${diskoScript}
|
||||
|
||||
echo "Installing RhemaWave"
|
||||
echo "Closure Path: ${targetSystem}"
|
||||
|
||||
nixos-install \
|
||||
--system "${targetSystem}" \
|
||||
--no-root-passwd \
|
||||
--no-channel-copy
|
||||
|
||||
echo "============================================"
|
||||
echo " Installation complete!"
|
||||
echo " Rebooting in 5 seconds..."
|
||||
echo "============================================"
|
||||
sleep 5
|
||||
systemctl reboot --force
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
disko.devices = {
|
||||
disk.disk1 = {
|
||||
device = lib.mkDefault "/dev/nvme0n1";
|
||||
type = "disk";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
name = "boot";
|
||||
size = "1M";
|
||||
type = "EF00";
|
||||
};
|
||||
esp = {
|
||||
name = "ESP";
|
||||
size = "500M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
extraArgs = [ "-n" "EFIBOOT" ];
|
||||
};
|
||||
};
|
||||
root = {
|
||||
name = "root";
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "xfs";
|
||||
mountpoint = "/";
|
||||
extraArgs = [ "-L" "nixos" ];
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
"pquota"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
+4549
File diff suppressed because it is too large
Load Diff
Generated
+299
@@ -0,0 +1,299 @@
|
||||
{
|
||||
"nodes": {
|
||||
"argononed": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1729566243,
|
||||
"narHash": "sha256-DPNI0Dpk5aym3Baf5UbEe5GENDrSmmXVdriRSWE+rgk=",
|
||||
"owner": "nvmd",
|
||||
"repo": "argononed",
|
||||
"rev": "16dbee54d49b66d5654d228d1061246b440ef7cf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nvmd",
|
||||
"repo": "argononed",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"disko": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1781152676,
|
||||
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"locked": {
|
||||
"lastModified": 1767039857,
|
||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"inputs": {
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-facter-modules": {
|
||||
"locked": {
|
||||
"lastModified": 1773858690,
|
||||
"narHash": "sha256-oW0/lC0oRG5H5LaK6Rmh9L1wmkn9TbenM4bXwnIEDKA=",
|
||||
"owner": "numtide",
|
||||
"repo": "nixos-facter-modules",
|
||||
"rev": "139dcef4dfc97009629c445806f197883351ab4a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "nixos-facter-modules",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-images": {
|
||||
"inputs": {
|
||||
"nixos-stable": [
|
||||
"nixos-raspberrypi",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixos-unstable": [
|
||||
"nixos-raspberrypi",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1747747741,
|
||||
"narHash": "sha256-LUOH27unNWbGTvZFitHonraNx0JF/55h30r9WxqrznM=",
|
||||
"owner": "nvmd",
|
||||
"repo": "nixos-images",
|
||||
"rev": "cbbd6db325775096680b65e2a32fb6187c09bbb4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nvmd",
|
||||
"ref": "sdimage-installer",
|
||||
"repo": "nixos-images",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-raspberrypi": {
|
||||
"inputs": {
|
||||
"argononed": "argononed",
|
||||
"flake-compat": "flake-compat",
|
||||
"nixos-images": "nixos-images",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1779023229,
|
||||
"narHash": "sha256-MInilg7B/06c34SwOuGSBho4l0H1EZcmvxTkSWCs5pE=",
|
||||
"owner": "nvmd",
|
||||
"repo": "nixos-raspberrypi",
|
||||
"rev": "06c6e3513e1ee64b651913193fc6ac38aa4963f5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nvmd",
|
||||
"ref": "main",
|
||||
"repo": "nixos-raspberrypi",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1778737229,
|
||||
"narHash": "sha256-6xWoytx8jFW4PF1GjRm/i/53trbpKGfz6zjzQGBr4cI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "d7a713c0b7e47c908258e71cba7a2d77cc8d71d5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-25.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1782175435,
|
||||
"narHash": "sha256-EMzXKmnOtBQ2MnvpiNOm7E+kOMvdPrIKaeg52Tip2Uk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "89570f24e97e614aa34aa9ab1c927b6578a43775",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1776877367,
|
||||
"narHash": "sha256-EHq1/OX139R1RvBzOJ0aMRT3xnWyqtHBRUBuO1gFzjI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0726a0ecb6d4e08f6adced58726b95db924cef57",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1776877367,
|
||||
"narHash": "sha256-EHq1/OX139R1RvBzOJ0aMRT3xnWyqtHBRUBuO1gFzjI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0726a0ecb6d4e08f6adced58726b95db924cef57",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"rhemawave": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1782591778,
|
||||
"narHash": "sha256-Aw9vAwpKkaSbreK3KlfRygV+pez0l61vBGvNdYqdEpM=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "9f8212cf550b7c2cb1f41e5540cc6e68be62ee72",
|
||||
"revCount": 189,
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/RhemaWave-Technologies/RhemaWave.git"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/RhemaWave-Technologies/RhemaWave.git"
|
||||
}
|
||||
},
|
||||
"rhemawave-dev": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs_4"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1783810010,
|
||||
"narHash": "sha256-LGEvcPYqIenopOSCg/GzvXPF1dJCtqTwd5rJQDLAfvg=",
|
||||
"ref": "dev",
|
||||
"rev": "cbb10ecda31f855fedd6034a7f2040c1a65f1e17",
|
||||
"revCount": 226,
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/RhemaWave-Technologies/RhemaWave.git"
|
||||
},
|
||||
"original": {
|
||||
"ref": "dev",
|
||||
"type": "git",
|
||||
"url": "https://codeberg.org/RhemaWave-Technologies/RhemaWave.git"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"disko": "disko",
|
||||
"nixos-facter-modules": "nixos-facter-modules",
|
||||
"nixos-raspberrypi": "nixos-raspberrypi",
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"rhemawave": "rhemawave",
|
||||
"rhemawave-dev": "rhemawave-dev"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
{
|
||||
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";
|
||||
rhemawave.url = "git+https://codeberg.org/RhemaWave-Technologies/RhemaWave.git";
|
||||
rhemawave-dev.url = "git+https://codeberg.org/RhemaWave-Technologies/RhemaWave.git?ref=dev";
|
||||
nixos-raspberrypi.url = "github:nvmd/nixos-raspberrypi/main";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
disko,
|
||||
nixos-facter-modules,
|
||||
rhemawave,
|
||||
rhemawave-dev,
|
||||
nixos-raspberrypi,
|
||||
...
|
||||
}@inputs:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
|
||||
mkKioskSystem = { system, rhemawave, upgradeFlakeRef, extraModules ? [], diskModule, enableAutoUpgrade ? true, extraSpecialArgs ? {}}:
|
||||
nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
|
||||
specialArgs = {
|
||||
inherit rhemawave;
|
||||
inherit upgradeFlakeRef;
|
||||
} // extraSpecialArgs;
|
||||
|
||||
modules = [
|
||||
./configuration.nix
|
||||
disko.nixosModules.disko
|
||||
diskModule
|
||||
nixos-facter-modules.nixosModules.facter
|
||||
{ facter.reportPath = ./facter.json; }
|
||||
rhemawave.nixosModules.default
|
||||
] ++ extraModules;
|
||||
};
|
||||
|
||||
mkRpiKioskSystem = { rhemawave, upgradeFlakeRef, extraModules ? [], enableAutoUpgrade ? true }:
|
||||
nixos-raspberrypi.lib.nixosSystem {
|
||||
specialArgs = {
|
||||
inherit rhemawave upgradeFlakeRef;
|
||||
inherit nixos-raspberrypi;
|
||||
};
|
||||
|
||||
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
|
||||
rhemawave.nixosModules.default
|
||||
{
|
||||
# system.autoUpgrade = {
|
||||
# enable = enableAutoUpgrade;
|
||||
# flake = upgradeFlakeRef;
|
||||
# dates = "*:00/10";
|
||||
# allowReboot = true;
|
||||
# flags = [ "--refresh" ];
|
||||
# };
|
||||
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;
|
||||
};
|
||||
in
|
||||
{
|
||||
packages.x86_64-linux.rhemawavekiosk = self.nixosConfigurations.rhemawavekiosk.config.system.build.toplevel;
|
||||
packages.x86_64-linux.rhemawavekiosk-dev = self.nixosConfigurations.rhemawavekiosk-dev.config.system.build.toplevel;
|
||||
packages.x86_64-linux.rhemawavekiosk-commercial = self.nixosConfigurations.rhemawavekiosk-commercial.config.system.build.toplevel;
|
||||
packages.x86_64-linux.rhemawavekiosk-android = self.nixosConfigurations.rhemawavekiosk-android.config.system.build.toplevel;
|
||||
nixosConfigurations = {
|
||||
rhemawavekiosk = mkKioskSystem {
|
||||
system = "x86_64-linux";
|
||||
rhemawave = rhemawave;
|
||||
diskModule = ./disk-config.nix;
|
||||
upgradeFlakeRef = "git+https://codeberg.org/RhemaWave-Technologies/KioskConfig.git#rhemawavekiosk";
|
||||
extraModules = [];
|
||||
};
|
||||
rhemawavekiosk-dev = mkKioskSystem {
|
||||
system = "x86_64-linux";
|
||||
rhemawave = rhemawave-dev;
|
||||
diskModule = ./disk-config.nix;
|
||||
upgradeFlakeRef = "git+https://codeberg.org/RhemaWave-Technologies/KioskConfig.git?ref=dev#rhemawavekiosk-dev";
|
||||
extraModules = [];
|
||||
};
|
||||
rhemawavekiosk-commercial = mkKioskSystem {
|
||||
system = "x86_64-linux";
|
||||
rhemawave = rhemawave;
|
||||
diskModule = ./commercial-disk-config.nix;
|
||||
upgradeFlakeRef = "git+https://codeberg.org/RhemaWave-Technologies/KioskConfig.git#rhemawavekiosk-commercial";
|
||||
extraModules = [];
|
||||
};
|
||||
rhemawavekiosk-commercial-dev = mkKioskSystem {
|
||||
system = "x86_64-linux";
|
||||
rhemawave = rhemawave;
|
||||
diskModule = ./commercial-disk-config.nix;
|
||||
upgradeFlakeRef = "git+https://codeberg.org/RhemaWave-Technologies/KioskConfig.git?ref=dev#rhemawavekiosk-commercial";
|
||||
extraModules = [];
|
||||
};
|
||||
rhemawavekiosk-android = mkKioskSystem {
|
||||
system = "x86_64-linux";
|
||||
rhemawave = rhemawave;
|
||||
diskModule = ./disk-config.nix;
|
||||
upgradeFlakeRef = "git+https://codeberg.org/RhemaWave-Technologies/KioskConfig.git#rhemawavekiosk-android";
|
||||
extraModules = [./rotated_display.nix ];
|
||||
};
|
||||
rhemawavekiosk-rpi = mkRpiKioskSystem {
|
||||
rhemawave = rhemawave;
|
||||
upgradeFlakeRef = "git+https://codeberg.org/RhemaWave-Technologies/KioskConfig.git#rhemawavekiosk-rpi";
|
||||
};
|
||||
rhemawavekiosk-rpi-dev = mkRpiKioskSystem {
|
||||
rhemawave = rhemawave-dev;
|
||||
upgradeFlakeRef = "git+https://codeberg.org/RhemaWave-Technologies/KioskConfig.git?ref=dev#rhemawavekiosk-rpi-dev";
|
||||
};
|
||||
usb-iso = 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
|
||||
./iso-config.nix
|
||||
./disk-config.nix
|
||||
({ pkgs, ... }: {
|
||||
environment.systemPackages = [
|
||||
disko.packages.${system}.default
|
||||
];
|
||||
isoImage.storeContents = [
|
||||
self.packages.x86_64-linux.rhemawavekiosk
|
||||
];
|
||||
environment.etc."disko-config.nix".source = ./disk-config.nix;
|
||||
})
|
||||
];
|
||||
};
|
||||
commercial-usb-iso = 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
|
||||
./commercial-iso-config.nix
|
||||
./commercial-disk-config.nix
|
||||
({ pkgs, ... }: {
|
||||
environment.systemPackages = [
|
||||
disko.packages.${system}.default
|
||||
];
|
||||
isoImage.storeContents = [
|
||||
self.packages.x86_64-linux.rhemawavekiosk-commercial
|
||||
];
|
||||
environment.etc."disko-config.nix".source = ./commercial-disk-config.nix;
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
android-iso = 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
|
||||
./iso-config.nix
|
||||
./disk-config.nix
|
||||
({ pkgs, ... }: {
|
||||
environment.systemPackages = [
|
||||
disko.packages.${system}.default
|
||||
];
|
||||
isoImage.storeContents = [
|
||||
self.packages.x86_64-linux.rhemawavekiosk-android
|
||||
];
|
||||
environment.etc."disko-config.nix".source = ./disk-config.nix;
|
||||
})
|
||||
];
|
||||
};
|
||||
dev-iso = 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
|
||||
./dev-iso.nix
|
||||
./disk-config.nix
|
||||
({ pkgs, ... }: {
|
||||
environment.systemPackages = [
|
||||
disko.packages.${system}.default
|
||||
];
|
||||
isoImage.storeContents = [
|
||||
self.packages.x86_64-linux.rhemawavekiosk-dev
|
||||
];
|
||||
environment.etc."disko-config.nix".source = ./disk-config.nix;
|
||||
})
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-label/nixos";
|
||||
fsType = "xfs";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-label/EFIBOOT";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0022" "dmask=0022" ];
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
self,
|
||||
...
|
||||
}:
|
||||
let
|
||||
targetSystem =
|
||||
self.nixosConfigurations.rhemawavekiosk.config.system.build.toplevel;
|
||||
|
||||
diskoScript =
|
||||
self.nixosConfigurations.rhemawavekiosk.config.system.build.diskoScript;
|
||||
in
|
||||
{
|
||||
nix.settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
|
||||
substituters = [
|
||||
"https://cache.nixos.org"
|
||||
];
|
||||
|
||||
flake-registry = "";
|
||||
};
|
||||
|
||||
nix.registry.nixpkgs = pkgs.lib.mkForce {
|
||||
to = {
|
||||
type = "path";
|
||||
path = "${inputs.nixpkgs}";
|
||||
};
|
||||
};
|
||||
|
||||
environment.variables.KIOSK_FLAKE = "${self}";
|
||||
|
||||
virtualisation.vmVariant = {
|
||||
virtualisation.memorySize = 8096;
|
||||
virtualisation.diskSize = 100000;
|
||||
virtualisation.cores = 4;
|
||||
virtualisation.qemu.options = [
|
||||
# "-nic none"
|
||||
];
|
||||
virtualisation.forwardPorts = [
|
||||
{ from = "host"; host.port = 2222; guest.port = 22; }
|
||||
];
|
||||
};
|
||||
|
||||
environment.etc."nix/netrc" = {
|
||||
text = ''
|
||||
password eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjIwODgzODk2ODEsIm5iZiI6MTc3MjgxMzY4MSwic3ViIjoia2lvc2siLCJodHRwczovL2p3dC5hdHRpYy5ycy92MSI6eyJjYWNoZXMiOnsia2lvc2siOnsiciI6MX19fX0.N6Ktrmmu1LSy2PP8uNF25VHRP1dxPZJ4M0MR1kUpVi0
|
||||
'';
|
||||
mode = "0400";
|
||||
};
|
||||
|
||||
nix.extraOptions = ''
|
||||
netrc-file = /etc/nix/netrc
|
||||
'';
|
||||
|
||||
networking.networkmanager.enable = true;
|
||||
|
||||
systemd.services.NetworkManager-wait-online.enable = false;
|
||||
|
||||
nix.settings.connect-timeout = 0;
|
||||
|
||||
services.openssh.enable = true;
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB4vXx7sOOVAyxdS/N1LEI+L8wYICf+gbzs6Kz7K8Je5 cnclack@pm.me:Thinkpad"
|
||||
];
|
||||
|
||||
systemd.services.zero-touch-install = {
|
||||
description = "Zero-Touch Kiosk Installation";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
wants = [ ];
|
||||
after = [ "systemd-udev-settle.service" ];
|
||||
|
||||
path = with pkgs; [
|
||||
nix
|
||||
git
|
||||
util-linux
|
||||
nixos-install-tools
|
||||
curl
|
||||
networkmanager
|
||||
mount
|
||||
umount
|
||||
disko
|
||||
];
|
||||
|
||||
environment = {
|
||||
NIX_PATH = "nixpkgs=${inputs.nixpkgs}";
|
||||
KIOSK_FLAKE = "${self}";
|
||||
DISKO_SCRIPT = "${diskoScript}";
|
||||
};
|
||||
|
||||
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
echo "Running disko script..."
|
||||
echo "Script: $DISKO_SCRIPT"
|
||||
|
||||
${diskoScript}
|
||||
|
||||
echo "Installing RhemaWave"
|
||||
echo "Closure Path: ${targetSystem}"
|
||||
|
||||
nixos-install \
|
||||
--system "${targetSystem}" \
|
||||
--no-root-passwd \
|
||||
--no-channel-copy
|
||||
|
||||
echo "============================================"
|
||||
echo " Installation complete!"
|
||||
echo " Rebooting in 5 seconds..."
|
||||
echo "============================================"
|
||||
sleep 5
|
||||
systemctl reboot --force
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
[Plymouth Theme]
|
||||
Name=RhemaWave
|
||||
Description=RhemaWave kiosk splash screen
|
||||
ModuleName=script
|
||||
|
||||
[script]
|
||||
ImageDir=/usr/share/plymouth/themes/rhemawave
|
||||
ScriptFile=/usr/share/plymouth/themes/rhemawave/rhemawave.script
|
||||
@@ -0,0 +1,6 @@
|
||||
wallpaper_image = Image("splash.png");
|
||||
screen_width = Window.GetWidth();
|
||||
screen_height = Window.GetHeight();
|
||||
resized_wallpaper_image = wallpaper_image.Scale(screen_width, screen_height);
|
||||
wallpaper_sprite = Sprite(resized_wallpaper_image);
|
||||
wallpaper_sprite.SetZ(-100);
|
||||
@@ -0,0 +1,34 @@
|
||||
{ pkgs, rhemawave, ...}:
|
||||
let
|
||||
rhemaApp = rhemawave.packages.${pkgs.system}.default;
|
||||
kioskscript = pkgs.writeShellScript "kiosk-start" ''
|
||||
OUTPUT=$(${pkgs.wlr-randr}/bin/wlr-randr | grep -m1 '^\S' | awk '{print $1}')
|
||||
${pkgs.wlr-randr}/bin/wlr-randr --output "$OUTPUT" --transform 90
|
||||
exec ${rhemaApp}/bin/rhemawave -d -s
|
||||
'';
|
||||
in
|
||||
{
|
||||
environment.systemPackages = [ pkgs.wlr-randr];
|
||||
|
||||
environment.loginShellInit = pkgs.lib.mkForce ''
|
||||
if [ "$(tty)" = "/dev/tty1" ]; then
|
||||
export CODEBUG=netdns=cgo
|
||||
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
|
||||
for i in {1..10}; do
|
||||
if ${pkgs.iputils}/bin/ping -c 1 8.8.8.8 &> /dev/null; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
export SDL_VIDEODRIVER=wayland
|
||||
export QT_QPA_PLATFORM=wayland
|
||||
export XDG_SESSION_TYPE=wayland
|
||||
export WLR_RENDERER=pixman
|
||||
export WLR_NO_HARDWARE_CURSORS=1
|
||||
|
||||
mkdir -p /home/kiosk/.local/share/rhemawave
|
||||
exec dbus-run-session cage -- ${kioskscript} > /tmp/kiosk.log 2>&1
|
||||
fi
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
disko.devices = {
|
||||
disk.disk1 = {
|
||||
device = lib.mkDefault "/dev/vda";
|
||||
type = "disk";
|
||||
content = {
|
||||
type = "gpt";
|
||||
partitions = {
|
||||
boot = {
|
||||
name = "boot";
|
||||
size = "1M";
|
||||
type = "EF02";
|
||||
};
|
||||
esp = {
|
||||
name = "ESP";
|
||||
size = "500M";
|
||||
type = "EF00";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
swap = {
|
||||
name = "swap";
|
||||
size = "16G";
|
||||
content = {
|
||||
type = "swap";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
name = "root";
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "xfs";
|
||||
mountpoint = "/";
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
"pquota"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user