mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 02:29:33 +01:00
fix(config-backup): a restore that fails partway names what it restored and what failed
Merge-time fix for #661. A restore that could not write one file (a full disk, a directory where the file should be) used to stop there and answer a bare 500, naming neither the files it had already put back nor the pre-restore copy, and the Settings form was not re-read, so the next Save wrote the old settings back over a restored settings.json. restoreConfigBackup now writes every verified file it can, then throws ConfigBackupPartialRestoreError with restored, failed (name and error), untouched and safetySnapshot. The route runs the same reload hooks and audit for the files written as a full restore does, and answers 500 with the error envelope plus those fields (and restartRequired) in data, as the tab-layout 409 carries its layout. Settings refills the form when settings.json is among the restored files, also on that path. Tests: a unit case where a later file is still restored, the clis.json-as-a-directory route case, and two vm cases for the Settings handler. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
8a4ff775fb
commit
0952a2ee47
8 files changed
+196
-33
No files matched your search
@@ -1165,7 +1165,7 @@ Settings (synced, in `settings.json`): `configBackupEnabled` (absent = on), `con
|
||||
| `GET` | `/api/config-backups` | none | `settings` in effect, `dir`, `defaultDir`, `tracked[]` and `backups[]` (`id`, `createdAt`, `reason`, `appVersion`, `files[]`, `bytes`), newest first. |
|
||||
| `POST` | `/api/config-backups` | none | Snapshot now, even if nothing changed (`reason: manual`), then apply retention. `status` is `created` or `empty` (nothing tracked exists yet); `removed[]` lists the ids retention deleted. `503` when a custom folder does not answer. |
|
||||
| `GET` | `/api/config-backups/diff?from=&to=` | none | What differs between two states: `from`/`to` are a backup id or `current` (the running config; the default for `to`). `files[]` (`name`, `status` `added`/`removed`/`changed`/`unchanged`, `changes[]` of `path`, `kind`, `before`/`after`, `truncated`, `detail`) and `changed`. Credential values are never returned (`redacted: true`). `400` without `from`; `404` unknown id; `409` if a file fails its checksum. |
|
||||
| `POST` | `/api/config-backups/:id/restore` | none | Put a snapshot's files back, atomically, after a `pre-restore` snapshot of the current ones. `404` unknown id; `409 CONFLICT` if a file fails its checksum (nothing changed). Returns `restored[]`, `untouched[]` (tracked files present now that the backup did not hold; left as they are), `safetySnapshot` (the `pre-restore` id) and `restartRequired[]` (files the running server only reads at start: `.env`, `push-keys.json`, `settings.json`). |
|
||||
| `POST` | `/api/config-backups/:id/restore` | none | Put a snapshot's files back, atomically, after a `pre-restore` snapshot of the current ones. `404` unknown id; `409 CONFLICT` if a file fails its checksum (nothing changed). Returns `restored[]`, `untouched[]` (tracked files present now that the backup did not hold; left as they are), `safetySnapshot` (the `pre-restore` id) and `restartRequired[]` (files the running server only reads at start: `.env`, `push-keys.json`, `settings.json`). A file that cannot be written (a full disk, a directory in its place) does not stop the others: the answer is then `500 OPERATION_FAILED` with the same fields in `data` plus `failed[]` (`name`, `error`); the files listed in `restored[]` are the backup's and are reloaded like a full restore. |
|
||||
|
||||
## Webhook notifications
|
||||
|
||||
|
||||
@@ -137,6 +137,12 @@ From the list, press **Restore** on a backup and confirm. Codeman then:
|
||||
|
||||
Only the tracked names are ever written, whatever a manifest lists.
|
||||
|
||||
If a file cannot be written (a full disk, a folder where the file should be), the restore still
|
||||
writes the others and then reports an error that names the files it restored, the ones it could
|
||||
not write, and the `pre-restore` backup that holds the files as they were before. The restored
|
||||
files are in effect as after a full restore (Settings re-reads `settings.json` into the form), so
|
||||
fix the cause and restore again, or restore the `pre-restore` backup to go back.
|
||||
|
||||
Restoring `settings.json` keeps the four backup settings (on or off, folder, how many, how many
|
||||
days) at their current values, so a restore from before a folder change does not point the list
|
||||
at the old folder and hide the `pre-restore` copy it just made. The exception is the two
|
||||
|
||||
Reference in new issue
Block a user