Incorporating Greptile feedback from PR 442.

persistence.conf was writing `union,source=...` entries.  On the first boot
that did not matter because the bootstrap performed a real `mount --bind`
itself; from the second boot onward, however, live-boot's initramfs reads
persistence.conf and applies the entries as OverlayFS union mounts.
PostgreSQL does not support OverlayFS — switching to `bind,source=...`
makes the in-band mount and the initramfs mount match and avoids potential
data corruption.

The bootstrap script hardcoded Postgres version 15 (cluster check, create,
service-start), inconsistent with the chroot hook which already derives it
dynamically.  Switched to discovery via `/usr/lib/postgresql/<ver>` so a
postgresql-16 bump no longer requires touching this script.

The tippecanoe source tarball was the only externally-fetched artifact in
the chroot hook without a SHA256 pin.  Added one (computed from upstream
v2.79.0).

`RequiresMountsFor` covered only `/usr/lib/live/mount/medium`; live-boot on
newer releases mounts at `/run/live/medium`.  Listed all three paths the
bootstrap script itself searches so systemd orders the unit after whichever
mount actually exists.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Roland 2026-05-22 20:25:33 -06:00 • committed by lrnselfreliance
parent 5040349c46
commit 94d56f313a
3 changed files with 32 additions and 8 deletions

View file

@ -133,10 +133,15 @@ chmod +x /usr/local/bin/pmtiles
pmtiles version
# Build and bake in tippecanoe (used to build map search indexes).
# Hash pinned to detect tampering of the upstream release tarball.
TIPPECANOE_VERSION="2.79.0"
TIPPECANOE_SHA256="b0fd9df49b6efc988288ea48774822c6de19eb48428017f27ee0b3b01d44f05d"
TIPPECANOE_BUILD_DIR=$(mktemp -d)
curl -fsSL "https://github.com/felt/tippecanoe/archive/refs/tags/${TIPPECANOE_VERSION}.tar.gz" \
| tar -xz -C "${TIPPECANOE_BUILD_DIR}" --strip-components=1
-o /tmp/tippecanoe.tar.gz
echo "${TIPPECANOE_SHA256} /tmp/tippecanoe.tar.gz" | sha256sum -c -
tar -xz -C "${TIPPECANOE_BUILD_DIR}" --strip-components=1 -f /tmp/tippecanoe.tar.gz
rm /tmp/tippecanoe.tar.gz
(cd "${TIPPECANOE_BUILD_DIR}" && make -j"$(nproc)" && make install)
rm -rf "${TIPPECANOE_BUILD_DIR}"
tippecanoe --version

View file

@ -4,7 +4,11 @@ Documentation=https://github.com/lrnselfreliance/wrolpi
After=local-fs.target systemd-tmpfiles-setup.service
Before=postgresql.service wrolpi-api.service wrolpi-app.service wrolpi-kiwix.service wrolpi-controller.service wrolpi-first-startup.service wrolpi.target
Wants=local-fs.target
RequiresMountsFor=/usr/lib/live/mount/medium
# live-boot uses one of these mount points depending on version: newer
# releases default to /run/live/medium, older ones use /usr/lib/live/mount/medium
# or /lib/live/mount/medium. Cover all three so the unit is correctly ordered
# after whichever mount actually exists.
RequiresMountsFor=/usr/lib/live/mount/medium /run/live/medium /lib/live/mount/medium
[Service]
Type=oneshot

View file

@ -102,10 +102,16 @@ chown wrolpi:wrolpi /mnt/persistence/wrolpi
# Write persistence.conf so live-boot's initramfs persistence machinery can
# apply these bind mounts before systemd starts on subsequent boots.
#
# `bind` (not `union`) is critical: `union` instructs live-boot to apply an
# OverlayFS union mount, which PostgreSQL explicitly does not support and
# which would silently corrupt data from the second boot onward. On first
# boot bind_if_unmounted below does a real bind mount; on subsequent boots
# live-boot's initramfs reads this file and must do the same.
cat > /mnt/persistence/persistence.conf <<EOF
/var/lib/postgresql union,source=postgresql-data
/etc/postgresql union,source=postgresql-config
/media/wrolpi union,source=wrolpi
/var/lib/postgresql bind,source=postgresql-data
/etc/postgresql bind,source=postgresql-config
/media/wrolpi bind,source=wrolpi
EOF
# --- Bind mounts (idempotent — only mount if not already mounted) -------
@ -121,13 +127,22 @@ bind_if_unmounted /mnt/persistence/postgresql-config /etc/postgresql
bind_if_unmounted /mnt/persistence/wrolpi /media/wrolpi
# --- Postgres cluster ----------------------------------------------------
# Derive version from the installed Postgres binary so this stays correct if
# the package list is later bumped past postgresql-15. This matches what
# the chroot hook does when dropping the default cluster.
if ! pg_lsclusters -h | awk '{print $1,$2}' | grep -q "^15 main$"; then
PG_VERSION=$(ls /usr/lib/postgresql 2>/dev/null | sort -n | tail -1)
if [ -z "$PG_VERSION" ]; then
log "ERROR: no postgresql server package found under /usr/lib/postgresql"
exit 1
fi
if ! pg_lsclusters -h | awk '{print $1,$2}' | grep -q "^${PG_VERSION} main$"; then
progress "Setting up Postgres cluster..."
pg_createcluster 15 main
pg_createcluster "${PG_VERSION}" main
fi
progress "Starting Postgres..."
systemctl start postgresql@15-main.service
systemctl start "postgresql@${PG_VERSION}-main.service"
# --- WROLPi DB schema + initial config import ----------------------------