diff --git a/README.md b/README.md index 16f2aae..50e743e 100644 --- a/README.md +++ b/README.md @@ -311,8 +311,8 @@ It needs: - At least one public key in `age_recipients`. - Read access to the configured paths. -- Permission to write objects at the destination. See - [Destination permissions](#destination-permissions). +- Permission to write objects at the destination, and more on some rclone + remotes. See [Destination permissions](#destination-permissions). - Free temporary space. See [Temporary files](#temporary-files). - The [lock](#locking). @@ -1025,9 +1025,9 @@ A leftover `.partial` file is ignored. You can delete it. Commands need these permissions at the destination: -- `snapshot create` without `--prune` needs only permission to write objects. A - machine you back up can therefore hold credentials that can neither read nor - delete. +- `snapshot create` without `--prune` writes objects. On S3 it needs no other + permission, so a machine you back up can hold credentials that can neither + read nor delete. - These commands list and read: - `snapshot list` - `snapshot verify` @@ -1039,6 +1039,10 @@ Commands need these permissions at the destination: - `remote nuke` - `prune` and `snapshot create --prune` list, read and delete. +An rclone remote that can move objects also needs permission to read and +delete. An upload there looks up the object it replaces and deletes it. It stops +when the look-up is refused. + `snapshot verify` and `snapshot restore` list only when you give a remote key. `snapshot remove --local-only` does not reach the destination. `snapshot remove --dry-run` deletes nothing. @@ -1046,8 +1050,8 @@ Commands need these permissions at the destination: A machine that runs `snapshot create --prune` can delete its own backups. To keep it to write-only credentials, run `prune` from a separate, trusted machine. -A backup tries to look up the marker file and each blob before it writes. It -goes on when the destination refuses those look-ups. +A backup tries to look up the marker file and each blob before it writes. On S3 +it goes on when the destination refuses those look-ups. ### The marker file @@ -1166,6 +1170,7 @@ progress: stdout carries the output you asked for: - status and progress lines +- confirmation prompts - warnings, and the errors that `snapshot create` and `snapshot restore` print about files - tables and reports @@ -1477,6 +1482,10 @@ Each archive holds three files: The release files are not signed, have no software bill of materials and are not built reproducibly. +## TODO + +Planned work is listed in [`TODO.md`](TODO.md). + ## license [MIT](https://opensource.org/license/mit/) diff --git a/docs/DATAMODEL.md b/docs/DATAMODEL.md index e380962..12f8223 100644 --- a/docs/DATAMODEL.md +++ b/docs/DATAMODEL.md @@ -11,8 +11,8 @@ The local index has two jobs: - It is the source of each snapshot's own database. A backup uploads a trimmed, encrypted copy of the index with every snapshot. -A restore does not need the local index. It reads the copy that was uploaded -with the snapshot. +A restore reads no file, chunk or blob rows from the local index. It reads the +copy that was uploaded with the snapshot. ## Terms diff --git a/docs/REPOSTRUCTURE.md b/docs/REPOSTRUCTURE.md index 3670ab7..caf90a1 100644 --- a/docs/REPOSTRUCTURE.md +++ b/docs/REPOSTRUCTURE.md @@ -105,7 +105,7 @@ This has two consequences: A backup looks a blob up by name before it uploads it. It does not upload a blob that is already there. -When the destination refuses the look-up, the backup uploads the blob. An +On S3, when the destination refuses the look-up, the backup uploads the blob. An object with that name is then replaced by one that holds the same chunk data. ## Metadata @@ -314,8 +314,8 @@ Trust the temporary directory as much as the directory you restore into. ### Commands need different permissions -`snapshot create` without `--prune` needs only permission to write objects. -Other commands need more: +`snapshot create` without `--prune` writes objects. On S3 it needs no other +permission. Other commands need more: - These commands list and read: - `snapshot list` @@ -328,6 +328,10 @@ Other commands need more: - `remote nuke` - `prune` lists, reads and deletes. +An rclone remote that can move objects also needs permission to read and +delete. An upload there looks up the object it replaces and deletes it. It stops +when the look-up is refused. + `snapshot verify` and `snapshot restore` list only when they are given a remote key. `snapshot remove --local-only` does not reach the destination. `snapshot remove --dry-run` deletes nothing. @@ -421,7 +425,8 @@ To avoid this case, give each machine and each user its own destination. - the snapshot's `db.zst.age` - the blobs that hold the files to restore -A restore does not read the manifest and does not need the local index. +A restore does not read the manifest, or the file, chunk and blob rows of the +local index. It works in these steps: diff --git a/internal/cli/remote.go b/internal/cli/remote.go index 3dbc486..5b3301c 100644 --- a/internal/cli/remote.go +++ b/internal/cli/remote.go @@ -42,8 +42,8 @@ func newRemoteNukeCommand() *cobra.Command { Short: "Delete ALL snapshot metadata and blobs from the backup destination store", Long: `Removes every snapshot's metadata, every blob and the destination marker from the backup destination store, and each removed snapshot from -the local index. After this command completes successfully the bucket -prefix is empty and the next backup starts from scratch. +the local index. After this command completes successfully the backup +destination store is empty and the next backup starts from scratch. This is destructive and irreversible. Requires --force, and permission to list and delete objects on the destination store.`, diff --git a/internal/cli/snapshot.go b/internal/cli/snapshot.go index 997a6d9..4a6a647 100644 --- a/internal/cli/snapshot.go +++ b/internal/cli/snapshot.go @@ -69,7 +69,8 @@ If no names are provided, all configured snapshots are created. Needs at least one public key in age_recipients, and permission to write objects at the backup destination store. It does not need the age private key. With --prune it also needs permission to list, read and delete objects -there. +there. An rclone remote that can move objects also needs permission to +read and delete. The config is read from the path given by --config or VAULTIK_CONFIG; otherwise from the platform config directory (~/.config/vaultik/config.yml