# Arq Restore

A program to restore [Arq 6 and 7](https://www.arqbackup.com) compatible backups.

I am using Arq 7 for remote backup of some important files on my Mac for many years now. The software works quite well for me, but there aren't as many updates recently as there used to be in the past. Since the [data format is documented](https://www.arqbackup.com/documentation/arq7/English.lproj/dataFormat.html) and I wanted to look into Rust, I created this project to learn the language and to also have an insurance plan in case the company behind Arq goes bust.

## Installation

```terminal
cargo install arq-restore
```

## Status

The basics do work, but there are various sharp edges. Be careful if you consider relying on this!

You can currently only restore backups that are in the local file system. S3-compatible storage locations planned (maybe more with [opendal](https://github.com/apache/opendal)). In the meantime, you can use [rclone serve](https://rclone.org/commands/rclone_serve/) to mount your remote storage location as an NFS volume.

The code is not at all optimized for performance, but in my testing I was able to get close to restore speed of about 75 MB/sec, which I would consider "good enough" for now.

## Arq Concepts

* Repository: Actually not a concept by Arq. `arq-restore` calls the storage location "repository".
* Backup Plan: Configures a backup, consisting of a storage location, one or more folders, a schedule etc
* Backup Folder: A plan can have one or more configured folders to be backed up.
* Backup Record: A backup at a specific point in time for a "Backup Folder"

## Usage

Usage is definitely subject to change. Check out `arq-restore --help`.

All operations require to provide the encryption password for the backup. It can be provided in three ways:

* `--password`: directly provide (not recommended)
* `--password-file`: read password from file, whitespace will be truncated
* `--password-command`: run command and use output as password, whitespace will be truncated
  
  You can use this to get a password from the macOS keychain:
  
  ```terminal
  arq-restore --password-command="security find-generic-password -w -s 'my-arq-backup'" […]
  ```

### List Backup Folders, Backup Records and Files in Backup

* List backup folders

  ```terminal
  arq-restore -PASSWORD- list --repository=arq/backup/D7E09473-74BF-4E6D-86C3-43A033570D80
  ```

* List backup records for given backup folder

  ```terminal
  arq-restore -PASSWORD- list --repository=arq/backup/D7E09473-74BF-4E6D-86C3-43A033570D80 --folder=DD994AEF-F9CB-4D39-B12D-1EF5305103C8
  ```

* List all directories and files for this backup record and folder

  ```terminal
  arq-restore -PASSWORD- list --repository=arq/backup/D7E09473-74BF-4E6D-86C3-43A033570D80 --folder=DD994AEF-F9CB-4D39-B12D-1EF5305103C8 --record=1763107319
  ```

* …which can be limited to a specific subfolder

  ```terminal
  arq-restore -PASSWORD- list --repository=arq/backup/D7E09473-74BF-4E6D-86C3-43A033570D80 --folder=DD994AEF-F9CB-4D39-B12D-1EF5305103C8 --record=1763107319 --subtree=/path/somewhere/into/the/backup/
  ```

### Restore

```terminal
arq-restore -PASSWORD- restore --repository=arq/backup/D7E09473-74BF-4E6D-86C3-43A033570D80 --record=1763107319 --folder=DD994AEF-F9CB-4D39-B12D-1EF5305103C8 tmp/restore/path/
```

* if a file exists, it won't be overwritten
* file ownership, mode and extendend attributes are currently not restored

### Inspect

```terminal
arq-resore -PASSWORD- inspect [--raw] FILE
```

`inspect` can be used to decrypt (and parse, depending on the detected file type) various metadata files. This is mostly a debugging tool for the `arq-restore` development itself.

## TODOs

### High Level

* better error messages all around
* continue if there is an error restoring a file
  * currently, for various errors, restoring will just abort
* add support to read backup data from S3-compatible storage
* support unencrypted backups (as supported by Arq)
* add option to create a "shopping list" of files needed to actually do the restore
  * this would allow to generate a list of files needed form the remote that can be downloaded with [rclone](https://rclone.org) for example
  * this way `arq-restore` does not need to support implementing so many storage backends; also useful for a slow or unstable uplink
* add option to `--exclude` to exclude file name patterns from being restored

### Internal

* ~~get rid of the remaining `panic!` and `unwrap`s 🫣~~ Revisit `panic!` for internal checks
* improve test coverage
