b135f11557
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>
77 lines
2.8 KiB
Markdown
77 lines
2.8 KiB
Markdown
# Migrating from the legacy scripts
|
|
|
|
This is only for people moving from the earlier version of this project, when
|
|
it was a collection of scripts under `/opt/sldl` with credentials scattered in
|
|
separate config folders. If you are setting up alembic fresh, ignore this file
|
|
and follow the README.
|
|
|
|
The migration does two things: bring your old playlists in, and bring your old
|
|
credentials in. Order matters, so do them in this order.
|
|
|
|
## 1. Import your playlists
|
|
|
|
`seed_legacy()` reads a JSON file at `/config/pipeline/legacy-playlists.json`
|
|
and creates a playlist row for each entry. The file is not shipped with your
|
|
playlists in it; you provide it. There is an example to copy from at
|
|
`pipeline/configs/legacy-playlists.json.example`.
|
|
|
|
Each entry looks like this:
|
|
|
|
```json
|
|
[
|
|
{
|
|
"name": "techno",
|
|
"spotify_url": "https://open.spotify.com/playlist/your-id-here",
|
|
"cron_expr": "0 1 * * *",
|
|
"no_m3u": false
|
|
}
|
|
]
|
|
```
|
|
|
|
Put your file at `/config/pipeline/legacy-playlists.json`, then run the seed
|
|
once:
|
|
|
|
```bash
|
|
docker exec alembic python -c "from app.db import SessionLocal; from app.services import playlist_service; db=SessionLocal(); print('created', playlist_service.seed_legacy(db)); db.close()"
|
|
```
|
|
|
|
It is safe to run more than once. It skips any playlist name that already
|
|
exists.
|
|
|
|
## 2. Import your credentials
|
|
|
|
Do this after step 1, not before. The credential import re-renders every
|
|
existing playlist config file with your Soulseek and Spotify details. If no
|
|
playlists exist yet, that render has nothing to write to and the step quietly
|
|
does nothing.
|
|
|
|
`scripts/import_legacy_credentials.py` reads your old plaintext credentials and
|
|
saves them into alembic's encrypted store. It only reads the legacy files, it
|
|
never changes them, and it is safe to run more than once.
|
|
|
|
It expects your old config folders bind-mounted read-only at `/legacy/*`. Run
|
|
it as a one-off container against the same image and config volume, for example:
|
|
|
|
```bash
|
|
docker run --rm \
|
|
-v /path/to/alembic-config:/config \
|
|
-v /path/to/old/opt-sldl:/legacy/opt-sldl:ro \
|
|
-v /path/to/old/bandcampconfig:/legacy/bandcampconfig:ro \
|
|
-v /path/to/old/azuracastconfig:/legacy/azuracastconfig:ro \
|
|
-v /path/to/old/qobuzconfig:/legacy/qobuzconfig:ro \
|
|
-v /path/to/old/telegramconfig:/legacy/telegramconfig:ro \
|
|
--secret ... \
|
|
--entrypoint python \
|
|
alembic:latest /app/scripts/import_legacy_credentials.py
|
|
```
|
|
|
|
Leave off any `-v /legacy/...` mount for a service you never used. The importer
|
|
skips a legacy folder that is not present.
|
|
|
|
## 3. Retire the old services
|
|
|
|
Once alembic is running your syncs and you have confirmed a playlist downloads
|
|
and imports correctly, you can remove the old on-demand download service and
|
|
the old import service from your compose file. Keep your old config folders
|
|
backed up until you are confident, since the importer only reads them.
|