Skip to content

fix(backup): pin pg_dump 18 in api images and expose download via SDK + CLI#48

Merged
jamofer merged 1 commit into
masterfrom
fix/admin-backup-button
May 24, 2026
Merged

fix(backup): pin pg_dump 18 in api images and expose download via SDK + CLI#48
jamofer merged 1 commit into
masterfrom
fix/admin-backup-button

Conversation

@jamofer

@jamofer jamofer commented May 24, 2026

Copy link
Copy Markdown
Owner

Summary

The admin "Download backup" button returned 500 Internal Server Error. Repro and findings:

  • docker-compose-dev.yml pins postgres:18.3-alpine; both backend/Dockerfile and backend/Dockerfile.prod installed Debian's default postgresql-client (currently 17.10). pg_dump refuses cross-major-version dumps and the request failed with pg_dump: error: aborting because of server version mismatch. The router swallowed the RuntimeError into a generic 500, so the only signal an operator got was the toast.
  • Two fixes for the actual hole, plus the SDK/CLI surface so this can be automated.

Backend:

  • Both Dockerfiles now install postgresql-client-18 from PGDG (apt.postgresql.org). pg_dump --version inside the api container is now 18.4, matching the postgres 18.x server.
  • New BackupFailed exception in services/backup.py. _pg_dump_to raises it on missing binary or non-zero exit, attaching the trimmed stderr. routers/settings.py::download_backup catches it and surfaces a 503 with the actionable detail so the next operator can see what's wrong without grep'ing logs.

SDK:

  • New BackupResource (testjam_client/resources/backup.py):
    • client.backup.download_bytes() returns the raw zip bytes for callers that handle persistence themselves.
    • client.backup.download(destination) accepts either a directory (resolves the filename from Content-Disposition, falling back to testjam-backup.zip) or an explicit file path; returns the Path written.

CLI:

  • New testjam backup [--out PATH] command. --out accepts a directory or a file path; defaults to the current directory. Reports {path, bytes} rendered through the standard output table / --json.
  • Wired into cli/__init__.py alongside the other resource Typers.

Tests:

  • Three SDK tests (testjam-client/tests/test_backup.py): valid zip via download_bytes, explicit-path save returns the same Path, and directory destination resolves the filename from the API header.
  • Two CLI smokes (tests/test_cli_backup.py): writing into a directory produces testjam-backup-*.zip, writing to an explicit file path lands the archive there.

Suites: backend 894, SDK 182 (3 skipped).

@jamofer jamofer merged commit 8388b93 into master May 24, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant