0.1.50 was taken to the church and the things a container cannot answer were answered on the hardware: boot, autologin, the panel after a reboot, panel and browser scaling, Wonder Ink, Parent Call opening in the corner and reaching the sanctuary with a typed name, readable and silent notifications, HDMI audio and the volume keys. The promotion is a fast-forward. The experiment was cut from the published stable source and never diverged from it, so master reaches this work without a merge and there is one history. One thing changed for the release. The channel rules turn around: classroom-v2 and hyprland are the obsolete channels now and a room on either comes home to stable, while canary — where the next development release goes — and any channel somebody named by hand stay where they were put. A fresh installation has always defaulted to stable. Nothing else moved. This is the 0.1.50 that was verified, with a version number and a channel rule. Co-Authored-By: Claude Opus 5 <[email protected]>
196 lines
7.1 KiB
Bash
Executable File
196 lines
7.1 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
|
|
if [[ $# -lt 1 || $# -gt 2 ]]; then
|
|
echo "Usage: $0 CANDIDATE.deb [PREVIOUS.deb]" >&2
|
|
exit 2
|
|
fi
|
|
|
|
candidate="$(realpath "$1")"
|
|
previous=""
|
|
|
|
[[ -f "$candidate" ]] || { echo "Package not found: $candidate" >&2; exit 1; }
|
|
|
|
if [[ $# -eq 2 ]]; then
|
|
previous="$(realpath "$2")"
|
|
[[ -f "$previous" ]] || { echo "Package not found: $previous" >&2; exit 1; }
|
|
fi
|
|
|
|
echo "Validating $(basename "$candidate") on Debian Trixie"
|
|
|
|
docker_args=(
|
|
run --rm -i
|
|
-v "$candidate:/packages/candidate.deb:ro"
|
|
)
|
|
|
|
if [[ -n "$previous" ]]; then
|
|
docker_args+=( -v "$previous:/packages/previous.deb:ro" )
|
|
fi
|
|
|
|
timeout --signal=TERM --kill-after=15s 720s \
|
|
docker "${docker_args[@]}" debian:trixie-slim \
|
|
bash -s -- "${previous:+/packages/previous.deb}" <<'CONTAINER'
|
|
set -Eeuo pipefail
|
|
|
|
validation_failure() {
|
|
status=$?
|
|
echo "Validation failed at line ${BASH_LINENO[0]}: ${BASH_COMMAND}" >&2
|
|
|
|
if command -v lpstat >/dev/null 2>&1; then
|
|
lpstat -t >&2 || true
|
|
lpoptions -p Elmer -l >&2 || true
|
|
fi
|
|
|
|
[[ ! -f /tmp/provision-first.log ]] || cat /tmp/provision-first.log >&2
|
|
[[ ! -f /tmp/provision-second.log ]] || cat /tmp/provision-second.log >&2
|
|
exit "$status"
|
|
}
|
|
|
|
trap validation_failure ERR
|
|
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
# Package validation runs in a container with no init system. Do not let
|
|
# maintainer scripts try to start CUPS, Avahi or other irrelevant daemons;
|
|
# services are inspected and CUPS is started explicitly when the test needs it.
|
|
cat > /usr/sbin/policy-rc.d <<'POLICY'
|
|
#!/bin/sh
|
|
exit 101
|
|
POLICY
|
|
chmod 0755 /usr/sbin/policy-rc.d
|
|
|
|
run_logged() {
|
|
label="$1"
|
|
seconds="$2"
|
|
shift 2
|
|
|
|
if ! timeout --signal=TERM --kill-after=10s "${seconds}s" "$@" \
|
|
>"/tmp/${label}.log" 2>&1; then
|
|
cat "/tmp/${label}.log" >&2
|
|
echo "${label} exceeded ${seconds}s or failed" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
run_logged apt-update 120 apt-get update -qq
|
|
|
|
previous="${1:-}"
|
|
|
|
if [[ -n "$previous" ]]; then
|
|
run_logged previous-install 360 apt-get install -y -qq "$previous"
|
|
|
|
cat > /etc/ekklesia-classroom/device.conf <<'CONFIG'
|
|
# Configuration carried forward from 0.1.36
|
|
UPDATE_URL=https://updates.riverofglorymn.org
|
|
CHANNEL=canary
|
|
DVD_ENABLED=false
|
|
UI_SCALE=1.25
|
|
MQTT_ENABLED=true
|
|
MQTT_HOST=broker.example.test
|
|
MQTT_PORT=1884
|
|
MQTT_USERNAME=classroom
|
|
MQTT_PASSWORD=preserve-me
|
|
CUSTOM_SETTING=preserve-me-too
|
|
CONFIG
|
|
fi
|
|
|
|
run_logged candidate-install 360 apt-get install -y -qq /packages/candidate.deb
|
|
|
|
command -v nmtui >/dev/null
|
|
command -v lpadmin >/dev/null
|
|
command -v lpinfo >/dev/null
|
|
|
|
systemctl is-enabled NetworkManager.service >/dev/null
|
|
systemctl is-enabled cups.service >/dev/null
|
|
! systemctl is-enabled NetworkManager-wait-online.service >/dev/null 2>&1
|
|
|
|
grep -q '^managed=false$' /etc/NetworkManager/NetworkManager.conf
|
|
|
|
# A normal Docker container has Ethernet and no Wi-Fi adapter. Reaching this
|
|
# point proves package configuration did not require Wi-Fi hardware.
|
|
! find /sys/class/net -mindepth 2 -maxdepth 2 -type d -name wireless | grep -q .
|
|
|
|
/usr/sbin/cupsd
|
|
sleep 1
|
|
|
|
driver='foomatic-db-compressed-ppds:0/ppd/foomatic-ppd/Generic-PCL_6_PCL_XL_Printer-pxlcolor.ppd'
|
|
lpinfo -m | grep -q "^${driver} "
|
|
|
|
# Simulate the queue an older release may have left behind, then run the real
|
|
# boot provisioning path. Chrome is stubbed as already installed and DVD is
|
|
# disabled so the test remains entirely local and deterministic.
|
|
lpadmin -p Classroom_Color -v socket://192.0.2.10:9100 -m "$driver"
|
|
install -m755 /bin/true /usr/local/bin/google-chrome
|
|
|
|
timeout --signal=TERM --kill-after=5s 45s classroom-provision \
|
|
>/tmp/provision-first.log
|
|
|
|
! lpstat -p Classroom_Color >/dev/null 2>&1
|
|
lpstat -p Elmer -d -v | grep -q 'socket://10.10.0.155:9100'
|
|
lpstat -l -p Elmer | grep -q 'Description: Elmer'
|
|
lpoptions -p Elmer -l | grep -Eq '^PrintoutMode/.*:.*\*Normal([[:space:]]|$)'
|
|
lpoptions -p Elmer -l | grep -Eq '^ColorModel/.*:.*\*Color([[:space:]]|$)'
|
|
[[ "$(lpstat -e)" == "Elmer" ]]
|
|
[[ "$(systemctl is-enabled avahi-daemon.service 2>/dev/null || true)" == "masked" ]]
|
|
[[ "$(systemctl is-enabled avahi-daemon.socket 2>/dev/null || true)" == "masked" ]]
|
|
|
|
timeout --signal=TERM --kill-after=5s 45s classroom-provision \
|
|
>/tmp/provision-second.log
|
|
grep -q 'Elmer is already correctly configured' /tmp/provision-second.log
|
|
|
|
if [[ -n "$previous" ]]; then
|
|
# The room's own values, untouched by the upgrade.
|
|
grep -q '^DVD_ENABLED=false$' /etc/ekklesia-classroom/device.conf
|
|
grep -q '^UI_SCALE=1.25$' /etc/ekklesia-classroom/device.conf
|
|
grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf
|
|
grep -q '^CUSTOM_SETTING=preserve-me-too$' /etc/ekklesia-classroom/device.conf
|
|
|
|
# The channel a room was put on deliberately survives the upgrade.
|
|
# canary is where the next development release goes, and the Plasma
|
|
# classroom is the stable line now, so nothing here has to move.
|
|
grep -q '^CHANNEL=canary$' /etc/ekklesia-classroom/device.conf
|
|
|
|
# And a room that was carried through the experiment on its own
|
|
# channel comes home, because that channel is the obsolete one now.
|
|
sed -i 's/^CHANNEL=.*/CHANNEL=classroom-v2/' /etc/ekklesia-classroom/device.conf
|
|
classroom-migrate >/tmp/migrate-from-v2.log 2>&1
|
|
grep -q '^CHANNEL=stable$' /etc/ekklesia-classroom/device.conf
|
|
grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf
|
|
grep -q '^CUSTOM_SETTING=preserve-me-too$' /etc/ekklesia-classroom/device.conf
|
|
sed -i 's/^CHANNEL=.*/CHANNEL=canary/' /etc/ekklesia-classroom/device.conf
|
|
|
|
# Every setting this release has that the room predates, appended
|
|
# exactly once. classroom-migrate hands device.conf to the shared
|
|
# helper after its own work for this, so that a machine converges
|
|
# whether it got here through this postinst or through somebody
|
|
# running the command by hand.
|
|
for setting in LIVE_ENABLED AUDIO_OUTPUT UI_SCALE; do
|
|
[[ "$(grep -c "^${setting}=" /etc/ekklesia-classroom/device.conf)" -eq 1 ]]
|
|
done
|
|
|
|
run_logged candidate-reinstall 360 \
|
|
apt-get install --reinstall -y -qq /packages/candidate.deb
|
|
|
|
# An install that changes nothing must change nothing.
|
|
for setting in LIVE_ENABLED AUDIO_OUTPUT UI_SCALE; do
|
|
[[ "$(grep -c "^${setting}=" /etc/ekklesia-classroom/device.conf)" -eq 1 ]]
|
|
done
|
|
grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf
|
|
grep -q '^CUSTOM_SETTING=preserve-me-too$' /etc/ekklesia-classroom/device.conf
|
|
grep -q '^CHANNEL=canary$' /etc/ekklesia-classroom/device.conf
|
|
|
|
# And by hand, on a machine that is already converged: the command a
|
|
# technician runs must be safe to run twice.
|
|
classroom-migrate >/tmp/migrate-by-hand.log 2>&1
|
|
for setting in LIVE_ENABLED AUDIO_OUTPUT UI_SCALE; do
|
|
[[ "$(grep -c "^${setting}=" /etc/ekklesia-classroom/device.conf)" -eq 1 ]]
|
|
done
|
|
grep -q '^MQTT_PASSWORD=preserve-me$' /etc/ekklesia-classroom/device.conf
|
|
! grep -q 'preserve-me' /tmp/migrate-by-hand.log
|
|
fi
|
|
|
|
echo "Trixie package, upgrade, bounded install, networking, Elmer printing and reinstall checks passed."
|
|
CONTAINER
|