Commit Graph

4 Commits

Author SHA1 Message Date
andrew db13890fe1 Harden fix-genre, sync-bandcamp, upgrade-mp3-to-flac under strict mode (R1)
- fix-genre.sh: set -euo pipefail; guard the tag-remove metaflac calls and the
  'beet ls | head -5' verify (SIGPIPE) that would otherwise abort.
- sync-bandcamp.sh: set -euo pipefail; the destructive chain already used
  'if cmd; then..else WARN' (set -e exempt); guard the staging mv.
- upgrade-mp3-to-flac.sh: set -euo pipefail; capture sldl/replace-with-better
  exit codes without aborting (was 'cmd; RC=$?', which set -e breaks); read
  Soulseek creds from the first available .conf instead of a hardcoded y2k.conf,
  guarded; guard the xargs purge and a grep -c.
- pipeline-status.sh: deliberately kept at set -u (documented). It is read-only
  and assembles ~30 independent probes; set -e would abort the whole digest on
  one missing optional file, which is exactly how the 9am notification broke.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 10:52:44 -06:00
andrew fa86e992ad Robustness: crash-safe migrations, stale-run sweep, optional prep tools; branded 404
- init_db applies each schema file with executescript (semicolons in triggers
  and string literals no longer break it) and records schema_version itself
  after each file, so a forgotten in-file bump can't re-run an ALTER and crash
  startup. Re-running is a no-op.
- On startup, sweep any job_runs left in 'running' (killed by a restart) to
  'interrupted' so the UI/history don't show a run stuck running forever.
- prep-audio.sh skips loudgain and cue_file cleanly when they aren't installed
  (they aren't in the base image) instead of failing on a missing binary and
  logging errors; pipeline-status.sh routes syslog through a guard so a missing
  `logger` doesn't spew into the job log.
- Add a branded 404 page (rendered to static HTML, no external runtime) via a
  custom exception handler that leaves all other responses, including the login
  redirect, untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 17:32:26 -06:00
andrew b135f11557 Security hardening and first-run/portability improvements
Security (P0):
- Remove committed session-secret default; auto-generate and persist a
  random secret to the config volume when SESSION_SECRET is unset
  (prevents forgeable session cookies / auth bypass).
- Validate playlist names to a safe charset and render sldl configs via
  literal Python substitution instead of sed (closes a command-injection
  and path-traversal path through playlist names).
- shlex-quote credential values written to shell-sourced env files, and
  strip newlines from values patched into .conf files.
- Render playlist .conf files 0600; warn at startup if the master key is
  co-located with the config volume; document keeping it separate.

Portability:
- Configurable timezone via TZ (default UTC) instead of hardcoded Edmonton.
- Remove personal defaults (navidrome user "andrew", ephemeral.club URLs).
- Ship generic example seeds; move the cross-album dedup keep-list and the
  legacy playlist import to editable config files; drop the personal
  _upgrade.csv.
- Generic VPN reference in docker-compose.snippet.yml.

First-run experience:
- Redirect to /setup instead of 500 when OIDC is unconfigured; surface a
  missing master key inline; entrypoint exits with an actionable message
  when the config folder is not writable.
- Add unauthenticated /health (JSON) and /setup (checklist) diagnostics.

Docs:
- Write docs/ARCHITECTURE.md and docs/MIGRATION.md (previously referenced
  but missing); expand README with ownership, backups, advanced settings,
  and migration guidance.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 14:25:55 -06:00
andrew 68cb007e4c Stage 0: migrate pipeline scripts from /opt/sldl, scaffold repo
Moves all ~30 pipeline scripts, configs, and the vendored sldl binary into
this repo (source /opt/sldl left untouched). Removes all docker exec/docker
compose dependencies now that beets and sldl run in-process/as a subprocess
of this container instead of via soulbeet/on-demand sldl containers.
Replaces hardcoded host paths, Navidrome credentials, and Spotify credential
sourcing with env-var-driven paths and shared credential loaders. Adds
Dockerfile, entrypoint.sh, requirements.txt, docker-compose.snippet.yml, and
the initial app DB schema.
2026-07-08 13:10:55 -06:00