feat(backup): restore subcommand (db + documents), proven on the sandbox #34

Merged
arcodange merged 1 commits from claude/dolibarr-backup-restore into main 2026-06-30 18:05:50 +02:00
Owner

Le dernier gap : la moitié récupération du backup dédié.

ops/backup/dolibarr-backup.sh list    --env <e>                      # trouver le <ts>
ops/backup/dolibarr-backup.sh restore --db   <ts>.dump   --env <e> --yes
ops/backup/dolibarr-backup.sh restore --docs <ts>.tar.gz --env <e> --yes

Destructif (gate --yes + --env explicite) : scale l'app à 0, puis

  • --db : DROP OWNED BY <owner_role> CASCADE + pg_restore --no-owner --role (mêmes mécaniques que sandbox-lifecycle.sh), depuis s3://…/erp/<env>/db/<ts>.dump ;
  • --docs : vide /var/www/documents et désarchive …/docs/<ts>.tar.gz ;
    puis re-scale à 1. OWNER_ROLE par env (erp_role / erp_sandbox_role). La clé est le <ts> nu de list ; --db/--docs choisit le sous-chemin.

Prouvé sur la sandbox (banc d'essai)

avant : company = ZZZ-RESTORE-PROOF   (mutation injectée)
restore --db → fetched 1 247 600 bytes → Restore complete.
après : company = Arcodange           (valeur du backup rétablie)

La mutation a été annulée par le restore. (Le 1er run a révélé un bug de chemin — le fetch oubliait le sous-dossier db/ — corrigé.)

Ferme le dernier reste de la stratégie backup : backup quotidien automatisé + skip-if-unchanged + rétention 10 ans + restore testé.

🤖 Generated with Claude Code

Le dernier gap : la moitié **récupération** du backup dédié. ```sh ops/backup/dolibarr-backup.sh list --env <e> # trouver le <ts> ops/backup/dolibarr-backup.sh restore --db <ts>.dump --env <e> --yes ops/backup/dolibarr-backup.sh restore --docs <ts>.tar.gz --env <e> --yes ``` **Destructif** (gate `--yes` + `--env` explicite) : scale l'app à 0, puis - **`--db`** : `DROP OWNED BY <owner_role> CASCADE` + `pg_restore --no-owner --role` (mêmes mécaniques que `sandbox-lifecycle.sh`), depuis `s3://…/erp/<env>/db/<ts>.dump` ; - **`--docs`** : vide `/var/www/documents` et désarchive `…/docs/<ts>.tar.gz` ; puis re-scale à 1. `OWNER_ROLE` par env (`erp_role` / `erp_sandbox_role`). La clé est le `<ts>` nu de `list` ; `--db`/`--docs` choisit le sous-chemin. ### Prouvé sur la sandbox (banc d'essai) ``` avant : company = ZZZ-RESTORE-PROOF (mutation injectée) restore --db → fetched 1 247 600 bytes → Restore complete. après : company = Arcodange (valeur du backup rétablie) ``` La mutation a été annulée par le restore. (Le 1er run a révélé un bug de chemin — le fetch oubliait le sous-dossier `db/` — corrigé.) Ferme le dernier reste de la stratégie backup : **backup quotidien automatisé + skip-if-unchanged + rétention 10 ans + restore testé**. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
arcodange added 1 commit 2026-06-30 18:05:37 +02:00
dolibarr-backup.sh restore --db|--docs <ts> --env <e> --yes — the recovery half of
the dedicated backup. DESTRUCTIVE (gated by --yes + explicit --env): scales the app
to 0, then
- --db: DROP OWNED BY <owner_role> CASCADE + pg_restore --no-owner --role (same
  mechanics as sandbox-lifecycle.sh), from s3://.../erp/<env>/db/<ts>.dump;
- --docs: clears /var/www/documents and untars s3://.../erp/<env>/docs/<ts>.tar.gz;
then scales the app back to 1. OWNER_ROLE per env (erp_role / erp_sandbox_role).
The key is the bare <ts> filename from `list`; --db/--docs selects the subpath.

Proven on the sandbox: backup → mutate MAIN_INFO_SOCIETE_NOM to a sentinel →
restore --db → the value reverted to the backup's ('Arcodange'). (First run caught
a path bug — the fetch missed the db/ subdir — now fixed.)

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
arcodange merged commit 27e7cef6f2 into main 2026-06-30 18:05:50 +02:00
arcodange deleted branch claude/dolibarr-backup-restore 2026-06-30 18:05:51 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange-org/erp#34