598abeb8cfd550008c4ea3442ae3dc4a2c259d3b
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
68e1e47534 |
fix: a new server takes a backup after its first scan, and restarts to load the restored settings (#6786)
release / Attach APK to the Release (tag releases only) (push) Canceled after 0s
release / Build + push container image (push) Canceled after 0s
release / Verify release artifacts (tag releases only) (push) Canceled after 0s
release / govulncheck (push) Successful in 16s
release / go (push) Failing after 49s
release / web (push) Successful in 1m9s
release / integration (push) Failing after 4m14s
release / android (push) Canceled after 4m38s
release / Build signed APK (push) Canceled after 4m38s
A one-off end-to-end run of the :dev image (scratch Postgres, generated FLAC files, no outbound network) found that the web restore, done the way docs/hosting.md describes, was refused with not_empty: a new server's startup scan fills the library before anyone signs up, and Restore counted tracks as occupied. The command-line restore passed the same run. - Restore now asks only that the instance has no accounts. The library the first scan found is replaced by the backup's (every foreign key into artists/albums/tracks cascades or sets null), and the restore locks the library tables so a running scan waits rather than adding to them. - Settings are read once at boot by about ten services, the library folders among them, so after a web restore the server ran on its defaults until restarted. The restore endpoint now answers, then asks the process to restart in place (syscall.Exec of the same binary, arguments and environment), which needs no container restart policy. The startup scan of the restarted server replaces the scan the endpoint used to start. - The restore form says Minstrel is restarting; the docs say a scanned new server still takes a backup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
29042e4eb2 |
feat: a new Minstrel restores a backup, from the web app or the command line, then rescans (#6775)
release / govulncheck (push) Successful in 29s
release / web (push) Failing after 1m21s
release / go (push) Successful in 1m39s
release / integration (push) Successful in 5m26s
release / android (push) Successful in 5m27s
release / Build signed APK (push) Successful in 5m44s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Skipped
release / Verify release artifacts (tag releases only) (push) Skipped
A new server (no accounts, no library) offers "Restore a backup" beside "Create account". The file goes up as the request body to POST /api/auth/restore with the setup token from the log in X-Setup-Token, since the backup's admins become this server's. It loads in one transaction, then a library scan starts and finds each file at its path. The same load runs offline as `minstrel restore FILE`, which migrates the schema first. That path alone gets a 1 GiB, 15-minute body allowance instead of 4 MiB and 30s, and skips the JSON-only check for cookie writes: a stale cookie from the old server would otherwise refuse the upload, and the custom header already rules out a cross-site form. The library sync answers 410 cursor_ahead to a cursor past the last one the server has handed out, read from the change sequence, so an app synced with the old server after the backup was made starts over instead of skipping the ids the restored server reuses. Restore now leaves each sequence as having issued the restored maximum, so that reading holds; a compacted log still counts its handed-out cursors. backup.Read keeps the underlying error in its chain, so an oversized upload answers 413 rather than "not a backup". The hosting docs say how to put the music back first and what is entered again afterwards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
967763f6ce |
feat: the backup can include the music, sending each library file once to music/ and again only when it changes (#6774)
release / govulncheck (push) Successful in 15s
release / web (push) Failing after 1m17s
release / go (push) Successful in 1m33s
release / integration (push) Successful in 5m16s
release / Build signed APK (push) Successful in 6m13s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Skipped
release / Verify release artifacts (tag releases only) (push) Skipped
release / android (push) Successful in 5m56s
With "Include the music" on, each night's run sends the library files the destination doesn't hold yet, after the database file has landed, for up to six hours; a large library spans several nights the first time. Files keep their path under the library folders' common root, beside database/ in the same folder or bucket. backup_music_files records each file's size and mtime as sent, so a night sends only new and changed files, and a rescan that touches a track but finds the same file sends nothing. A changed file goes to its old name; Minstrel never deletes there. An object the bucket refuses (a locked overwrite) is kept with its answer and goes again once the file changes or the settings are saved; three refusals in a row stop the night's music, since that is a key that may not write under music/. A folder copy is written under a .part name and renamed, keeping the file's time. The panel shows how much of the library is in, the refused files, and each run's music count and note. The verdict still turns on the database file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
9d324ab2d0 |
feat: Minstrel backs itself up nightly to a folder or an S3 bucket, off until an admin switches it on (#6773)
release / integration (push) Failing after 3m29s
release / web (push) Failing after 15s
release / govulncheck (push) Successful in 16s
release / go (push) Failing after 41s
release / android (push) Successful in 4m7s
release / Attach APK to the Release (tag releases only) (push) Canceled after 0s
release / Build + push container image (push) Canceled after 0s
release / Verify release artifacts (tag releases only) (push) Canceled after 0s
release / Build signed APK (push) Canceled after 5m34s
Admin › Backups shows a verdict first (off, not set up, waiting, backed up, overdue, failing since when), Back up now, Test destination and the latest runs, with the settings beside them. - backup.Service: one run at a time, bounded at 30 minutes; the schedule ticks every 5 minutes, catches up a slot missed while the server was down, and retries a failure after an hour and then after as long as it has been failing. Runs are recorded in backup_runs, pruned after 90 days; a run cut off by a shutdown is marked failed at the next start. - A folder destination writes database/minstrel-<UTC stamp>.tar and refuses a folder that isn't there. An S3 destination stages the file, hashes it, and uploads it under database/ through a throttled reader (4 MiB/s by default, 0 for no limit). - Test destination checks the form as typed and only lists. - The bucket secret is sealed like every stored credential; backup_settings and backup_runs are left out of the backup itself. - The panel polls only while a run is going, capped at the run limit plus five minutes. The music switch named in the task is left to #6774, so no control ships that does nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
7e1cfb8d08 |
feat: Integrations splits into Library, Acquisition, Metadata sources and Email & network, each a page on the admin rail; the Overview keeps only what needs you (M503 #5607)
release / govulncheck (push) Successful in 14s
release / web (push) Failing after 16s
release / go (push) Successful in 1m13s
release / integration (push) Successful in 4m54s
release / android (push) Successful in 5m5s
release / Build signed APK (releases and dev) (push) Successful in 5m18s
release / Attach APK to the Release (tag releases only) (push) Skipped
release / Build + push container image (push) Skipped
release / Verify release artifacts (tag releases only) (push) Skipped
- Library: the folders, Run scan and a row per scan job, cover art, fingerprints and loudness (off the Overview and Duplicates) - Acquisition: indexers and clients, searching, re-acquisition (off Missing files), Lidarr - Metadata sources: AcoustID, and one provider block for cover art and tags in place of the pasted pair - Email & network: outgoing email, the notification schedule, public address, proxies - Lidarr, outgoing email and the provider block are rebuilt as SettingsGroup rows; failures read as sentences, not codes - Duplicates and Missing files say what their setting is and link to where it is set Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |
||
|
|
522503e011 |
docs: hosting guide and security notes; README setup and HTTPS guidance (M462 #4986)
- docs/hosting.md: LAN vs internet; binding 4533 to 127.0.0.1 behind an HTTPS proxy (Caddy example, no buffering, long read timeouts for SSE and streams); the Client IP detection hop count (default 1, so 0 with no proxy or clients can forge X-Forwarded-For); the public address that password-reset links need; finding the setup token. - docs/security.md: sessions, API keys, rate limits, headers and CSP; why CSRF rests on SameSite=Strict plus JSON-only cookie writes; the Subsonic password column, including the known issue that admin reset-password writes the login password there (#5026); why Android allows plain HTTP; the CI publish gate. - README: keeps the LAN-first port mapping with a pointer for internet hosts, scopes "plain http:// is fine" to trusted networks, explains the setup token in first-run step 1, and links both docs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> |