Commit Graph

2 Commits

Author SHA1 Message Date
dillard dad60140bd M4: admin settings page and JSON API
- AdminApiController (admin only, CSRF-protected): status, create key,
  download recovery kit, confirm (statement accepted + exact phrase),
  backends with their usable auth mechanisms, add/test/remove locations,
  start backups, schedule, snapshots, browse, queue restores
- RestoreJob runs web-initiated restores in the background; backup and
  restore runs are kept apart in the run table
- admin section 'NG Backup' with a Vue 3 / @nextcloud/vue 9 page: key and
  recovery-kit flow (download, tick statement, 'Yes, I confirm'), location
  form built from files_external's parameter definitions, schedule, run
  list with polling, snapshot browser and restore with the three modes
- auth mechanisms that depend on a user session or on files_external's
  own stored credentials are not offered

API tested with curl on NC34 (status, backends, schedule validation,
confirmation refusal, browse, queued restore and backup completed by
cron); non-admins get 403, anonymous 401.
2026-10-02 01:09:47 +02:00
dillard b06ff0f89f Phase 0: repository on files_external storages without a mount (spike D)
ExternalStorageFactory builds storages with files_external's own
backends and auth mechanisms from an unsaved StorageConfig (as its
ConfigAdapter does), and StorageBackend adapts any IStorage to IBackend
(writeStream, seekable range reads, temp name + rename except on S3).
IBackend::put() now owns and always closes the stream, because
files_external's S3 writeStream closes it.

Spike D (NC34): S3 (SeaweedFS) and SFTP: 120 MiB backup ~6s, unchanged
run uploads nothing, restore bit-identical, no files_external mount
created, no temp files (max 12 KiB in /tmp). Works with files_external
disabled when its classes are loaded. Backup peak memory 85-89 MiB on
these targets (to investigate).
2026-10-01 18:33:15 +02:00