feat: four-part versions, and a published version is never used again
0.2.6.1 is a maintenance release of 0.2.6. The build refused four parts, update_canary.sh's automatic bump could not add one to "6.1", and neither publish script would have noticed a version being published twice — which is what happened to 0.2.6 this morning: it was rebuilt with the Presentations hardening and uploaded over the first 0.2.6, and a room that had installed the first can never be offered the second. One release library now holds the version pattern (three or four parts, no leading zeros, no .0 maintenance), orders by dpkg --compare-versions, refuses a version that has ever been published or is not newer than all of them, uploads with --ignore-existing and checks the server's checksum, writes a manifest only for a package the server holds, and reads the channel back over HTTPS afterwards. update_canary.sh takes the version explicitly; update_stable.sh refuses to go backwards. The classroom updater refuses a manifest whose version, package name or checksum is malformed, and refuses a download whose own control file is not the version the manifest promised, so a room can never loop on reinstalling and rebooting. tests/test-release-versions.sh: 87 checks against a stand-in server and real dpkg. The Trixie gate now also rehearses a stable room: 0.2.2 to an interim 0.2.6.1 upgraded with settings, channel and Presentations=false intact, and the installed updater answering correctly. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6f2d169355
commit
690ef95aff
+14
-5
@@ -11,11 +11,10 @@ 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
|
||||
# Three parts for a feature release, four for a maintenance release of
|
||||
# one: 0.2.6, then 0.2.6.1. See tools/release-lib.sh.
|
||||
source "$ROOT/tools/release-lib.sh"
|
||||
release_require_version "$VERSION" || exit 1
|
||||
|
||||
STAGE="$ROOT/packaging/root"
|
||||
OUTPUT="$ROOT/dist/ekklesia-classroom_${VERSION}_amd64.deb"
|
||||
@@ -568,6 +567,16 @@ dpkg-deb \
|
||||
--root-owner-group \
|
||||
--build "$STAGE" "$OUTPUT"
|
||||
|
||||
# The version dpkg reads out of the file is the one a classroom will
|
||||
# report, so it is checked rather than assumed to have survived the sed.
|
||||
built_version="$(release_package_version "$OUTPUT")"
|
||||
|
||||
if [[ "$built_version" != "$VERSION" ]]; then
|
||||
echo "The package says it is $built_version, not $VERSION" >&2
|
||||
rm -f "$OUTPUT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Built:"
|
||||
echo "$OUTPUT"
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
# Release helpers shared by tools/build-release.sh, update_canary.sh and
|
||||
# update_stable.sh. Sourced, not run.
|
||||
#
|
||||
# VERSIONS.
|
||||
#
|
||||
# 0.2.6 a feature release
|
||||
# 0.2.6.1 the first maintenance release of 0.2.6
|
||||
# 0.2.6.2 the second
|
||||
# 0.2.7 the next feature release
|
||||
#
|
||||
# Three or four dot-separated numbers, and nothing else. No leading zeros,
|
||||
# because dpkg compares 0.2.06 and 0.2.6 as the SAME version, and two
|
||||
# packages that dpkg thinks are equal are one package too many. No fourth
|
||||
# part of 0: maintenance releases count from 1, and 0.2.6.0 would sort
|
||||
# after 0.2.6 while claiming to be it.
|
||||
#
|
||||
# Ordering is dpkg's, always, through `dpkg --compare-versions`. That is
|
||||
# what a classroom's updater and apt use to decide what is newer, so
|
||||
# anything else here could only ever disagree with them.
|
||||
#
|
||||
# PUBLISHED IS PERMANENT.
|
||||
#
|
||||
# 0.2.6 was rebuilt and uploaded a second time under the same version, and
|
||||
# the second upload replaced the first on the server. A room that had
|
||||
# installed the first one could never be offered the second: the updater
|
||||
# only installs a version newer than its own, and they were equal. So a
|
||||
# version number, once it has been on the server, is never used again,
|
||||
# and a package file on the server is never written twice.
|
||||
|
||||
RELEASE_HOST="${RELEASE_HOST:-classroom-control}"
|
||||
RELEASE_ROOT="${RELEASE_ROOT:-/srv/ekklesia/classroom-updates}"
|
||||
RELEASE_URL="${RELEASE_URL:-https://updates.riverofglorymn.org}"
|
||||
# The local copy of what was published. ROOT is the checkout, set by
|
||||
# whichever script sourced this.
|
||||
RELEASE_LOCAL="${RELEASE_LOCAL:-$ROOT/repo}"
|
||||
|
||||
# The same pattern is in scripts/ekklesia-classroom-update, which is what
|
||||
# a classroom checks a manifest against. tests/test-release-versions.sh
|
||||
# holds both to the same list of good and bad versions.
|
||||
RELEASE_VERSION_PATTERN='^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(\.[1-9][0-9]*)?$'
|
||||
|
||||
release_version_valid() {
|
||||
[[ "$1" =~ $RELEASE_VERSION_PATTERN ]]
|
||||
}
|
||||
|
||||
release_require_version() {
|
||||
if ! release_version_valid "$1"; then
|
||||
echo "Invalid version: $1" >&2
|
||||
echo "Expected MAJOR.MINOR.PATCH or MAJOR.MINOR.PATCH.MAINTENANCE," >&2
|
||||
echo "for example 0.2.7 or 0.2.6.1" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
release_version_gt() {
|
||||
dpkg --compare-versions "$1" gt "$2"
|
||||
}
|
||||
|
||||
release_package_name() {
|
||||
printf 'ekklesia-classroom_%s_amd64.deb\n' "$1"
|
||||
}
|
||||
|
||||
# The version dpkg itself reads out of a built package, which is the one a
|
||||
# classroom will report after installing it.
|
||||
release_package_version() {
|
||||
dpkg-deb --field "$1" Version
|
||||
}
|
||||
|
||||
release_remote() {
|
||||
ssh "$RELEASE_HOST" "$@"
|
||||
}
|
||||
|
||||
# Every version that has ever been published, one per line, read from the
|
||||
# package file names on the server and in the local copy of it. Names that
|
||||
# are not a classroom package (ekklesia-classroom-v2.deb) are skipped;
|
||||
# experiment builds such as 0.1.45~hypr1 are kept, because dpkg orders
|
||||
# them and they were published.
|
||||
release_published_versions() {
|
||||
{
|
||||
release_remote "ls -1 '$RELEASE_ROOT/packages'" || return 1
|
||||
ls -1 "$RELEASE_LOCAL/packages" 2>/dev/null || true
|
||||
} | sed -n 's/^ekklesia-classroom_\(.*\)_amd64\.deb$/\1/p' | sort -u
|
||||
}
|
||||
|
||||
release_highest() {
|
||||
local highest="" version
|
||||
|
||||
while read -r version; do
|
||||
[[ -n "$version" ]] || continue
|
||||
|
||||
if [[ -z "$highest" ]] || release_version_gt "$version" "$highest"; then
|
||||
highest="$version"
|
||||
fi
|
||||
done
|
||||
|
||||
printf '%s\n' "$highest"
|
||||
}
|
||||
|
||||
# The version a channel's manifest on the server names, or nothing.
|
||||
release_channel_version() {
|
||||
release_remote "cat '$RELEASE_ROOT/$1/manifest.json' 2>/dev/null" \
|
||||
| python3 -c 'import json, sys
|
||||
try:
|
||||
print(json.load(sys.stdin)["version"])
|
||||
except Exception:
|
||||
pass'
|
||||
}
|
||||
|
||||
# May VERSION be published as a new package at all? It has to be valid,
|
||||
# its file name must never have been used, and it must be newer than every
|
||||
# package ever published, so that it is newer than whatever any room is
|
||||
# running whichever channel that room is on.
|
||||
release_check_new_version() {
|
||||
local version="$1" name published highest
|
||||
|
||||
release_require_version "$version" || return 1
|
||||
name="$(release_package_name "$version")"
|
||||
|
||||
published="$(release_published_versions)" || {
|
||||
echo "Could not list the published packages on $RELEASE_HOST." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
if grep -qxF -- "$version" <<< "$published"; then
|
||||
echo "$version has already been published." >&2
|
||||
echo "A published version is never rebuilt or replaced. Use the next one." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if release_remote "test -e '$RELEASE_ROOT/packages/$name'"; then
|
||||
echo "$name already exists on $RELEASE_HOST." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
highest="$(release_highest <<< "$published")"
|
||||
|
||||
if [[ -n "$highest" ]] && ! release_version_gt "$version" "$highest"; then
|
||||
echo "$version is not newer than $highest, the highest version already published." >&2
|
||||
echo "Every release must sort after every one before it." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Upload a package that has never been on the server, and prove that what
|
||||
# arrived is what was built. --ignore-existing is the second lock on the
|
||||
# rule above: even if the check were wrong, rsync would not replace a
|
||||
# published file.
|
||||
release_upload_package() {
|
||||
local package="$1" name local_hash remote_hash
|
||||
|
||||
name="$(basename "$package")"
|
||||
local_hash="$(sha256sum "$package" | awk '{print $1}')"
|
||||
|
||||
rsync -av --ignore-existing -e ssh \
|
||||
"$package" "$RELEASE_HOST:$RELEASE_ROOT/packages/"
|
||||
|
||||
remote_hash="$(release_remote "sha256sum '$RELEASE_ROOT/packages/$name'" | awk '{print $1}')"
|
||||
|
||||
if [[ "$remote_hash" != "$local_hash" ]]; then
|
||||
echo "The package on $RELEASE_HOST does not match the one built here." >&2
|
||||
echo " built: $local_hash" >&2
|
||||
echo " on server: ${remote_hash:-missing}" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Write CHANNEL's manifest for VERSION locally, then upload it, then move
|
||||
# the channel's latest.deb. The package must already be on the server with
|
||||
# exactly the checksum the manifest is about to promise.
|
||||
release_publish_manifest() {
|
||||
local channel="$1" version="$2" hash="$3" name remote_hash
|
||||
|
||||
name="$(release_package_name "$version")"
|
||||
remote_hash="$(release_remote "sha256sum '$RELEASE_ROOT/packages/$name'" | awk '{print $1}')"
|
||||
|
||||
if [[ "$remote_hash" != "$hash" ]]; then
|
||||
echo "Refusing to point $channel at $name:" >&2
|
||||
echo " the manifest would say $hash" >&2
|
||||
echo " the server has ${remote_hash:-no such file}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
mkdir -p "$RELEASE_LOCAL/$channel"
|
||||
|
||||
cat > "$RELEASE_LOCAL/$channel/manifest.json" <<EOF
|
||||
{
|
||||
"version": "$version",
|
||||
"package": "/packages/$name",
|
||||
"sha256": "$hash",
|
||||
"requires_reboot": true
|
||||
}
|
||||
EOF
|
||||
|
||||
# Manifest deliberately goes LAST, after the package it names.
|
||||
rsync -av -e ssh \
|
||||
"$RELEASE_LOCAL/$channel/manifest.json" \
|
||||
"$RELEASE_HOST:$RELEASE_ROOT/$channel/manifest.json"
|
||||
|
||||
# THE PERMANENT URL.
|
||||
#
|
||||
# .../CHANNEL/latest.deb is a symlink beside the manifest pointing at
|
||||
# the versioned package the manifest names, so there is one download
|
||||
# address that never changes and still no second place recording which
|
||||
# version is current. The manifest remains the only answer to that
|
||||
# question.
|
||||
#
|
||||
# It is swapped AFTER the manifest, and by rename, for two reasons. A
|
||||
# rename is atomic, so nothing ever downloads a half-written pointer;
|
||||
# and going last means latest.deb can only ever lag the manifest by a
|
||||
# moment, never lead it — it can never offer a package the channel has
|
||||
# not published. The versioned file itself is never touched again once
|
||||
# uploaded.
|
||||
release_remote "
|
||||
set -e
|
||||
cd '$RELEASE_ROOT/$channel'
|
||||
test -f ../packages/$name
|
||||
ln -sfn ../packages/$name latest.deb.new
|
||||
mv -Tf latest.deb.new latest.deb
|
||||
"
|
||||
}
|
||||
|
||||
# What a classroom on CHANNEL actually sees, read over HTTPS the way the
|
||||
# updater reads it: the manifest, the versioned package it names, and the
|
||||
# permanent latest.deb, all agreeing with each other and with EXPECTED if
|
||||
# one is given. Read-only; safe to run against stable at any time.
|
||||
#
|
||||
# A subshell, so the temporary directory is removed however it returns.
|
||||
release_verify_channel() (
|
||||
channel="$1"
|
||||
expected="${2:-}"
|
||||
work="$(mktemp -d)"
|
||||
trap 'rm -rf "$work"' EXIT
|
||||
|
||||
manifest="$(curl -fsS -H 'Cache-Control: no-cache' \
|
||||
"$RELEASE_URL/$channel/manifest.json")" || {
|
||||
echo " FAIL $channel: manifest could not be fetched" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
read -r version package hash < <(python3 -c 'import json, sys
|
||||
m = json.loads(sys.argv[1])
|
||||
print(m["version"], m["package"], m["sha256"])' "$manifest")
|
||||
|
||||
name="$(release_package_name "$version")"
|
||||
|
||||
if [[ -n "$expected" && "$version" != "$expected" ]]; then
|
||||
echo " FAIL $channel: manifest says $version, expected $expected" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$package" != "/packages/$name" ]]; then
|
||||
echo " FAIL $channel: manifest names $package for version $version" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
curl -fsS -o "$work/versioned.deb" "$RELEASE_URL$package" || {
|
||||
echo " FAIL $channel: $package could not be downloaded" >&2
|
||||
return 1
|
||||
}
|
||||
curl -fsSL -H 'Cache-Control: no-cache' -o "$work/latest.deb" \
|
||||
"$RELEASE_URL/$channel/latest.deb" || {
|
||||
echo " FAIL $channel: latest.deb could not be downloaded" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
got_hash="$(sha256sum "$work/versioned.deb" | awk '{print $1}')"
|
||||
latest_hash="$(sha256sum "$work/latest.deb" | awk '{print $1}')"
|
||||
deb_version="$(release_package_version "$work/versioned.deb")"
|
||||
|
||||
if [[ "$got_hash" != "$hash" ]]; then
|
||||
echo " FAIL $channel: $name has sha256 $got_hash, manifest says $hash" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$latest_hash" != "$hash" ]]; then
|
||||
echo " FAIL $channel: latest.deb has sha256 $latest_hash, manifest says $hash" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$deb_version" != "$version" ]]; then
|
||||
echo " FAIL $channel: the package itself says $deb_version, manifest says $version" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo " ok $channel: $version, $name, sha256 $hash, latest.deb agrees"
|
||||
)
|
||||
@@ -18,6 +18,16 @@ if [[ $# -eq 2 ]]; then
|
||||
[[ -f "$previous" ]] || { echo "Package not found: $previous" >&2; exit 1; }
|
||||
fi
|
||||
|
||||
# The channel the upgraded room is on. canary by default, which is the
|
||||
# machine a new release goes to first; stable to rehearse the day the
|
||||
# desktops are moved, from the release they are actually on.
|
||||
channel="${VALIDATION_CHANNEL:-canary}"
|
||||
|
||||
case "$channel" in
|
||||
stable|canary) ;;
|
||||
*) echo "VALIDATION_CHANNEL must be stable or canary" >&2; exit 2 ;;
|
||||
esac
|
||||
|
||||
echo "Validating $(basename "$candidate") on Debian Trixie"
|
||||
|
||||
docker_args=(
|
||||
@@ -41,7 +51,7 @@ fi
|
||||
# instead teaches everybody to re-run it until it passes.
|
||||
timeout --signal=TERM --kill-after=15s 2700s \
|
||||
docker "${docker_args[@]}" debian:trixie-slim \
|
||||
bash -s -- "${previous:+/packages/previous.deb}" <<'CONTAINER'
|
||||
bash -s -- "${previous:+/packages/previous.deb}" "$channel" <<'CONTAINER'
|
||||
set -Eeuo pipefail
|
||||
|
||||
validation_failure() {
|
||||
@@ -87,6 +97,7 @@ run_logged() {
|
||||
run_logged apt-update 300 apt-get update -qq
|
||||
|
||||
previous="${1:-}"
|
||||
channel="${2:-canary}"
|
||||
|
||||
if [[ -n "$previous" ]]; then
|
||||
run_logged previous-install 1200 apt-get install -y -qq "$previous"
|
||||
@@ -94,7 +105,7 @@ if [[ -n "$previous" ]]; then
|
||||
cat > /etc/ekklesia-classroom/device.conf <<'CONFIG'
|
||||
# Configuration carried forward from 0.1.36
|
||||
UPDATE_URL=https://updates.riverofglorymn.org
|
||||
CHANNEL=canary
|
||||
CHANNEL=@CHANNEL@
|
||||
DVD_ENABLED=false
|
||||
UI_SCALE=1.25
|
||||
MQTT_ENABLED=true
|
||||
@@ -104,10 +115,28 @@ MQTT_USERNAME=classroom
|
||||
MQTT_PASSWORD=preserve-me
|
||||
CUSTOM_SETTING=preserve-me-too
|
||||
CONFIG
|
||||
sed -i "s/@CHANNEL@/${channel}/" /etc/ekklesia-classroom/device.conf
|
||||
previous_version="$(dpkg-query -W -f='${Version}' ekklesia-classroom)"
|
||||
fi
|
||||
|
||||
run_logged candidate-install 1200 apt-get install -y -qq /packages/candidate.deb
|
||||
|
||||
# THE VERSION, AS THE MACHINE REPORTS IT.
|
||||
#
|
||||
# Three places say which release a classroom is running: dpkg's database,
|
||||
# which the updater compares against the manifest; the VERSION file the
|
||||
# package carries; and the file name the release was published under.
|
||||
# They have to be one number, or a room either never updates or updates
|
||||
# for ever.
|
||||
candidate_version="$(dpkg-deb --field /packages/candidate.deb Version)"
|
||||
[[ "$(dpkg-query -W -f='${Version}' ekklesia-classroom)" == "$candidate_version" ]]
|
||||
[[ "$(cat /usr/local/lib/ekklesia-classroom/VERSION)" == "$candidate_version" ]]
|
||||
echo "installed ekklesia-classroom $candidate_version${previous_version:+ over $previous_version}"
|
||||
|
||||
if [[ -n "${previous_version:-}" ]]; then
|
||||
dpkg --compare-versions "$candidate_version" gt "$previous_version"
|
||||
fi
|
||||
|
||||
command -v nmtui >/dev/null
|
||||
command -v lpadmin >/dev/null
|
||||
command -v lpinfo >/dev/null
|
||||
@@ -376,6 +405,64 @@ timeout --signal=TERM --kill-after=5s 45s classroom-provision \
|
||||
>/tmp/provision-second.log
|
||||
grep -q 'Elmer is already correctly configured' /tmp/provision-second.log
|
||||
|
||||
# THE UPDATER THIS PACKAGE INSTALLED, AGAINST A MANIFEST.
|
||||
#
|
||||
# Served from this container, so nothing reaches the real update server.
|
||||
# The installed version has to be "up to date" against a manifest naming
|
||||
# itself — or the room reinstalls and reboots at every check — and has to
|
||||
# see the next feature release as newer.
|
||||
mkdir -p /tmp/updates/packages "/tmp/updates/$channel"
|
||||
cp /packages/candidate.deb "/tmp/updates/packages/ekklesia-classroom_${candidate_version}_amd64.deb"
|
||||
|
||||
serve_manifest() {
|
||||
python3 - "$1" "$channel" <<'MANIFEST'
|
||||
import hashlib, json, sys
|
||||
version, channel = sys.argv[1], sys.argv[2]
|
||||
name = f"ekklesia-classroom_{version}_amd64.deb"
|
||||
try:
|
||||
digest = hashlib.sha256(open(f"/tmp/updates/packages/{name}", "rb").read()).hexdigest()
|
||||
except FileNotFoundError:
|
||||
digest = "0" * 64
|
||||
json.dump({"version": version, "package": f"/packages/{name}",
|
||||
"sha256": digest, "requires_reboot": True},
|
||||
open(f"/tmp/updates/{channel}/manifest.json", "w"))
|
||||
MANIFEST
|
||||
}
|
||||
|
||||
python3 -m http.server --bind 127.0.0.1 --directory /tmp/updates 8765 \
|
||||
>/tmp/updates.log 2>&1 &
|
||||
updates_server=$!
|
||||
sleep 1
|
||||
|
||||
cp /etc/ekklesia-classroom/device.conf /tmp/device.conf.before-updater
|
||||
sed -i 's|^UPDATE_URL=.*|UPDATE_URL=http://127.0.0.1:8765|' \
|
||||
/etc/ekklesia-classroom/device.conf
|
||||
|
||||
serve_manifest "$candidate_version"
|
||||
ekklesia-classroom-update --check >/tmp/updater-same.log 2>&1
|
||||
grep -q "Already up to date" /tmp/updater-same.log
|
||||
|
||||
# The next milestone after whatever this is, and a release every
|
||||
# classroom has long since passed.
|
||||
IFS=. read -r major minor _ <<< "$candidate_version"
|
||||
next_version="${major}.$((minor + 1)).0"
|
||||
|
||||
serve_manifest "$next_version"
|
||||
ekklesia-classroom-update --check >/tmp/updater-next.log 2>&1
|
||||
grep -q "Update available: $candidate_version -> $next_version" /tmp/updater-next.log
|
||||
|
||||
serve_manifest 0.2.2
|
||||
ekklesia-classroom-update --check >/tmp/updater-older.log 2>&1
|
||||
grep -q "Already up to date" /tmp/updater-older.log
|
||||
|
||||
echo '{"version": "0.2.06", "package": "/packages/x.deb", "sha256": "x"}' \
|
||||
> "/tmp/updates/$channel/manifest.json"
|
||||
! ekklesia-classroom-update --check >/tmp/updater-bad.log 2>&1
|
||||
grep -q "invalid version" /tmp/updater-bad.log
|
||||
|
||||
kill "$updates_server"
|
||||
cp /tmp/device.conf.before-updater /etc/ekklesia-classroom/device.conf
|
||||
|
||||
if [[ -n "$previous" ]]; then
|
||||
# The room's own values, untouched by the upgrade.
|
||||
grep -q '^DVD_ENABLED=false$' /etc/ekklesia-classroom/device.conf
|
||||
@@ -386,7 +473,17 @@ if [[ -n "$previous" ]]; then
|
||||
# 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
|
||||
grep -q "^CHANNEL=${channel}\$" /etc/ekklesia-classroom/device.conf
|
||||
|
||||
# An optional feature an existing room never had stays off. A
|
||||
# Presentations launcher appearing on the desktops' panels by itself
|
||||
# would be an upgrade changing a classroom, which upgrades do not do.
|
||||
[[ "$(grep -c '^PRESENTATIONS_ENABLED=' /etc/ekklesia-classroom/device.conf)" -eq 1 ]]
|
||||
grep -q '^PRESENTATIONS_ENABLED=false$' /etc/ekklesia-classroom/device.conf
|
||||
classroom-presentations 2>&1 | grep -q 'PRESENTATIONS_ENABLED is false'
|
||||
classroom-desktop-layout >/dev/null 2>&1 || true
|
||||
grep -q 'var PRESENTATIONS = false;' \
|
||||
/usr/share/plasma/look-and-feel/org.ekklesia.classroom.desktop/contents/layouts/org.kde.plasma.desktop-layout.js
|
||||
|
||||
# And a room that was carried through the experiment on its own
|
||||
# channel comes home, because that channel is the obsolete one now.
|
||||
@@ -395,7 +492,7 @@ if [[ -n "$previous" ]]; then
|
||||
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
|
||||
sed -i "s/^CHANNEL=.*/CHANNEL=${channel}/" /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
|
||||
@@ -415,7 +512,7 @@ if [[ -n "$previous" ]]; then
|
||||
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
|
||||
grep -q "^CHANNEL=${channel}\$" /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.
|
||||
|
||||
Reference in New Issue
Block a user