diff --git a/.gitea/workflows/build-dev.yml b/.gitea/workflows/build-dev.yml index 5fb76e5..dd685ba 100644 --- a/.gitea/workflows/build-dev.yml +++ b/.gitea/workflows/build-dev.yml @@ -2,17 +2,25 @@ name: Build Dev ISO on: workflow_dispatch: + push: + branches: + - dev + +env: + NIX_CONFIG: | + extra-substituters = https://attic.radiantwavetech.com/radiantwave-dev + extra-trusted-public-keys = radiantwave-dev:B8FhLu3MQ9JfeEIHIKNrKxnP+3akzzkqMbTZR4hRfj0= jobs: build-dev-iso: runs-on: build-server steps: - - name: Checkout - run: git clone --depth 1 ssh://git@gitea.radiantwavetech.com:2222/RadiantWaveTech/KioskConfig.git . + - name: Clone Repository + run: git clone --depth 1 --no-single-branch ssh://git@gitea.radiantwavetech.com:2222/RadiantWaveTech/KioskConfig.git . - # flake.lock is updated manually (committing an updated lock is the - # release trigger); CI only builds what is checked in. + - name: Checkout dev branch + run: git checkout dev - name: Prepare output directory run: mkdir -p /home/user/radiantwave @@ -32,8 +40,7 @@ jobs: echo "KIOSK_ISO_FILENAME=${FILENAME}" >> "$GITHUB_ENV" - name: Move old dev images to archive - run: | - ssh nclack@157.245.124.103 'mv /mnt/infrastructure_data/files/images/radiantwave-kiosk-dev* /mnt/infrastructure_data/files/images/archives/' + run: tools/archive-images.sh nclack@157.245.124.103 /mnt/infrastructure_data/files/images /mnt/infrastructure_data/files/images/archives 'radiantwave-kiosk-dev*' - name: Copy kiosk ISO to fileserver run: | diff --git a/.gitea/workflows/build-prod-android.yml b/.gitea/workflows/build-prod-android.yml index af18b88..5a3db42 100644 --- a/.gitea/workflows/build-prod-android.yml +++ b/.gitea/workflows/build-prod-android.yml @@ -1,6 +1,11 @@ on: workflow_dispatch: +env: + NIX_CONFIG: | + extra-substituters = https://attic.radiantwavetech.com/radiantwave + extra-trusted-public-keys = radiantwave:QADrjpBWJssTZ3KmiZtcWEf4uAm66oOlHmtQI3jkrgA= + jobs: build-android: runs-on: build-server diff --git a/.gitea/workflows/build-prod-commercial.yml b/.gitea/workflows/build-prod-commercial.yml index 5b56db4..128b176 100644 --- a/.gitea/workflows/build-prod-commercial.yml +++ b/.gitea/workflows/build-prod-commercial.yml @@ -1,6 +1,11 @@ on: workflow_dispatch: +env: + NIX_CONFIG: | + extra-substituters = https://attic.radiantwavetech.com/radiantwave + extra-trusted-public-keys = radiantwave:QADrjpBWJssTZ3KmiZtcWEf4uAm66oOlHmtQI3jkrgA= + jobs: build-commercial: runs-on: build-server diff --git a/.gitea/workflows/build-prod-kiosk.yml b/.gitea/workflows/build-prod-kiosk.yml index beaae9e..d341a4e 100644 --- a/.gitea/workflows/build-prod-kiosk.yml +++ b/.gitea/workflows/build-prod-kiosk.yml @@ -1,6 +1,11 @@ on: workflow_dispatch: +env: + NIX_CONFIG: | + extra-substituters = https://attic.radiantwavetech.com/radiantwave + extra-trusted-public-keys = radiantwave:QADrjpBWJssTZ3KmiZtcWEf4uAm66oOlHmtQI3jkrgA= + jobs: build-kiosk: runs-on: build-server diff --git a/.gitea/workflows/build-prod-rpi.yml b/.gitea/workflows/build-prod-rpi.yml index fd15415..bb267ce 100644 --- a/.gitea/workflows/build-prod-rpi.yml +++ b/.gitea/workflows/build-prod-rpi.yml @@ -1,6 +1,11 @@ on: workflow_dispatch: +env: + NIX_CONFIG: | + extra-substituters = https://attic.radiantwavetech.com/radiantwave https://nixos-raspberrypi.cachix.org + extra-trusted-public-keys = radiantwave:QADrjpBWJssTZ3KmiZtcWEf4uAm66oOlHmtQI3jkrgA= nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI= + jobs: build-rpi: runs-on: build-server @@ -26,8 +31,7 @@ jobs: echo "RPI_IMAGE_FILENAME=${FILENAME}" >> "$GITHUB_ENV" - name: Move old Raspberry Pi images to archive - run: | - ssh nclack@157.245.124.103 'mv /mnt/infrastructure_data/files/images/radiantwave-rpi* /mnt/infrastructure_data/files/images/archives/' + run: tools/archive-images.sh nclack@157.245.124.103 /mnt/infrastructure_data/files/images /mnt/infrastructure_data/files/images/archives 'radiantwave-rpi*' - name: Copy Raspberry Pi image to fileserver run: | diff --git a/configuration.nix b/configuration.nix index 89908d8..e51b742 100644 --- a/configuration.nix +++ b/configuration.nix @@ -55,6 +55,22 @@ in } ]; + # Let the kiosk app apply pending updates by restarting its own TTY + # session (re-autologin -> fresh cage + RadiantWave). Scoped to exactly + # one unit and verb; everything else keeps stock (denied) policy. + security.polkit.enable = true; + environment.etc."polkit-1/rules.d/10-kiosk-getty.rules".text = '' + polkit.addRule(function(action, subject) { + if (subject.user !== "kiosk") return null; + if (action.id !== "org.freedesktop.systemd1.manage-units") return null; + var unit = action.lookup("unit"); + var verb = action.lookup("verb"); + if ((unit === "getty@tty1.service" || unit === "getty@tty1") && verb === "restart") { + return polkit.Result.YES; + } + }); + ''; + hardware.graphics.enable = true; time.timeZone = "America/Chicago"; @@ -69,10 +85,6 @@ in operation = "switch"; }; - system.activationScripts.cleanRadiantFiles = '' - rm -rf /home/kiosk/.local/radiantwave/audio - ''; - # Virtual machine declaration virtualisation.vmVariant = { boot.loader.systemd-boot.enable = pkgs.lib.mkForce false; @@ -96,6 +108,14 @@ in # NixOS settings. nix.settings.experimental-features = [ "nix-command" "flakes" ]; nix.settings.accept-flake-config = true; + nix.settings.extra-substituters = [ + "https://attic.radiantwavetech.com/radiantwave" + "https://attic.radiantwavetech.com/radiantwave-dev" + ]; + nix.settings.extra-trusted-public-keys = [ + "radiantwave:QADrjpBWJssTZ3KmiZtcWEf4uAm66oOlHmtQI3jkrgA=" + "radiantwave-dev:B8FhLu3MQ9JfeEIHIKNrKxnP+3akzzkqMbTZR4hRfj0=" + ]; system.stateVersion = "24.05"; ############################################################ diff --git a/flake.lock b/flake.lock index 5a28305..5778b60 100644 --- a/flake.lock +++ b/flake.lock @@ -220,11 +220,11 @@ "nixpkgs": "nixpkgs_3" }, "locked": { - "lastModified": 1787322563, - "narHash": "sha256-Eh3H6sYhpvXBNoPOX9/2On13YVRlLpEkhFrEU1pdnJM=", + "lastModified": 1787341934, + "narHash": "sha256-pWGpgM5acdCO02H8P3KKtdv09n9ucnI3cg8d3/tvwtk=", "ref": "main", - "rev": "3c9de0bee2c6915d6a48ba44e985e681e48daba2", - "revCount": 33, + "rev": "b96631c374682088088b3d679359d192a0ae74d6", + "revCount": 35, "type": "git", "url": "https://gitea.radiantwavetech.com/RadiantWaveTech/radiantwave.git" }, @@ -240,11 +240,11 @@ "nixpkgs": "nixpkgs_4" }, "locked": { - "lastModified": 1787322563, - "narHash": "sha256-Eh3H6sYhpvXBNoPOX9/2On13YVRlLpEkhFrEU1pdnJM=", + "lastModified": 1787522765, + "narHash": "sha256-D3KOrGcAH07lvKYgyiwejOQpDW91js7zI6l87WdabLk=", "ref": "dev", - "rev": "3c9de0bee2c6915d6a48ba44e985e681e48daba2", - "revCount": 33, + "rev": "63265cc22f3055a782a0114e92c57a36bef723b2", + "revCount": 40, "type": "git", "url": "https://gitea.radiantwavetech.com/RadiantWaveTech/radiantwave.git" }, diff --git a/tools/archive-images.sh b/tools/archive-images.sh new file mode 100755 index 0000000..cad0525 --- /dev/null +++ b/tools/archive-images.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Archive old build images on the fileserver before publishing new ones. +# +# Usage: tools/archive-images.sh ... +# +# Zero matching files is fine (nothing to archive yet); a missing directory +# or a failed move aborts non-zero so CI stops before publishing. +# The remote half is piped to `bash -s` over stdin so there is no nested +# shell quoting to get wrong. + +set -euo pipefail + +die() { echo "error: $*" >&2; exit 1; } + +(( $# >= 4 )) || die "usage: $0 ..." + +target=$1 images_dir=$2 archive_dir=$3 +shift 3 +patterns=("$@") + +for v in "$images_dir" "$archive_dir" "${patterns[@]}"; do + case $v in + *[[:space:]\'\"]*) die "unsafe argument (whitespace/quotes): $v" ;; + esac +done + +echo "Archiving previous images on $target:" +printf ' pattern: %s\n' "${patterns[@]}" + +# Assignments prefixed to `bash -s` are parsed by the remote shell as +# environment variables for the script below; the quoted heredoc marker +# keeps every byte of the payload literal until bash executes it. +ssh "$target" "IMAGES_DIR=$images_dir ARCHIVE_DIR=$archive_dir bash -s" <<'REMOTE' +set -euo pipefail +shopt -s nullglob + +if [ ! -d "$IMAGES_DIR" ]; then + echo "error: images dir not found: $IMAGES_DIR" >&2 + exit 1 +fi +if [ ! -d "$ARCHIVE_DIR" ]; then + echo "error: archive dir not found: $ARCHIVE_DIR" >&2 + exit 1 +fi + +moved=0 +for pat in "${PATTERNS[@]}"; do + for f in "$IMAGES_DIR"/$pat; do + echo " archiving $(basename "$f")" + mv "$f" "$ARCHIVE_DIR/" + moved=$((moved + 1)) + done +done + +echo "Archived $moved file(s)." +REMOTE