diff --git a/PLAN.md b/PLAN.md index fd7d829..e856e7e 100644 --- a/PLAN.md +++ b/PLAN.md @@ -359,6 +359,24 @@ minimale volledige restore (`occ backup:restore:full` op een verse installatie) Backlog: (a) de originele weergavenaam herstellen (het label uit de export is niet getest als weergavenaam); (b) de interne `migrated-`-naam hernoemen (vereist directe databasewijziging, niet voor de beta). +**Backlog uit de pre-beta review (2026-10-07)** — geen belemmering voor 0.9.0-beta of 1.0.0, staat +in README "Known limitations": +1. Geheugen bij grote instanties (>1 TB, miljoenen bestanden): blob-index, prune-set, browse van een + snapshot in de web-UI, `trashExtras` bij restore en het manifest van een user-export staan volledig + in het geheugen; streaming/paginering nodig. +2. Twee servers op één locatie: catalogus kan breken (generatie overschreven, of anchor >200 generaties + achter). Docs-waarschuwing staat er; mogelijk later een echte put-if-absent per backend. +3. Sleutelrotatie: een slot verwijderen trekt geen toegang in (master-key blijft gelijk). +4. Rollback vóór DR niet detecteerbaar: referentie-generatie en -hash in de kit opnemen of tonen. +5. Kit-velden buiten `wrapped_key` (o.a. `delete_delay_days`) zijn niet geauthenticeerd; nu alleen getoond. +6. Repository-id in de AD van objecten (formaatwijziging). +7. Wachtwoorden van locaties via `--option-file` of omgevingsvariabele i.p.v. de commandoregel. +8. Tijdelijke restore-bestanden niet via de Files-API verwijderen (komen nu in de prullenbak). +9. DB-restore in foreign-key-volgorde (cascades). +10. Packs zonder index (index-upload mislukt) opruimen. +11. `backup:restore:full` in onderhoudsmodus en hervatbaar maken; nu: opnieuw draaien met `--force`. +12. Config/rename op FTP/SMB-servers die geen rename over een bestaand bestand toestaan. + Doorgeschoven naar **v1.3.0** (fase 3, niet meer fase 2): in-place volledige restore (eigen restore-modus i.p.v. onderhoudsmodus) en zelfbediening voor gebruikers (eigen bestanden terugzetten vanuit de Files-app). diff --git a/README.md b/README.md index d64caf9..b0be2a8 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,9 @@ installations and hosted Nextcloud. (Choosing SMB as a storage backend is the on see "Storage backend experiences" below — that requirement comes from files_external, not from ng_backup, and applies to any Nextcloud app that writes to an SMB share.) -**Status: pre-release. Not yet tested on production.** See `PLAN.md` for the design and `docs/HOWTO.md` for a -step-by-step guide from setup to a tested restore. +**Status: beta (0.9.0).** Tested thoroughly, usable alongside your current backup, but not yet a +drop-in replacement for it. See "Known limitations" below, `PLAN.md` for the design and +`docs/HOWTO.md` for a step-by-step guide from setup to a tested restore. License: AGPL-3.0-or-later. @@ -147,6 +148,29 @@ Contributions welcome via PR — add what you ran into with your own provider. mid-run behaves like any other local-path failure (the run resumes). See PLAN.md 3.5 for why NFS can't be driven from PHP directly. +## Known limitations + +On the backlog; none of these block the beta or 1.0.0, but know them before you rely on it: + +- **Very large instances** (well over 1 TB, millions of files): the blob index, cleanup, browsing a + snapshot in the web interface and per-user export manifests are held in memory. Expect high + memory use there; reports from such instances are very welcome. +- **One location, one server.** Never let two Nextcloud servers write to the same location (for + example a disaster recovery test server pointed at the production location): they can break each + other's catalog, and the location is then refused as possibly tampered with. Test a disaster + recovery against a copy of the location, or only read from it. +- **Removing a passphrase slot does not revoke access.** The master key stays the same, so someone + with an old recovery kit and that slot's passphrase can still decrypt the location if they can + read it. Key rotation is not available yet. +- **Rollback before a disaster recovery is not detected.** A fresh server has no record of the + newest catalog generation, so a location rolled back to an older state looks valid there. +- Location passwords passed with `-o password=...` are visible in the process list and shell + history while the command runs. +- Temporary files of a restore into a user's files end up in that user's trash. +- Restoring the database does not order tables by foreign keys; apps with cascading foreign keys + could lose rows (Nextcloud core does not use them). +- A pack whose index upload failed stays on the location until removed by hand. + ## Commands | Command | Purpose | diff --git a/docs/HOWTO.md b/docs/HOWTO.md index e6d0097..5e2fe05 100644 --- a/docs/HOWTO.md +++ b/docs/HOWTO.md @@ -14,7 +14,8 @@ occ backup:key:confirm -u --code= --confirm="Yes, I - The passphrase protects the backup. Keep it somewhere other than this server. - Optional: extra passphrases for other people with `occ backup:key:slot:add --label="..."`. - Any one passphrase is enough to restore. + Any one passphrase is enough to restore. Removing a slot later does not revoke access for someone + who kept an old kit and that passphrase (see "Known limitations" in the README). - The recovery kit (`/var/tmp/ng_backup-kit.json` above) is also required for disaster recovery. The web user writes it there; then move it off the server as root, next to the passphrase, and delete the copy in `/var/tmp`. Without the kit and a passphrase, the backup cannot be read. @@ -117,7 +118,8 @@ occ backup:user:restore offsite users// --mode=as-backup ## 7. Disaster recovery: restore the whole server Use a fresh Nextcloud installation of the same major version, with NG Backup installed and -the same location available: +the same location available. For a test, use a **copy** of the location: two servers writing to one +location break each other's catalog. ``` occ backup:key:import /path/ng_backup-kit.json --passphrase-file=/path/passphrase