fix(calibre-web): apply the reader model on upgrades, not just fresh installs - #158
Merged
Merged
Conversation
…installs 1.2.1's Guest grant was written to run on existing installs — and could not. Everything this package writes to app.db lived in a custom-init hook, which only executes when the APP container starts; a release that changes only the init sidecar leaves the app container's compose config identical, so Hola's upgrade (`docker compose up -d`) correctly does not recreate it and the hook never runs. Observed on a live 0.11.0-rc.4 host: upgrading 1.1.2 -> 1.2.1 left `config_anonbrowse = 0` and `Guest 32`, and /opds answered 401 to a caller holding the correct Traefik credential. Anonymous browsing is the half that was never migrated at all — it was only ever set on first run. 1.1.x left /opds and /kobo/ exempt with no gate and Calibre-Web's own Basic auth in front; 1.2.x moves that gate to Traefik, which strips the credential once verified. An upgraded install therefore has the gate without the anonymous browsing that makes it serviceable, and answers 401 to every reader that just passed it. Three changes: - All app.db work moves into ONE script the sidecar writes, run from two places: the sidecar itself when app.db already exists (the upgrade), and the custom-init hook when it does not yet (the fresh install). A stamp file makes it a one-shot, so operator edits made later stand. - The library path keeps its own first-run-only guard: a configured install is never repointed. - A label on the calibre-web service, bumped when a change must reach a running container, so `up -d` recreates it and Calibre-Web re-reads its settings. Without this the sidecar's writes sit unread until something else restarts the app — and `hola restart` will not, since it is `up -d` too. Exercised in the real image across four paths: upgrade (32 -> 290, anonbrowse 0 -> 1), re-run (stamped no-op), operator turning anonymous browsing back off (left alone), and fresh install (sidecar writes nothing, hook applies once) — including an app.db that exists before Calibre-Web has created its tables, which now exits cleanly instead of raising. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vck5KSX2CLxhohx14nb5Sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Bundle 1.2.1 → 1.2.2. All
app.dbwork moves into one stamped script the sidecar runs on every deploy, plus a label that forces the app container to be recreated so the change is actually read.Why — #157 shipped a fix that could not run
I wrote 1.2.1's Guest grant deliberately outside the first-run guard so existing installs would get it. It never had a chance: everything this package writes to
app.dblives in a/custom-cont-init.dhook, and that only executes when the app container starts. A release that changes only the init sidecar leaves the calibre-web service's compose config byte-identical, sodocker compose up -dcorrectly leaves that container alone — and the hook never runs.Observed on a live host (Hola 0.11.0-rc.4), upgrading 1.1.2 → 1.2.1:
Anonymous browsing is the half that was never migrated at all — it was only ever set on first run. 1.1.x left
/opdsand/kobo/exempt with no gate and Calibre-Web's own Basic auth in front of them; 1.2.x moves that gate to Traefik, which strips the credential once verified (try-hola/hola#455). An upgraded install therefore gets the gate without the anonymous browsing that makes it serviceable, and answers401to every reader that just passed it. That is strictly worse than 1.1.x, where readers at least worked.How
/config/.hola-apply-reader-modeland runs it immediately whenapp.dbalready exists (the upgrade). When it does not exist yet — a fresh install, where s6 createsapp.dblater — the custom-init hook runs the same script. No duplicated logic./config/.hola-reader-model-v1written on success; from then on it is a no-op, so anything you change afterwards in the UI stands.io.try-hola.calibre-web.reader-model: "v1"on the calibre-web service. Changing a label changes the service config, so the upgrade recreates the container and Calibre-Web re-reads its settings. Without it the sidecar's writes sit unread — andhola restartwill not help, because that isup -dtoo. Bump the label whenever a package change has to reach a running container. Not insh.hola.*, which the platform owns and overwrites.Verification
In the real image (
lscr.io/linuxserver/calibre-web:0.6.26-ls393), four paths:README
Adds an Upgrading from 1.1.x section, including the part that bites operators: readers authenticated with a Calibre-Web account under 1.1.x and must be reconfigured to
https://hola:<OPDS_BYPASS_PASSWORD>@<host>/opdsfrom 1.2.x on.Related
🤖 Generated with Claude Code
https://claude.ai/code/session_01Vck5KSX2CLxhohx14nb5Sh