startDataBackupRun already holds the backup run lock, but the archive
(createDataBackup) and restoreDataBackup took it again, so every run
failed a few seconds in with "Another backup or restore is already
running". The writer and the restore now take no lock of their own.
The run's notice (archiving, restoring, or why it failed) moves to its
own line under the actions row so the buttons don't shift, and archiving
reads in gray rather than the warning colour.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A data archive or restore ran inside its request, which sent nothing
until tar finished: Bun closes a silent socket after 10s (its default
idleTimeout in production) and a proxy cuts it at about 100s, so the
page showed a network error while the archive kept going, and a retry
said another backup was already running.
The routes now start the run (startDataBackupRun, refused while the
backup lock is held) and answer at once. The page follows it by polling
api/admin/backups/data-status: an archive reloads once written, a
restore once the status comes from a new process after its restart,
and a failure shows its error. A run in progress survives a reload.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Settings > Backups gains a whole-data archive beside the database
snapshots, and both lists now fully work from the page.
- Data archives: `write-data-backup-archive.ts` tars all of DATA_DIR into
BACKUP_ARCHIVE_DIR as cobble-data-<epoch-ms>.tar.gz, every entry under one
root folder named after the archive, writing a .part name and renaming on
success so a cut-off run is never listed. The newest
AppData.DataBackupsKept are kept; db/.backups is left as it is.
- Restore: `restore-data-backup.ts` extracts to a temp dir, requires one
root folder holding a db folder, takes a safety archive first, then
replaces DATA_DIR (the database snapshots included) and `restart-app.ts`
restarts the process through the docker socket, since the open SQLite
handle points at the replaced file.
- Upload and restore: a modal over each list (database file or data
archive), replacing the old /admin/settings/backups/restore page.
- Delete for both kinds, icon-only row actions shared through
RowIconButton, and restore on every row.
- One backup or restore of either kind at a time (with-backup-run-lock).
- BACKUP_ARCHIVE_DIR is a start-up path (ProcessOnlyEnvKeys); the installer
mounts $COBBLE_HOME/backups-archives at /backups-archives and recreates a
container that lacks it. The image installs tar and gzip.