Update configuration and dev-iso

dev-iso now mirrors both in function, setup and organization iso-config.

configuration.nix has been updated to ensure PipeWire audio controls, and pin sink volumes to 100%.
This commit is contained in:
NeilClack
2026-08-07 00:38:25 -05:00
parent 2209f90c5a
commit 2d4aca230d
2 changed files with 63 additions and 37 deletions
+26 -5
View File
@@ -115,25 +115,46 @@ in
services.pipewire = { enable = true; alsa.enable = true; pulse.enable = true; }; services.pipewire = { enable = true; alsa.enable = true; pulse.enable = true; };
# --- Pin system audio to 100% before RadiantWave launches --- # New sinks with no stored volume default to ~40% in WirePlumber 0.5+.
# Force every newly-created sink to 100% so switching the default sink
# never changes the volume.
services.pipewire.wireplumber.extraConfig."99-kiosk-audio" = {
"wireplumber.settings"."device.routes.default-sink-volume" = 1.0;
};
# --- Pin all system audio sinks to 100% before RadiantWave launches ---
# User unit (PipeWire runs per-user in the kiosk session), owned by this # User unit (PipeWire runs per-user in the kiosk session), owned by this
# system config. Ordered after PipeWire/WirePlumber; the retry loop covers # system config. Ordered after PipeWire/WirePlumber; the retry loop covers
# default-sink readiness at boot. RadiantWave's loginShellInit waits on this # sink readiness at boot. Pins every connected sink (not just the default)
# before exec'ing cage. # and unmutes them, so switching the default sink never changes the volume.
# RadiantWave's loginShellInit waits on this before exec'ing cage.
systemd.user.services.radiantwave-audio-init = { systemd.user.services.radiantwave-audio-init = {
description = "Pin system audio volume to 100% and unmute"; description = "Pin all system audio sinks to 100% and unmute";
after = [ "pipewire.service" "wireplumber.service" ]; after = [ "pipewire.service" "wireplumber.service" ];
wants = [ "pipewire.service" "wireplumber.service" ]; wants = [ "pipewire.service" "wireplumber.service" ];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
}; };
script = '' script = ''
# Wait until WirePlumber exposes at least one sink
sinks=""
for i in {1..30}; do for i in {1..30}; do
if ${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 1.0 2>/dev/null; then sinks=$(${pkgs.wireplumber}/bin/wpctl list audio sinks 2>/dev/null \
| ${pkgs.gnused}/bin/sed -nE 's/^.*[^0-9]([0-9]+)\. .*$/\1/p')
if [ -n "$sinks" ]; then
break break
fi fi
sleep 1 sleep 1
done done
# Pin and unmute every connected sink
for sink_id in $sinks; do
${pkgs.wireplumber}/bin/wpctl set-volume "$sink_id" 1.0 2>/dev/null || true
${pkgs.wireplumber}/bin/wpctl set-mute "$sink_id" 0 2>/dev/null || true
done
# Fallback in case the sink list came up empty
${pkgs.wireplumber}/bin/wpctl set-volume @DEFAULT_AUDIO_SINK@ 1.0 2>/dev/null || true
${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SINK@ 0 2>/dev/null || true ${pkgs.wireplumber}/bin/wpctl set-mute @DEFAULT_AUDIO_SINK@ 0 2>/dev/null || true
''; '';
}; };
+37 -32
View File
@@ -8,23 +8,27 @@ let
targetSystem = targetSystem =
self.nixosConfigurations.radiantwavekiosk-dev.config.system.build.toplevel; self.nixosConfigurations.radiantwavekiosk-dev.config.system.build.toplevel;
# 🔧 FIX: prebuilt disko script (restores v1.0.1 behavior)
diskoScript = diskoScript =
self.nixosConfigurations.radiantwavekiosk-dev.config.system.build.diskoScript; self.nixosConfigurations.radiantwavekiosk-dev.config.system.build.diskoScript;
in in
{ {
############################################################
# System configuration
############################################################
nix.settings = { nix.settings = {
experimental-features = [ experimental-features = [
"nix-command" "nix-command"
"flakes" "flakes"
]; ];
# 🔧 FIX: restore cache (prevents massive rebuild/download cascade)
substituters = [ substituters = [
"https://cache.nixos.org" "https://cache.nixos.org"
]; ];
flake-registry = ""; flake-registry = "";
connect-timeout = 0;
}; };
nix.registry.nixpkgs = pkgs.lib.mkForce { nix.registry.nixpkgs = pkgs.lib.mkForce {
@@ -34,19 +38,11 @@ in
}; };
}; };
environment.variables.KIOSK_FLAKE = "${self}"; nix.extraOptions = ''
netrc-file = /etc/nix/netrc
'';
virtualisation.vmVariant = { environment.variables.KIOSK_FLAKE = "${self}";
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" = { environment.etc."nix/netrc" = {
text = '' text = ''
@@ -55,30 +51,33 @@ in
mode = "0400"; mode = "0400";
}; };
nix.extraOptions = ''
netrc-file = /etc/nix/netrc
'';
networking.networkmanager.enable = true; networking.networkmanager.enable = true;
systemd.services.NetworkManager-wait-online.enable = false; ############################################################
# User configuration
############################################################
nix.settings.connect-timeout = 0; users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL4qWNZnYU5JaqR9c2qh6oFZktzVNBOx42PfDaGofCL6 cnclack@pm.me macbook"
];
############################################################
# Service configuration
############################################################
services.openssh.enable = true; services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keys = [ systemd.services.NetworkManager-wait-online.enable = false;
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB4vXx7sOOVAyxdS/N1LEI+L8wYICf+gbzs6Kz7K8Je5 cnclack@pm.me:Thinkpad"
];
systemd.services.zero-touch-install = { systemd.services.zero-touch-install = {
description = "Zero-Touch Kiosk Installation"; description = "Zero-Touch Kiosk Installation";
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
# 🔧 FIX: remove runtime network dependency # Make sure we own tty1 exclusively - getty@tty1 will otherwise
wants = [ ]; # try to spawn a login prompt on the same console.
after = [ "systemd-udev-settle.service" ]; conflicts = [ "getty@tty1.service" ];
after = [ "systemd-udev-settle.service" "getty@tty1.service" ];
path = with pkgs; [ path = with pkgs; [
nix nix
@@ -98,15 +97,22 @@ in
DISKO_SCRIPT = "${diskoScript}"; DISKO_SCRIPT = "${diskoScript}";
}; };
serviceConfig = {
StandardInput = "tty";
StandardOutput = "tty";
StandardError = "tty";
TTYPath = "/dev/tty1";
TTYReset = true;
TTYVHangup = true;
TTYVTDisallocate = true;
};
script = '' script = ''
set -euo pipefail set -euo pipefail
DISK=/dev/vda
echo "Running disko script..." echo "Running disko script..."
echo "Script: $DISKO_SCRIPT" echo "Script: $DISKO_SCRIPT"
# 🔧 FIX: use prebuilt script instead of runtime disko eval
${diskoScript} ${diskoScript}
echo "Installing RadiantWave" echo "Installing RadiantWave"
@@ -119,10 +125,9 @@ in
echo "============================================" echo "============================================"
echo " Installation complete!" echo " Installation complete!"
echo " Rebooting in 5 seconds..." echo " Please shut down and remove the flash drive before restarting"
echo "============================================" echo "============================================"
sleep 5 sleep 10000000
systemctl reboot --force
''; '';
}; };
} }