The library-ownership migration compared the owner of
/mnt/persistence/wrolpi after creating it, so on a new persistence
partition the root-owned directory always looked like an old library and
the first-boot dialog said "Updated the library's ownership for this
WROLPi version". Only re-own a library that already existed.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
ISOs before wrolpi became a system account wrote the Live USB's library on
the persistence partition as UID 1000. Upgrading such a USB with a newer
ISO (wrolpi-usb.sh upgrade) keeps the persistence partition, so the library
would belong to the live session's "user" and the services could not write
to it. Bootstrap now re-owns the library once when its owner is not this
image's wrolpi. Live USBs only: installed systems' drives are left alone.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
wrolpi-bootstrap.sh created controller.yaml on installed systems, which
hid the onboarding wizard. Installed systems now wait for the wizard,
whose repair.sh finishes setup.
"Run repair without external drive" now writes controller.yaml before
starting repair, so the wizard does not return after repair.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
All three build targets move from Debian 12/bookworm to Debian 13/trixie
for fresh installs; existing Debian 12 systems remain supported in place.
Docker: api/help on python:3.13-trixie, controller on 3.13-slim-trixie,
app on node:20-trixie (matches trixie's nodejs 20), samba/zim on
debian:13. Full backend suite passes on Python 3.13 in the api container.
debian-live-config: --distribution trixie; postgres teardown for the
SQLite cutover (pg_dropcluster hook block removed, wrolpi-bootstrap.sh no
longer creates a cluster or calls the deleted initialize_api_db.sh — the
API creates wrolpi.db itself on first start). README documents the
SQLite layout and drops Etcher recommendations.
pi-gen: upstream has no trixie branch — the arm64 branch now defaults to
RELEASE=trixie; KEYBOARD_KEYMAP=en_US is rejected by trixie's
console-setup (ckbcomp validates), use 'us'; stop stamping a Postgres
.pgpass into /etc/skel.
Package lists (both targets): postgresql-15/postgresql-doc/libpq-dev
deleted; libtiff5-dev renamed to libtiff-dev; software-properties-common
and cpufrequtils removed from trixie (Controller CPU throttle falls back
to sysfs, dead cpufreq-set sudoers rule removed); locales and gnupg added
(no longer arrive transitively under --apt-recommends false); sqlite3 CLI
added for reset_tags.sh.
help.sh: replace the Postgres service/port/socket/cluster/psql checks
(all false FAILEDs after the SQLite cutover) with SQLite checks:
wrolpi.db exists, PRAGMA quick_check, file_group table + row count, run
as the wrolpi user so root never creates the -shm sidecar.
Both build scripts take a WROLPI_BUILD_DIR override so development builds
can run beside the release pipeline's build trees; the sudo re-exec
passes it through explicitly (a plain sudo would drop it).
test_common.py: the truncate tests hard-coded sys.getsizeof results from
the 3.11 object layout (str/list shrank in 3.12); assert the contract
(fits budget, prefix, monotonic in budget) so they pass on 3.11 and 3.13.
Verified: trixie ISO (3.7G) and pi-gen desktop image (4.3G) both built
from scratch and passed their sanity checks.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
wrolpi-bootstrap.service applied the /media/wrolpi/config/postgresql
bind-mounts over /var/lib/postgresql and /etc/postgresql at every boot,
including on installed systems. The binds exist for live boots, where
the root filesystem is an ephemeral overlay; on an installed system they
put the cluster in the path of repair.sh's config chown
(pg_filenode.map permission errors) and, once the user mounts an
NTFS/exFAT primary drive over /media/wrolpi, point Postgres at a
filesystem that cannot host a data directory at all — no clusters,
connection refused, while the umbrella postgresql.service stays green.
Installed systems now keep Postgres at the normal Debian paths on the
root filesystem. A box that still has a stale bind active from an old
boot gets a log note to reboot; on the first clean boot the existing
pg_createcluster/initialize_api_db logic builds the root-disk cluster
automatically and the database rebuilds from configs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Etcher is privacy-invasive; replace it in INSTALL.md, the USB upgrade
tool messages, and the live-boot ephemeral warning.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Treat virtual disks (vd*/xvd*/hd*) as direct, not ephemeral. A blank
VM disk imaged with the ISO can safely hold a persistence partition;
previously these fell through the wildcard to loop mode and never
accumulated state.
- Move the ephemeral note_action inside the mountpoint guard so a manual
wrolpi-bootstrap.service restart mid-session doesn't re-fire the "NOT
writing to disk" first-boot dialog.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
wrolpi-bootstrap.sh now classifies the live medium by device-node
pattern. Real partitions (/dev/sd*, /dev/nvme*, /dev/mmcblk*) continue
to get a persistence partition appended. Loop/device-mapper sources
(/dev/loop*, /dev/dm-*, /dev/mapper/*) — the marker for Ventoy/YUMI/
Easy2Boot/etc — mount a tmpfs at /media/wrolpi instead, so we never
sfdisk-append a partition onto the user's multiboot stick.
First-boot zenity dialog branches on mode and tells ephemeral users
their data won't persist; README documents the behaviour and the
deferred persistence.dat work.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The persistence partition is created immediately after the ISO partition
ends (1-MiB aligned). When `wrolpi-usb.sh upgrade` overwrites the ISO
partition with a future, possibly-larger ISO, growth past the current
ISO size would overwrite persistence-partition sectors.
Reserve 8 GiB between them on first boot. Future ISO releases up to
roughly 2x the current size (~3.3 GB) can be written into that gap
without touching persistence.
The cost is ~8 GiB of persistence the user can't reclaim. On a typical
128 GB USB this is ~6% of total capacity, which is comparable to
filesystem overhead and rounding loss.
Existing USBs flashed before this commit have no headroom — they need
a one-time backup-and-reflash to pick it up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Splash:
Shifted the logo + text block up by half a logo-height. GRUB's menu
renders centred over the splash; the previous placement put the icon
directly behind the menu entries.
First-boot summary:
wrolpi-bootstrap.sh now accumulates a short list of notable actions
(partition created, Postgres cluster set up, DB initialised) and
writes them to /tmp/wrolpi-firstboot-summary.txt. A new XDG autostart
(wrolpi-firstboot-notify) reads that file once XFCE comes up and shows
a zenity dialog telling the user what just happened — answering the
"wait, what did this thing just do to my USB drive?" question.
Subsequent boots where the bootstrap is a no-op write no summary file,
so the dialog only appears the boot it actually matters. /tmp is tmpfs,
so the file is also naturally per-boot.
Adds zenity to the package list (not pulled by --apt-recommends false).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two parallel live-build configs (debian-live-config/ for the installer
ISO and wrolpi-portable/ for the Live USB) carry the same chroot hook
with subtly different fixes — the portable side had accumulated the
better implementation (npm build, SHA-pinned blobs, dynamic Postgres
version, partition-by-start-sector, controller.yaml sentinel, autologin,
branding). This commit folds those improvements into debian-live-config/
and retires wrolpi-portable/.
The Postgres data + config directories now bind-mount to
/media/wrolpi/config/postgresql/{data,config} regardless of deployment
shape (Live USB, Calamares-installed system with external drive,
Calamares-installed system with no external drive). Result: pulling
a WROLPi external drive from one host and plugging into another
brings the entire indexed library along — no re-indexing. Previously
the DB lived on /mnt/persistence/postgresql-{data,config} on Portable
and on /var/lib/postgresql (root) everywhere else; moving a drive
required rebuilding the DB on the new host.
Single wrolpi-bootstrap.{sh,service} replaces wrolpi-portable-bootstrap.
The script detects deployment by probing for a live-boot medium mount:
present → Live (create persistence partition if missing); absent →
Installed (skip partition step; Postgres bind-mount and cluster init
still run). --debian-installer is dropped from lb config; Calamares
will land in a follow-up commit as the graphical installer.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>