diff --git a/README.md b/README.md new file mode 100644 index 0000000..7e2b61a --- /dev/null +++ b/README.md @@ -0,0 +1,233 @@ +# pbc + +A Bash wrapper around Proxmox's `proxmox-backup-client` for Proxmox Backup Server (PBS). + +It keeps the repository, credentials and the list of paths to back up in a single config +file, injects the configured namespace (`--ns`) into every command that needs it, and lets +you pick a snapshot group, snapshot and archive from an interactive menu instead of typing +them out. Any command it does not implement itself is passed straight through to +`proxmox-backup-client`. + +## Requirements + +- A Debian-based host with `bash` and `curl` — a Debian-based WSL instance works as well, + which lets you back up Windows directories through `/mnt/c` +- `jq` and `proxmox-backup-client` — both installed by `pbc install` +- A reachable PBS with a datastore and an API token + +## Installation + +```bash +curl -fsSL https://git.ccc-rheintal.ch/spacefreak/pbc/raw/branch/master/install.sh | sudo bash +``` + +This installs the newest tagged version to `/usr/local/bin/pbc`, installs the +dependencies, and puts an example config at `/etc/pbc/config.example`. + +From a clone: + +```bash +sudo ./pbc install # install the dependencies, then copy pbc where you want it +``` + +`install.sh` always fetches the newest tagged release from the repository, so running it +from a clone does not install your local copy. + +### Updating + +Run the same command again to update `pbc` itself: + +```bash +curl -fsSL https://git.ccc-rheintal.ch/spacefreak/pbc/raw/branch/master/install.sh | sudo bash +``` + +It fetches the newest tag and overwrites `/usr/local/bin/pbc`. Your `/etc/pbc/config` is +left untouched. + +To update only the `proxmox-backup-client` binary: + +```bash +sudo pbc install --update +``` + +This is skipped when the client is managed by the package manager — use `apt` in that case. + +## Configuration + +```bash +sudo cp /etc/pbc/config.example /etc/pbc/config +sudo chmod 640 /etc/pbc/config +sudo editor /etc/pbc/config +``` + +```bash +PBS_SERVER='pbs.domain.tld:8007' +PBS_USER='backup@pam:token-name' +PBS_PASSWORD='XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' +PBS_DATASTORE='backup' +PBS_NAMESPACE='MyBackups' + +BACKUP=('root.pxar:/' 'data.pxar:/mnt/data') +``` + +| Key | Description | +|---|---| +| `PBS_SERVER` | PBS host and port | +| `PBS_USER` | User and API token name, `user@realm:token-name` | +| `PBS_PASSWORD` | The API token secret | +| `PBS_DATASTORE` | Datastore to back up to | +| `PBS_NAMESPACE` | Namespace inside the datastore | +| `BACKUP` | Array of `archive-name.pxar:/path` entries to back up | +| `PBC` | Optional, path to `proxmox-backup-client` (default `/usr/local/bin/proxmox-backup-client`) | + +`pbc` never creates the config for you — copy the example and edit it yourself. The file +has to be readable for the user that runs `pbc`, so if that is not root, hand +it over: + +```bash +sudo chown youruser /etc/pbc/config +``` + +The config is sourced as Bash and contains your token secret. `pbc` refuses to run if the +file is writable by group or others, and warns if it is readable by others. + +Check that it works: + +```bash +pbc list +``` + +Use a different config with `-c`: + +```bash +pbc -c ./myconfig list +``` + +## Usage + +Run `pbc --help` for the synopsis and the list of options, or `pbc -H` to additionally +list every command of `proxmox-backup-client`. The commands `pbc` implements itself are +described below. + +### backup + +Back up everything listed in `BACKUP` and print the client output: + +```bash +pbc backup +``` + +Extra arguments are forwarded to the client: + +```bash +pbc backup --exclude '/mnt/data/cache' +``` + +### backup-cron + +Same backup, but output is suppressed unless it fails — so cron only mails you on errors: + +```cron +0 3 * * * /usr/local/bin/pbc backup-cron +``` + +### list + +List backup groups with their latest snapshot and archives: + +```bash +pbc list +``` + +### snapshot-list + +List snapshots of a group with sizes and archives. Without an argument you get a menu of +the available groups: + +```bash +pbc snapshot-list +pbc snapshot-list host/myhost +``` + +### mount + +Mount a single archive of a snapshot on a local directory. Anything you leave out is +asked for interactively: + +```bash +pbc mount +pbc mount host/myhost/2026-08-24T01:00:00Z root.pxar /mnt/restore +``` + +The target directory is not created for you — create it beforehand and make sure it is +writable for the user that runs `pbc`. Unmount when done: + +```bash +umount /mnt/restore +``` + +### catalog-shell + +Open an interactive shell to browse an archive and restore selected files — see below. + +```bash +pbc catalog-shell +pbc catalog-shell host/myhost/2026-08-24T01:00:00Z root.pxar +``` + +### install + +Install or update the dependencies. Requires root: + +```bash +sudo pbc install +sudo pbc install --update +``` + +## Restoring files + +### Selectively, with `catalog-shell` + +```bash +pbc catalog-shell +``` + +Pick a snapshot and an archive from the menu, then browse the archive as if it were a +filesystem and mark what you want back: + +``` +pxar:/ > cd etc +pxar:/etc > ls +pxar:/etc > select nginx +pxar:/etc > cd ../home/user +pxar:/home/user > select .ssh/config +pxar:/home/user > list-selected +pxar:/home/user > restore-selected /mnt/restore +pxar:/home/user > exit +``` + +- `ls`, `cd`, `pwd`, `stat`, `find` — browse the archive +- `select` / `deselect` — mark a file or directory for restore +- `list-selected` — show what is currently marked +- `restore-selected ` — restore only the marked entries +- `restore ` — restore the whole archive +- `help` — list all available shell commands +- `exit` — leave the shell + +Create the target directory beforehand — `pbc` does not create it. It has to be writable +for the user that runs `pbc`, and should be empty. + +### Everything, or with normal tools + +To copy files out with `cp`, `rsync` or a file manager, mount the archive instead: + +```bash +mkdir -p /mnt/restore # must exist and be writable for the user running pbc +pbc mount +cp -a /mnt/restore/etc/nginx /etc/nginx +umount /mnt/restore +``` + +## License + +GPLv3 — see [LICENSE](LICENSE).