d05f13a080
The server publishes 8080 on the Kvitt Pi's LAN interfaces and trusts X-Forwarded-For only from HA_HOST, NPM's LAN address (an IPv4 literal, checked by install.sh). KVITT_PUBLIC_HOST (owner-chosen, not icehack.asuscomm.com, which is NPM's proxy host for Home Assistant) builds KVITT_PUBLIC_URL. Only fcm-service-account.json and rclone.conf are installed; install.sh removes the Caddyfile, the Home Assistant SSH key, known_hosts and the certs and caddy_data volumes left by the earlier stack. Health checks: port 8080, then through NPM. The cert-sync image leaves the workflow and build-images.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TQd3pEP9UeN2uifbHknQ7B
43 lines
2.3 KiB
Bash
Executable File
43 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Put the APKs that infra/publish-apk.sh made on the Mac into the server's data volume (SPEC §10.6).
|
|
# The owner copies infra/pi/out/apk/ from the Mac to /opt/kvitt/apk/ on the Pi, then runs ON the Pi:
|
|
# /opt/kvitt/install-apk.sh
|
|
# Copies every kvitt-<version_code>.apk from /opt/kvitt/apk into /data/apk, then latest.json last and atomically
|
|
# (temp file, rename), so the server never announces a file it does not have; keeps the newest 5 APKs in /data/apk.
|
|
# R8 mapping files (kvitt-<version_code>.mapping.txt) stay in /opt/kvitt/apk; the server never needs them.
|
|
set -euo pipefail
|
|
here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=lib.sh
|
|
. "$here/lib.sh"
|
|
|
|
src="$KVITT_DIR/apk"
|
|
[[ -f "$src/latest.json" ]] || die "no $src/latest.json: copy infra/pi/out/apk/ from the Mac first (README, Publishing an APK)"
|
|
file_name=$(sed -n 's/.*"file_name": *"\([^"]*\)".*/\1/p' "$src/latest.json")
|
|
[[ "$file_name" =~ ^kvitt-[0-9]+\.apk$ ]] || die "latest.json has no valid file_name"
|
|
[[ -f "$src/$file_name" ]] || die "latest.json names $file_name, which is not in $src"
|
|
sha=$(sed -n 's/.*"sha256": *"\([0-9a-f]\{64\}\)".*/\1/p' "$src/latest.json")
|
|
[[ "$(sha256sum "$src/$file_name" | cut -d' ' -f1)" == "$sha" ]] || die "$file_name does not match the sha256 in latest.json"
|
|
|
|
# backup runs as uid 10001, the owner of /data, and has a shell; the server image has none.
|
|
# shellcheck disable=SC2016 # the script runs inside the backup container
|
|
compose run --rm --no-deps -T -v "$src:/incoming:ro" --entrypoint /bin/sh backup -c '
|
|
set -eu
|
|
mkdir -p /data/apk
|
|
for f in /incoming/kvitt-*.apk; do
|
|
[ -f "$f" ] || continue
|
|
n=$(basename "$f")
|
|
[ -f "/data/apk/$n" ] && cmp -s "$f" "/data/apk/$n" && continue
|
|
cp "$f" "/data/apk/.$n.tmp" && mv -f "/data/apk/.$n.tmp" "/data/apk/$n"
|
|
echo "copied $n"
|
|
done
|
|
cp /incoming/latest.json /data/apk/.latest.json.tmp
|
|
mv -f /data/apk/.latest.json.tmp /data/apk/latest.json
|
|
# keep the newest 5 APKs by version code
|
|
ls /data/apk | sed -n "s/^kvitt-\([0-9]*\)\.apk$/\1/p" | sort -n -r | tail -n +6 | while read -r v; do
|
|
rm -f "/data/apk/kvitt-$v.apk"; echo "removed kvitt-$v.apk"
|
|
done
|
|
echo "latest.json installed"'
|
|
say "GET $SERVER_URL/apk/latest:"
|
|
curl -fsS --max-time 15 "$SERVER_URL/apk/latest" || die "GET /apk/latest failed"
|
|
echo
|