River Kids came up silent on stable 0.2.2. The decision this policy makes
was right and was never asked for.
classroom-audio applied its policy once at startup and then only when a
PipeWire event arrived. pactl talks to PipeWire's PulseAudio server, and
the unit was ordered after pipewire and wireplumber but not after that.
At boot it therefore raced the server and lost: the single startup apply
failed with "Connection refused", the subscription attached cleanly a few
seconds later, and from that moment the daemon waited for an event that
had already happened. systemd said active, the subscription was live, and
the policy had never run at all.
That is why the card was found on output:analog-stereo+input:analog-stereo
with its HDMI port available. That profile is WirePlumber's own pick, not
one this policy would ever produce, which is the evidence it never ran.
Reproduced in the lab against real PipeWire 1.4.2 and WirePlumber 0.5.8 by
starting the daemon with pipewire-pulse stopped and then starting it: the
old daemon sits idle forever, the new one converges.
The shape is now: wait for the server, apply, subscribe, apply again the
moment the subscription attaches, and coalesce each burst of events into
one decision. Applying on attach is the fix for the race. While the room
has not got the output it would prefer it also looks again on a backing
off timer capped at a minute, so a television switched on hours later is
picked up whether or not ALSA's jack change ever reaches us as an event.
Once the room has what it wants it stops looking entirely, and a machine
with no digital output never looks at all.
Also here, all of it found by measuring the real server rather than
reading the code:
* sink lookup matched on fields a sink does not have. Two of its three
conditions could never be true; the one that worked returned whichever
sink of the card came first rather than the one for the chosen port.
* volume and mute are no longer touched. The old code unmuted and forced
70% on every output change, so every television power cycle reset a
volume the teacher had set and could unmute an output muted on
purpose. WirePlumber already remembers volume per device. A machine
this policy has never configured still gets 70% once.
* the profile chosen keeps the card's input, which is the difference
between output:hdmi-stereo and the output:hdmi-stereo+input:analog-stereo
an administrator reaches for by hand.
* a card profile is only set when it is not already in place, and only
so many times, so a sink that never appears cannot become a switching
loop.
* a machine with no sound server at all says so once and backs off,
rather than filling the journal. pactl subscribe's own stderr is
dropped because saying it is this daemon's job, and a subscription is
only treated as healthy once it has lasted, since pactl starts
successfully and then fails to connect.
* the fixtures described a machine nobody has. Real pactl puts no
"direction" on a port at all and says "availability unknown" rather
than nothing, so a test could not have caught this.
Existing streams are moved explicitly. Measured both ways on the real
stack: changing the default sink does move a stream that never asked for
a particular sink, but a stream pinned to a device stays where it is with
no policy running, and this moves it back without the application being
restarted.
tests/test-classroom-audio-daemon.sh drives the real daemon through the
boot race, a television switched on with and without an event announcing
it, a power cycle, a set that never comes on, and a room already correct.
It uses a pactl mock because no loopback or dummy sound driver has an HDMI
port, so the one thing a lab cannot prove is that the real jack change
arrives; docs/testing.md carries the physical procedure for that and says
not to take a passing build as evidence of it.
Co-Authored-By: Claude Opus 5 <[email protected]>
490 lines
16 KiB
Bash
Executable File
490 lines
16 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
if [[ $# -ne 1 ]]; then
|
|
echo "Usage: $0 VERSION"
|
|
exit 1
|
|
fi
|
|
|
|
VERSION="$1"
|
|
|
|
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
echo "Invalid version: $VERSION"
|
|
echo "Expected MAJOR.MINOR.PATCH, for example 0.1.6"
|
|
exit 1
|
|
fi
|
|
|
|
STAGE="$ROOT/packaging/root"
|
|
OUTPUT="$ROOT/dist/ekklesia-classroom_${VERSION}_amd64.deb"
|
|
|
|
# Syntax check everything the package ships, by shebang, so this cannot
|
|
# drift out of date as classroom commands are added.
|
|
echo "Validating sources"
|
|
|
|
for script in "$ROOT/packaging/debian/postinst" "$ROOT"/scripts/* "$ROOT"/tests/*; do
|
|
[[ -f "$script" ]] || continue
|
|
|
|
case "$(head -n 1 "$script")" in
|
|
*python3*)
|
|
python3 -m py_compile "$script"
|
|
;;
|
|
*bash*|*bin/sh*)
|
|
bash -n "$script"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
for module in "$ROOT"/lib/*.py; do
|
|
[[ -f "$module" ]] || continue
|
|
|
|
python3 -m py_compile "$module"
|
|
done
|
|
|
|
for policy in "$ROOT"/config/chrome/policies/*/*.json; do
|
|
[[ -f "$policy" ]] || continue
|
|
|
|
python3 -c 'import json, sys; json.load(open(sys.argv[1]))' "$policy"
|
|
done
|
|
|
|
find "$ROOT/scripts" "$ROOT/lib" "$ROOT/tests" \
|
|
-name '__pycache__' -type d -prune -exec rm -rf {} + 2>/dev/null || true
|
|
|
|
for test in "$ROOT"/tests/test-*.sh; do
|
|
[[ -x "$test" ]] || continue
|
|
|
|
echo "Running $(basename "$test")"
|
|
"$test" > /dev/null || {
|
|
echo "Tests failed. Run it directly to see why:"
|
|
echo " $test"
|
|
exit 1
|
|
}
|
|
done
|
|
|
|
echo "Building Ekklesia Classroom ${VERSION}"
|
|
|
|
# Always construct the package from clean canonical sources.
|
|
rm -rf "$STAGE"
|
|
mkdir -p "$STAGE/DEBIAN" "$ROOT/dist"
|
|
|
|
# Debian package metadata.
|
|
sed \
|
|
"s/^Version: @VERSION@$/Version: ${VERSION}/" \
|
|
"$ROOT/packaging/debian/control.template" \
|
|
> "$STAGE/DEBIAN/control"
|
|
|
|
install -m755 \
|
|
"$ROOT/packaging/debian/postinst" \
|
|
"$STAGE/DEBIAN/postinst"
|
|
|
|
|
|
|
|
|
|
# Classroom commands.
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-browser" \
|
|
"$STAGE/usr/local/bin/classroom-browser"
|
|
|
|
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-dvd" \
|
|
"$STAGE/usr/local/bin/classroom-dvd"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-dvd-session" \
|
|
"$STAGE/usr/local/bin/classroom-dvd-session"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-dvd-css-setup" \
|
|
"$STAGE/usr/local/bin/classroom-dvd-css-setup"
|
|
|
|
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-mqtt" \
|
|
"$STAGE/usr/local/bin/classroom-mqtt"
|
|
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-scale" \
|
|
"$STAGE/usr/local/bin/classroom-scale"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-shutdown" \
|
|
"$STAGE/usr/local/bin/classroom-shutdown"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-chrome-setup" \
|
|
"$STAGE/usr/local/bin/classroom-chrome-setup"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-provision" \
|
|
"$STAGE/usr/local/bin/classroom-provision"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-printer-setup" \
|
|
"$STAGE/usr/local/bin/classroom-printer-setup"
|
|
|
|
# Shared helpers imported by the classroom commands.
|
|
install -Dm644 \
|
|
"$ROOT/lib/classroom_config.py" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_config.py"
|
|
|
|
|
|
|
|
install -Dm644 \
|
|
"$ROOT/lib/classroom_mqtt.py" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_mqtt.py"
|
|
|
|
|
|
|
|
install -Dm644 \
|
|
"$ROOT/lib/classroom_vlc.py" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_vlc.py"
|
|
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/wallpapers/classroom-calm.png" \
|
|
"$STAGE/usr/share/backgrounds/ekklesia/classroom-calm.png"
|
|
|
|
|
|
|
|
|
|
# Chrome enterprise policy: suppress first-run and sign-in nags, and pin
|
|
# Home to Wonder Ink. Nothing here restricts where teachers can browse.
|
|
install -Dm644 \
|
|
"$ROOT/config/chrome/policies/managed/ekklesia-classroom.json" \
|
|
"$STAGE/etc/opt/chrome/policies/managed/ekklesia-classroom.json"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/chrome/policies/recommended/ekklesia-classroom.json" \
|
|
"$STAGE/etc/opt/chrome/policies/recommended/ekklesia-classroom.json"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/ekklesia-classroom-update" \
|
|
"$STAGE/usr/local/bin/ekklesia-classroom-update"
|
|
|
|
# System configuration.
|
|
install -Dm644 \
|
|
"$ROOT/config/sddm/ekklesia-classroom.conf" \
|
|
"$STAGE/etc/sddm.conf.d/ekklesia-classroom.conf"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/systemd/updater/ekklesia-classroom-update.service" \
|
|
"$STAGE/etc/systemd/system/ekklesia-classroom-update.service"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/systemd/updater/ekklesia-classroom-update.timer" \
|
|
"$STAGE/etc/systemd/system/ekklesia-classroom-update.timer"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/systemd/provision/ekklesia-classroom-provision.service" \
|
|
"$STAGE/etc/systemd/system/ekklesia-classroom-provision.service"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/systemd/shutdown/ekklesia-classroom-shutdown.service" \
|
|
"$STAGE/etc/systemd/system/ekklesia-classroom-shutdown.service"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/systemd/mqtt/ekklesia-classroom-mqtt.service" \
|
|
"$STAGE/etc/systemd/system/ekklesia-classroom-mqtt.service"
|
|
|
|
|
|
|
|
|
|
|
|
# The classroom desktop.
|
|
#
|
|
# Not a shell, and not a daemon: a Plasma session described in files Plasma
|
|
# already reads. The panel, the window behaviour, the notifications, the
|
|
# lockdown and the palette are all in here, which is why there is no longer
|
|
# a dock, a window helper, a notification wrapper or a compositor config in
|
|
# the list above.
|
|
|
|
# Not /etc/xdg: plasma-workspace already owns files by these names there.
|
|
# The classroom's directory goes in front of it in XDG_CONFIG_DIRS instead.
|
|
for setting in kwinrc kwinrulesrc kscreenlockerrc ksmserverrc \
|
|
krunnerrc plasmanotifyrc powermanagementprofilesrc plasmarc \
|
|
plasmaparc; do
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/xdg/${setting}" \
|
|
"$STAGE/etc/ekklesia-classroom/xdg/${setting}"
|
|
done
|
|
|
|
# kdeglobals is composed rather than copied: the session policy plus the
|
|
# dark palette itself. Naming a colour scheme does not produce one, and a
|
|
# room whose user profile had never had a scheme applied came up light.
|
|
install -d "$STAGE/etc/ekklesia-classroom/xdg"
|
|
"$ROOT/tools/build-kdeglobals" > "$STAGE/etc/ekklesia-classroom/xdg/kdeglobals"
|
|
chmod 0644 "$STAGE/etc/ekklesia-classroom/xdg/kdeglobals"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/environment/90-ekklesia-classroom.conf" \
|
|
"$STAGE/etc/environment.d/90-ekklesia-classroom.conf"
|
|
|
|
# The session shortcuts, and deliberately NOT in the xdg directory above.
|
|
#
|
|
# kglobalacceld reads ~/.config/kglobalshortcutsrc as a SimpleConfig: no
|
|
# cascade, no system directories. Measured — with this file in the
|
|
# cascade, kreadconfig6 reported the chord unbound while the shortcut
|
|
# server went on answering Ctrl+Alt+Del. classroom-desktop-reset copies
|
|
# this into the teacher's home before the shortcut server starts, the
|
|
# same way the panel is copied out of the package at every login.
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/kglobalshortcutsrc" \
|
|
"$STAGE/etc/ekklesia-classroom/kglobalshortcutsrc"
|
|
|
|
# The one that actually reaches a session started by a display manager.
|
|
# startplasma sources this directory; PAM does not read environment.d, so
|
|
# without this file none of the settings above are in the cascade at all
|
|
# and the room comes up as stock Plasma. Measured, on a real machine.
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/env/zz-ekklesia-classroom.sh" \
|
|
"$STAGE/etc/xdg/plasma-workspace/env/zz-ekklesia-classroom.sh"
|
|
|
|
# The power button does nothing. Two layers, because while a session is
|
|
# running PowerDevil holds logind's inhibitor and would overrule it.
|
|
install -Dm644 \
|
|
"$ROOT/config/systemd/logind-ekklesia-classroom.conf" \
|
|
"$STAGE/etc/systemd/logind.conf.d/ekklesia-classroom.conf"
|
|
|
|
for scheme in EkklesiaDark EkklesiaLight; do
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/colors/${scheme}.colors" \
|
|
"$STAGE/usr/share/color-schemes/${scheme}.colors"
|
|
done
|
|
|
|
LOOK="$STAGE/usr/share/plasma/look-and-feel/org.ekklesia.classroom.desktop"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/lookandfeel/metadata.json" \
|
|
"$LOOK/metadata.json"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/lookandfeel/contents/defaults" \
|
|
"$LOOK/contents/defaults"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/lookandfeel/contents/layouts/org.kde.plasma.desktop-layout.js" \
|
|
"$LOOK/contents/layouts/org.kde.plasma.desktop-layout.js"
|
|
|
|
# NO SHELL PACKAGE OF OUR OWN.
|
|
#
|
|
# Plasma 6.3 loads the volume display from the shell package and from
|
|
# nowhere else — the look and feel is not consulted, which was measured —
|
|
# so a shell package is the only supported way to replace it, and a
|
|
# classroom-sized one was built and tried. With it selected, plasmashell
|
|
# builds no panel at all: not the stock one, not ours. Measured twice, and
|
|
# the room's panel is deleted at every login on purpose, so every login
|
|
# would have come up with nothing on the screen.
|
|
#
|
|
# The volume display is Plasma's own instead. UI_SCALE makes it the right
|
|
# size on a television, which is what the room actually needed.
|
|
|
|
# The room's Plasma style: the card a notification and the volume display
|
|
# are drawn on. Only the pieces the classroom changes; everything else
|
|
# comes from Breeze, so this can never leave a popup undrawn.
|
|
STYLE="$STAGE/usr/share/plasma/desktoptheme/ekklesia"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/desktoptheme/metadata.json" \
|
|
"$STYLE/metadata.json"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/desktoptheme/dialogs/background.svg" \
|
|
"$STYLE/dialogs/background.svg"
|
|
|
|
for entry in "$ROOT"/config/plasma/applications/*.desktop; do
|
|
install -Dm644 "$entry" \
|
|
"$STAGE/usr/share/applications/$(basename "$entry")"
|
|
done
|
|
|
|
# Shadows Chrome's own entry. XDG_DATA_DIRS searches /usr/local/share first,
|
|
# so the panel matches a Chrome window to this launcher instead of to
|
|
# Chrome's, and the room gets one button rather than two.
|
|
for entry in "$ROOT"/config/plasma/applications-local/*.desktop; do
|
|
install -Dm644 "$entry" \
|
|
"$STAGE/usr/local/share/applications/$(basename "$entry")"
|
|
done
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/solid/ekklesia-dvd.desktop" \
|
|
"$STAGE/usr/share/solid/actions/ekklesia-dvd.desktop"
|
|
|
|
# Shadows the old notification daemon's D-Bus activation. Deactivating its
|
|
# systemd unit is not enough: D-Bus starts it on demand from a file
|
|
# mako-notifier owns, and the crash-recovery test on a migrated machine
|
|
# caught it doing exactly that while the panel was down.
|
|
install -Dm644 \
|
|
"$ROOT/config/dbus/fr.emersion.mako.service" \
|
|
"$STAGE/usr/local/share/dbus-1/services/fr.emersion.mako.service"
|
|
|
|
# Shadows Plasma's session screen. Ctrl+Alt+Delete asks D-Bus to start it;
|
|
# with this in front of plasma-workspace's own file there is nothing to
|
|
# start. See the file itself for why the unbound chord is not enough on
|
|
# its own.
|
|
install -Dm644 \
|
|
"$ROOT/config/dbus/org.kde.LogoutPrompt.service" \
|
|
"$STAGE/usr/local/share/dbus-1/services/org.kde.LogoutPrompt.service"
|
|
|
|
# Two marks the classroom draws itself, because nothing in Breeze says
|
|
# either thing: a lesson, and fetching a child's grown-up.
|
|
for icon in ekklesia-wonderink ekklesia-parent-call; do
|
|
install -Dm644 \
|
|
"$ROOT/config/icons/${icon}.svg" \
|
|
"$STAGE/usr/share/icons/hicolor/scalable/apps/${icon}.svg"
|
|
done
|
|
|
|
# The panel is the only way a teacher has of getting anywhere. Plasma gives
|
|
# up restarting it after three crashes in a minute; this does not.
|
|
install -Dm644 \
|
|
"$ROOT/systemd/user/plasma-plasmashell.service.d/ekklesia-classroom.conf" \
|
|
"$STAGE/etc/systemd/user/plasma-plasmashell.service.d/ekklesia-classroom.conf"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/systemd/user/ekklesia-classroom-audio.service" \
|
|
"$STAGE/etc/systemd/user/ekklesia-classroom-audio.service"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/systemd/user/ekklesia-classroom-desktop.service" \
|
|
"$STAGE/etc/systemd/user/ekklesia-classroom-desktop.service"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-wonderink" \
|
|
"$STAGE/usr/local/bin/classroom-wonderink"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-audio" \
|
|
"$STAGE/usr/local/bin/classroom-audio"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-parent-call" \
|
|
"$STAGE/usr/local/bin/classroom-parent-call"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-desktop-layout" \
|
|
"$STAGE/usr/local/bin/classroom-desktop-layout"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-admin-terminal" \
|
|
"$STAGE/usr/local/bin/classroom-admin-terminal"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-desktop-reset" \
|
|
"$STAGE/usr/local/bin/classroom-desktop-reset"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-theme" \
|
|
"$STAGE/usr/local/bin/classroom-theme"
|
|
|
|
# Converges a machine that used to run something else. Called from
|
|
# postinst on every install, and by hand by a technician.
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-migrate" \
|
|
"$STAGE/usr/local/bin/classroom-migrate"
|
|
|
|
# One number, one place to ask for it.
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-ui-scale" \
|
|
"$STAGE/usr/local/bin/classroom-ui-scale"
|
|
|
|
# The room's display size: a hidden dialog behind a chord, a writer that
|
|
# asks for an administrator password, and the one thing that applies the
|
|
# answer at every login.
|
|
for command in classroom-display-settings classroom-set-scale; do
|
|
install -Dm755 \
|
|
"$ROOT/scripts/${command}" \
|
|
"$STAGE/usr/local/bin/${command}"
|
|
done
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/polkit/org.ekklesia.classroom.display.policy" \
|
|
"$STAGE/usr/share/polkit-1/actions/org.ekklesia.classroom.display.policy"
|
|
|
|
# The classroom user cannot suspend or hibernate the room. A vendor rule
|
|
# in /usr/share, not /etc, so a technician can override it by dropping a
|
|
# file of the same name into /etc/polkit-1/rules.d.
|
|
install -Dm644 \
|
|
"$ROOT/config/polkit/org.ekklesia.classroom.sleep.rules" \
|
|
"$STAGE/usr/share/polkit-1/rules.d/49-ekklesia-classroom-sleep.rules"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/plasma/autostart/ekklesia-classroom-scale.desktop" \
|
|
"$STAGE/etc/xdg/autostart/ekklesia-classroom-scale.desktop"
|
|
|
|
# The panel's disc player follows this machine's hardware, and the
|
|
# detection has to have happened before a session starts.
|
|
install -Dm644 \
|
|
"$ROOT/systemd/layout/ekklesia-classroom-layout.service" \
|
|
"$STAGE/etc/systemd/system/ekklesia-classroom-layout.service"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/udev/60-ekklesia-classroom-optical.rules" \
|
|
"$STAGE/etc/udev/rules.d/60-ekklesia-classroom-optical.rules"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/lib/classroom_audio.py" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_audio.py"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/lib/classroom_parent_call.py" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_parent_call.py"
|
|
|
|
# The notifier the MQTT service uses to put a church message on screen.
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-notify" \
|
|
"$STAGE/usr/local/bin/classroom-notify"
|
|
|
|
install -Dm755 \
|
|
"$ROOT/scripts/classroom-notify-test" \
|
|
"$STAGE/usr/local/bin/classroom-notify-test"
|
|
|
|
|
|
install -Dm644 \
|
|
"$ROOT/lib/classroom_optical.py" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_optical.py"
|
|
|
|
# The DVD overlay draws its own control bar as a layer-shell surface, so it
|
|
# still needs the icon and stylesheet helpers the dock used to share.
|
|
install -Dm644 \
|
|
"$ROOT/lib/classroom_icons.py" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_icons.py"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/lib/classroom_style.py" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/classroom_style.py"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/icons/dvd.svg" \
|
|
"$STAGE/etc/ekklesia-classroom/icons/dvd.svg"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/config/overlay/style.css.in" \
|
|
"$STAGE/etc/ekklesia-classroom/overlay/style.css.in"
|
|
|
|
# DVD mode control bar.
|
|
for icon in media-play media-pause chapter-prev chapter-next \
|
|
disc-menu eject close; do
|
|
install -Dm644 \
|
|
"$ROOT/config/icons/${icon}.svg" \
|
|
"$STAGE/etc/ekklesia-classroom/icons/${icon}.svg"
|
|
done
|
|
|
|
printf '%s\n' "$VERSION" > "$ROOT/VERSION"
|
|
|
|
install -Dm644 \
|
|
"$ROOT/VERSION" \
|
|
"$STAGE/usr/local/lib/ekklesia-classroom/VERSION"
|
|
|
|
dpkg-deb \
|
|
--root-owner-group \
|
|
--build "$STAGE" "$OUTPUT"
|
|
|
|
echo
|
|
echo "Built:"
|
|
echo "$OUTPUT"
|
|
sha256sum "$OUTPUT"
|