Man pages

pull/10/head
Dennis Schwerdel 2017-04-05 16:02:16 +02:00
parent faf7b4906f
commit 1dd4878b4c
21 changed files with 1205 additions and 131 deletions

View File

@ -95,6 +95,18 @@ Recommended: Brotli/2-7
## Design
### Semantic Versioning
zVault sticks to the semantic versioning scheme. In its current pre-1.0 stage
this has the following implications:
- Even now the repository format is considered pretty stable. All future
versions will be able to read the current repository format. Maybe conversions
might be necessary but the backups should always be forward-compatible.
- The CLI might see breaking changes but at least it is guaranteed that calls
that are currently non-destructive will not become destructive in the future.
Running todays commands on a future version will not cause any harm.
## TODO
### Packaging

1
deb/.gitignore vendored
View File

@ -1,5 +1,6 @@
zvault/debian/zvault
zvault/zvault*
zvault/man/*
libsquash/src
libsquash/debian/libsquash
*/debian/debhelper*

View File

@ -10,7 +10,7 @@ build: libsquash_*.deb $(PACKAGE)_*.deb
libsquash_*.deb:
(cd libsquash; make clean; debuild -b -us -uc; cd ..)
$(PACKAGE)_*.deb: $(PACKAGE)/zvault.1.ronn $(PACKAGE)/zvault
$(PACKAGE)_*.deb: $(PACKAGE)/man/* $(PACKAGE)/zvault
(cd $(PACKAGE); make clean; debuild -b -us -uc; cd ..)
.PHONY: clean
@ -19,10 +19,9 @@ clean:
rm -rf $(PACKAGE)_*
(cd libsquash; debuild clean; cd ..)
rm -rf libsqash_*
rm -f ../target/release/zvault
$(PACKAGE)/zvault.1.ronn: ../docs/manpage.md
cp ../docs/manpage.md $(PACKAGE)/zvault.1.ronn
$(PACKAGE)/man/*: ../docs/man/*
cp ../docs/man/* $(PACKAGE)/man
$(PACKAGE)/zvault: ../target/release/zvault
cp ../target/release/zvault $(PACKAGE)/zvault

View File

@ -1,7 +1,10 @@
build: zvault.1
build: man/zvault.1 man/zvault-backup.1 man/zvault-check.1 man/zvault-config.1 \
man/zvault-import.1 man/zvault-info.1 man/zvault-init.1 man/zvault-list.1 \
man/zvault-mount.1 man/zvault-prune.1 man/zvault-remove.1 \
man/zvault-restore.1 man/zvault-vacuum.1
zvault.1: zvault.1.ronn
ronn -r zvault.1.ronn
%.1: %.1.md
ronn -r $<
install:
install -d $(DESTDIR)/usr/bin

View File

@ -1 +1,13 @@
zvault.1
man/zvault.1
man/zvault-init.1
man/zvault-info.1
man/zvault-list.1
man/zvault-prune.1
man/zvault-backup.1
man/zvault-check.1
man/zvault-config.1
man/zvault-import.1
man/zvault-mount.1
man/zvault-remove.1
man/zvault-restore.1
man/zvault-vacuum.1

148
docs/man/zvault-backup.1.md Normal file
View File

@ -0,0 +1,148 @@
zvault-backup(1) -- Create a new backup
=======================================
## SYNOPSIS
`zvault backup [OPTIONS] <SRC> <BACKUP>`
## DESCRIPTION
This subcommand creates a new backup `BACKUP` from the data located at `SRC`.
The backup given by `BACKUP` must be in the format `[repository]::backup_name`
as described in _zvault(1)_. If `repository` is omitted, the default repository
location is used instead.
The source data given by `SRC` can either be a filesystem path or the path of a
tar archive (with `--tar`).
If `SRC` is a filesystem path, a reference backup is used (unless `--full` is
set) to compare the data with and only store modified data and take the
unmodified data from the reference backup. Unless a specific reference backup
is chosen via `--ref`, the latest matching backup from the same machine with the
same source path is used as reference.
When `SRC` is a filesystem path, a set of exclude patterns can be configured.
The patterns can be given directly via `--exclude` or be read from a file via
`--excludes-from`. Unless `--no-default-excludes` is set, a set of default
exclude pattern is read from the file `excludes` in the repository folder.
All exclude pattern given via any of these ways will be combined.
Unless `--xdev` is set, zVault will not traverse into subfolders that are on a
different filesystem, i.e. mount points will not be included.
When zVault fails to read a source file, either because of file permissions,
filesystem errors or because the file has an unsupported type, it will print a
warning message and continue with the backup process.
zVault will store all file attributes including extended attributes except for
creation time and access time as creation time can not be reliably set on
restore and access times change by reading files.
## OPTIONS
* `-e`, `--exclude <PATTERN>...`:
Exclude this path or file pattern. This option can be given multiple times.
Please see *EXCLUDE PATTERNS* for details on pattern.
This option conflicts with `--tar`.
* `--excludes-from <FILE>`:
Read the list of excludes from this file.
Please see *EXCLUDE PATTERNS* for details on pattern.
This option conflicts with `--tar`.
* `--full`:
Create a full backup without using another backup as a reference. This makes
sure that all files in the source path (except excluded files) are fully
read. The file contents will still be deduplicated by using existing backups
but all files are read fully.
This option conflicts with `--ref`.
* `--no-default-excludes`:
Do not load the default `excludes` file from the repository folder.
Those excludes are pre-filled with generic pattern to exclude like pseudo
filesystems or cache folders.
* `--ref <REF>`:
Base the new backup on this reference backup instead of automatically
selecting a matching one. The backup given as `REF` must be a valid backup
name as listed by zvault-list(1).
This option conflicts with `--full`.
* `--tar`:
Read the source data from a tar archive instead of the filesystem. When this
flag is set, the `SRC` path must specify a valid tar file.
The contents of the archive are then read instead of the filesystem. Note
that the tar file contents are read as files and directories and not just
as a single file (this would happen when `SRC` is a tar file and `--tar` is
not set).
This option can be used to import a backup that has been exported using
zvault-restore(1) with the `--tar` flag.
This flag conflicts with `--exclude` and `--excludes_from`.
* `-x`, `--xdev`:
Allow to cross filesystem boundaries. By default, paths on different
filesystems than the start path will be ignored. If this flag is set,
the scan will traverse also into mounted filesystems.
**Note:** Please use this option with case. Some pseudo filesystems
contain arbitrarily deep nested directories that will send zVault into
an infinite loop. Also it should be avoided to include the remote storage
in the backup.
* `-h`, `--help`:
Prints help information
## EXCLUDE PATTERNS
Exclude patterns can either be absolute patterns or relative patterns. Absolute
patterns start with `/` and must match from the begin of the absolute file path.
Relative patterns start with anything but `/` and can also match any portion of
the absolute path. For example the pattern `/bin` only matches the system
directory `/bin` but not `/usr/bin` or `/usr/local/bin` while the pattern `bin`
matches them too.
Exclude patterns must match full path components, i.e. the pattern `bin` will
match any path that contains `bin` as as component (e.g. `/bin` and `/usr/bin`)
but not paths that contain `bin` only as substring like `/sbin`.
Wildcards can be used to match also substrings of path components:
- `?` matches any single character.
- `*` matches any string not containing `/`, i.e. `*` only matches within a path
component but does not span components. For example `/usr/*bin` matches
`/usr/bin` and `/usr/sbin` but not `/usr/local/bin`.
- `**` matches any string, even spanning across path components. So `/usr/**bin`
will match `/usr/bin`, `/usr/sbin` and also `/usr/local/bin`.
If a pattern matches on a filesystem entry, that entry and any child entry (in
the case of directories) will be left out of the backup.
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -0,0 +1,56 @@
zvault-check(1) -- Check the repository, a backup or a backup subtree
=====================================================================
## SYNOPSIS
`zvault check [OPTIONS] [PATH]`
## DESCRIPTION
This subcommand checks the repository, a backup or a backup subtree given by
`PATH`.
The repository, backup, of subtree given by `PATH` must be in the format
`[repository][::backup_name[::subtree]]` as described in _zvault(1)_.
If `PATH` is omitted, the default repository location is used instead.
The command will perform the following checks in order:
- Bundle integrity
- Full bundle contents (optional)
- Index integrity
- Backup integrity
- Filesystem integrity
If a backup is specified in `PATH`, only this backup will be check in the backup
integrity check and only the filesystem integrity of this backup will be checked
in the filesystem integrity check.
If a subtree is specified in `PATH`, no backups will be checked and only the
given subtree will be checked in the filesystem integrity check.
Unless `--full` is set, the bundles will only be checked without actually
fetching them fully. This means that their contents can only be read from their
header and this information is not verified. If `--full` is set, the full
bundles are fetched and their contents are compared to what their header claims.
This check takes a long time since all bundles need to fetched, decrypted and
decompressed fully to read their contents.
## OPTIONS
* `--full`:
Also check the contents of the bundles by fetching and decompressing them.
Note: This flag causes the check to be much slower.
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -0,0 +1,78 @@
zvault-config(1) -- Display or change the configuration
=======================================================
## SYNOPSIS
`zvault config [REPO]`
## DESCRIPTION
This subcommand displays or changes the configuration of the repository `REPO`.
If `REPO` is omitted, the default repository location will be used.
The configuration can be changes using the options described below. If no
options are set, the current configuration is displayed. Otherwise, the
configuration is changed as specified and then displayed.
Beware that the *chunker algorithm*, *chunk size* and *hash method* should not
be changed on existing repositories already containing many backups. If those
values are changed, new backups will not be able to use existing data for
deduplication. This can waste lots of storage space and most likely outweighs
the expected benefits.
The values for *bundle size*, *compression* and *encryption* only affect new
data and can be changed at any time without any drawback.
## OPTIONS
* `--bundle-size <SIZE>`:
Set the target bundle size in MiB (default: 25).
Please see _zvault(1)_ for more information on *bundle size*.
* `--chunker <CHUNKER>`:
Set the chunker algorithm and target chunk size (default: fastcdc/16).
Please see _zvault(1)_ for more information on *chunkers* and possible
values.
* `-c`, `--compression <COMPRESSION>`:
Set the compression method and level (default: brotli/3).
Please see _zvault(1)_ for more information on *compression* and possible
values.
* `-e`, `--encryption <PUBLIC_KEY>`:
Use the given public key for encryption. The key must be a valid public key
encoded as hexadecimal. Please use _zvault-genkey(1)_ to generate keys and
_zvault-addkey(1)_ to add keys to the repository.
If `none` is given as public key, encryption is deactivated.
**Warning:** ZVault does not verify that the matching secret key which is
needed for decryption is known.
Please see _zvault(1)_ for more information on *encryption*.
* `--hash <HASH>`:
Set the hash method (default: blake2).
Please see _zvault(1)_ for more information on *hash methods* and possible
values.
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -0,0 +1,45 @@
zvault-import(1) -- Reconstruct a repository from the remote storage
====================================================================
## SYNOPSIS
`zvault import <REMOTE> [REPO]`
## DESCRIPTION
This subcommand imports a repository from remote storage. First, an empty
repository will be created and then the remote bundles will be imported and
added to the local index.
The repository will be created at the location `REPO`. If `REPO` is omitted,
the default repository location will be used. It is important that the path
given as `REPO` does not yet exist, so that it can be created.
The remote storage path `REMOTE` must be an existing remote storage folder
initialized by _zvault-init(1)_.
Note that this command is not intended to import single backups exported as tar
files via _zvault-restore(1)_ with the `--tar` flag. Those archives can be
imported via _zvault-backup(1)_ also with the `--tar` flag.
## OPTIONS
* `-k`, `--key <FILE>...`:
Add the key pair in the given file to the repository before importing the
remote bundles. This option can be used to add keys that are needed to read
the bundles. If multiple keys are needed, this options can be given multiple
times.
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

29
docs/man/zvault-info.1.md Normal file
View File

@ -0,0 +1,29 @@
zvault-info(1) -- Display information on a repository, a backup or a subtree
============================================================================
## SYNOPSIS
`zvault info [PATH]`
## DESCRIPTION
This subcommand displays information on the repository, backup or backup subtree
specified by `PATH`.
The repository, backup or backup subtree given by `PATH` must be in the format
`[repository][::backup_name[::subtree]]` as described in _zvault(1)_.
If `PATH` is omitted, the default repository location is used instead.
## OPTIONS
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

75
docs/man/zvault-init.1.md Normal file
View File

@ -0,0 +1,75 @@
zvault-init(1) -- Initialize a new repository
=============================================
## SYNOPSIS
`zvault init [OPTIONS] --remote <REMOTE> [REPO]`
## DESCRIPTION
This subcommand initializes a new repository at the location `REPO`. If `REPO`
is omitted, the default repository location will be used. It is important that
the path given as `REPO` does not yet exist, so that it can be created.
The remote storage path `REMOTE` must be an existing empty folder. ZVault
supports mounted remote filesystems, so it is a good idea to use such a folder
to keep the backups on a remote location.
This subcommand should **NOT** be used to import existing remote backup
locations. Please use _zvault-import(1)_ for this purpose.
The rest of the options sets configuration options for the new repository. The
configuration can be changed by _zvault-config(1)_ later.
## OPTIONS
* `--bundle-size <SIZE>`:
Set the target bundle size in MiB (default: 25).
Please see zvault(1) for more information on *bundle size*.
* `--chunker <CHUNKER>`:
Set the chunker algorithm and target chunk size (default: fastcdc/16).
Please see _zvault(1)_ for more information on *chunkers* and possible
values.
* `-c`, `--compression <COMPRESSION>`:
Set the compression method and level (default: brotli/3).
Please see _zvault(1)_ for more information on *compression* and possible
values.
* `-e`, `--encryption`:
Generate a keypair and enable encryption.
Please see _zvault(1)_ for more information on *encryption*.
* `--hash <HASH>`:
Set the hash method (default: blake2).
Please see _zvault(1)_ for more information on *hash methods* and possible
values.
* `-h`, `--help`:
Prints help information
* `-r`, `--remote <REMOTE>`:
Set the path to the mounted remote storage. There should be an empty folder
at this location.
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

40
docs/man/zvault-list.1.md Normal file
View File

@ -0,0 +1,40 @@
zvault-list(1) -- List backups or backup contents
=================================================
## SYNOPSIS
`zvault list [PATH]`
## DESCRIPTION
This subcommand lists all backups or backup contents of the repository or backup
specified by `PATH`.
The repository, backup or backup subtree given by `PATH` must be in the format
`[repository][::backup_name[::subtree]]` as described in _zvault(1)_.
If `PATH` is omitted, the default repository location is used instead.
If `PATH` specifies a repository, all backups of this repository are listed.
If `PATH` specifies a backup or a backup subtree, all contents of this folder
are displayed. In the case of a backup, the contents of its root folder are
displayed.
_zvault-info(1)_ can be used to display more information on single entities.
Note that _zvault-mount(1)_ can be used to make backups accessible as a
filesystem which is faster than _zvault-list(1)_ for multiple listings.
## OPTIONS
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -0,0 +1,42 @@
zvault-mount(1) -- Mount the repository, a backup or a subtree
==============================================================
## SYNOPSIS
`zvault mount [PATH] <MOUNTPOINT>`
## DESCRIPTION
This subcommand mounts a repository, backup or backup subtree specified by
`PATH` on the location given by `MOUNTPOINT` making it accessible as a
filesystem.
The repository, backup or backup subtree given by `PATH` must be in the format
`[repository][::backup_name[::subtree]]` as described in _zvault(1)_.
If `PATH` is omitted, the default repository location is used instead.
If `PATH` specifies a backup or backup subtree, the root of that backup or the
respective subtree is mounted onto the given location.
If `PATH` specifies a whole repository, all backups of that repository will be
accessible in separate folders below the given mount point.
The provided file system is mounted read-only, i.e. it can only be used to
inspect and restore backups but not to create new backups or modify exiting
ones.
Please note that since the filesystem is mounted via fuse, restoring huge data
this way is slower than using _zvault-restore(1)_.
## OPTIONS
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -0,0 +1,95 @@
zvault-prune(1) -- Remove backups based on age
==============================================
## SYNOPSIS
`zvault prune [OPTIONS] [REPO]`
## DESCRIPTION
This subcommand removes backups in the repository `REPO` based on their age.
If `REPO` is omitted, the default repository location is used instead.
If a prefix is specified via `--prefix`, only backups which start with this
string are considered for removal.
The prune logic will preserve a certain number of backups for different time
periods and discard the rest. The available periods are `daily`, `weekly`,
`monthly` and `yearly`. For each of those periods, a number `N` can be specified
that defines that for each of the last `N` of these periods, a single backup
(the newest one in that period) will be kept.
For example, `--daily 3` will keep backups of the last 3 days, i.e. one backup
for today, yesterday and the day before yesterday (if a backup has been saved
today). If several backups have been saved on a single day, only the newest is
kept.
The different periods can also be combined to preserve backups using multiple
different time periods. Backups are only removed if they are not preserved by
any of the time periods.
For example, `--daily 3 --weekly 4 --monthly 3` will keep one backup for each of
the last 3 days, for each of the last 4 weeks and for each of the last 3 months.
As time progresses, the daily backups will be removed as new ones are created so
that only 3 of them are kept but each week one of them will be preserved as a
weekly backup and an old weekly backup will be removed unless that backup
happens to be the last backup of last month...
If one period is not set, no backups for that time period will be preserved.
This command will refuse to remove all backups if called without options.
Unless the option `--force` is set, this command only displays the backups that
would be removed but does not remove them.
This command renders certain chunks unused, but reclaiming their space is a
complicated task as chunks are combined into bundles together with other chunks
which are potentially still used. Please use _zvault-vacuum(1)_ to reclaim
unused space.
**Important note: Although this command does not actually remove any data, the
data of the deleted backups becomes inaccessible and can not be restored.**
## OPTIONS
* `-p`, `--prefix <PREFIX>`:
Only consider backups starting with this prefix.
* `-d`, `--daily <NUM>`:
Keep the newest backup for each of the last `NUM` days.
* `-w`, `--weekly <NUM>`:
Keep the newest backup for each of the last `NUM` weeks.
* `-m`, `--monthly <NUM>`:
Keep the newest backup for each of the last `NUM` months.
* `-y`, `--yearly <NUM>`:
Keep the newest backup for each of the last `NUM` years.
* `-f`, `--force`:
Actually remove backups instead of displaying what would be removed.
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -0,0 +1,43 @@
zvault-remove(1) -- Remove a backup or a subtree
================================================
## SYNOPSIS
`zvault remove <BACKUP>`
## DESCRIPTION
This subcommand removes a backup or a backup subtree `BACKUP`.
The backup or backup subtree given by `BACKUP` must be in the format
`[repository]::backup_name[::subtree]` as described in _zvault(1)_.
If `repository` is omitted, the default repository location is used instead.
If a backup is referenced, this backup will be deleted. If a subtree is given,
the backup is instead rewritten to not include that subtree anymore.
Note: When removing backup subtrees, the meta information of that backup is left
unchanged and still contains the data (e.g. duration and size) of the original
backup run.
This command renders certain chunks unused, but reclaiming their space is a
complicated task as chunks are combined into bundles together with other chunks
which are potentially still used. Please use _zvault-vacuum(1)_ to reclaim
unused space.
**Important note: Although this command does not actually remove any data, the
data of the deleted backups becomes inaccessible and can not be restored.**
## OPTIONS
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -0,0 +1,43 @@
zvault-restore(1) -- Restore a backup or subtree
================================================
## SYNOPSIS
`zvault restore [OPTIONS] <BACKUP> <DST>`
## DESCRIPTION
This subcommand restores a backup or a backup subtree `BACKUP` into the folder
`DST`.
The backup or backup subtree given by `BACKUP` must be in the format
`[repository]::backup_name[::subtree]` as described in _zvault(1)_.
If `repository` is omitted, the default repository location is used instead.
If `--tar` is set, the data is written to a tar file named `DST`. In this case
`DST` must not exist.
If `--tar` is not set, the data will be written into the existing folder `DST`.
## OPTIONS
* `--tar`:
Write the backup to a tar archive named `DST` instead of creating files and
folders at this location.
This option can be used to export a backup that can be imported again using
zvault-backup(1) with the `--tar` flag.
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -0,0 +1,66 @@
zvault-vacuum(1) -- Reclaim space by rewriting bundles
======================================================
## SYNOPSIS
`zvault vacuum [OPTIONS] [REPO]`
## DESCRIPTION
This subcommand reclaims space by rewriting bundles in the repository `REPO`.
If `REPO` is omitted, the default repository location is used instead.
This command rewrites bundles to remove unused chunks of backups that have been
removed by _zvault-remove(1)_ or _zvault-prune(1)_.
To accomplish this, it will scan all backups and track all used chunks to
identify chunks that are not used by any backup. Those chunks are then grouped
by bundle and bundles with many unused chunks will be rewritten with those
chunks left out.
The option `--ratio` configures the minimal ratio of used chunks in a bundle
required to remove it. Since all chunks that are still used must be read from
the bundle and written to a new one and only the storage space of the unused
chunks can be reclaimed, rewriting a bundle is more economical the lower the
ratio. At a ratio of 0% will only rewrite bundles with no used chunks at all
(in this case the bundle is just removed). At a ratio of 100%, all bundles will
be rewritten regardless of unused chunks.
Please note that the bundles will be rewritten with the current settings for
encryption and compression, disregarding the original settings during bundle
creation.
Unless `--force` is set, this command will only simulate the process but not
actually rewrite any bundle.
As this is a critical operation, zVault takes many precaution measures to avoid
any damaging the integrity to the repository or other backups. The whole process
is performed with an exclusive lock on the repository which prevents any backup
runs. Also the chunk index is double checked before removing bundles to make
sure that they are unused. Nevertheless, this is a critical operation which
should be avoided when the storage space permits it.
## OPTIONS
* `-r`, `--ratio <NUM>`:
Do not rewrite bundles with more than `NUM`% of used chunks.
The ratio must be given in whole percentage, e.g. 50 mean 50%.
* `-f`, `--force`:
Actually run the vacuum instead of simulating it.
* `-h`, `--help`:
Prints help information
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

324
docs/man/zvault.1.md Normal file
View File

@ -0,0 +1,324 @@
zvault(1) -- Deduplicating backup solution
==========================================
## SYNOPSIS
`zvault <SUBCOMMAND>`
## DESCRIPTION
ZVault is a deduplicating backup solution. It creates backups from data read
from the filesystem or a tar file, deduplicates it, optionally compresses and
encrypts the data and stores the data in bundles at a potentially remote storage
location.
## OPTIONS
* `-h`, `--help`:
Prints help information
* `-V`, `--version`:
Prints version information
## SUBCOMMANDS
### Main Commands
* `init` Initialize a new repository, _zvault-init(1)_
* `import` Reconstruct a repository from the remote storage, _zvault-import(1)_
* `backup` Create a new backup, _zvault-backup(1)_
* `restore` Restore a backup or subtree, _zvault-restore(1)_
* `check` Check the repository, a backup or a backup subtree, _zvault-check(1)_
* `list` List backups or backup contents, _zvault-list(1)_
* `info` Display information on a repository, a backup or a subtree, _zvault-info(1)_
* `mount` Mount the repository, a backup or a subtree, _zvault-mount(1)_
* `remove` Remove a backup or a subtree, _zvault-remove(1)_
* `prune` Remove backups based on age, _zvault-prune(1)_
* `vacuum` Reclaim space by rewriting bundles, _zvault-vacuum(1)_
### Other Commands
* `addkey` Add a key pair to the repository, _zvault-addkey(1)_
* `algotest` Test a specific algorithm combination, _zvault-algotest(1)_
* `analyze` Analyze the used and reclaimable space of bundles, _zvault-analyze(1)_
* `bundleinfo` Display information on a bundle, _zvault-bundleinfo(1)_
* `bundlelist` List bundles in a repository, _zvault-bundlelist(1)_
* `config` Display or change the configuration, _zvault-config(1)_
* `diff` Display differences between two backup versions, _zvault-diff(1)_
* `genkey` Generate a new key pair, _zvault-genkey(1)_
* `versions` Find different versions of a file in all backups, _zvault-versions(1)_
## USAGE
### Path syntax
Most subcommands work with a repository that has to be specified as a parameter.
If this repository is not specified, the default repository in `~/.zvault` will
be used instead.
Some subcommands need to reference a specific backup in the repository. This is
done via the syntax `repository::backup_name` where `repository` is the path to
the repository and `backup_name` is the name of the backup in that repository
as listed by `zvault list`. In this case, `repository` can be omitted,
shortening the syntax to `::backup_name`. In this case, the default repository
is used.
Some subcommands need to reference a specific subtree inside a backup. This is
done via the syntax `repository::backup_name::subtree` where
`repository::backup_name` specifies a backup as described before and `subtree`
is the path to the subtree of the backup. Again, `repository` can be omitted,
yielding the shortened syntax `::backup_name::subtree`.
Some subcommands can take either a repository, a backup or a backup subtree. In
this case it is important to note that if a path component is empty, it is
regarded as not set at all.
Examples:
- `~/.zvault` references the repository in `~/.zvault` and is identical with
`::` (as well as not setting the path at all).
- `::backup1` references the backup `backup1` in the default repository
- `::backup1::/` references the root folder of the backup `backup1` in the
default repository
## CONFIGURATION OPTIONS
ZVault offers some configuration options that affect the backup speed, storage
space, security and RAM usage. Users should select them carefully for their
scenario. The performance of different combinations can be compared using
_zvault-algotest(1)_.
### Bundle size
The target bundle size affects how big bundles written to the remote storage
will become. The configured size is not a hard maximum, as headers and some
effects of compression can cause bundles to become slightly larger than this
size. Also since bundles will be closed at the end of a backup run, some bundles
can also be smaller than this size. However most bundles will end up with
approximately the specified size.
The configured value for the bundle size has some practical consequences.
Since the whole bundle is compressed as a whole (a so-called *solid archive*),
the compression ratio is impacted negatively if bundles are small. Also the
remote storage could become inefficient if too many small bundle files are
stored. On the other side, since the whole bundle has to be fetched and
decompressed to read a single chunk from that bundle, bigger bundles increase
the overhead of reading the data.
The recommended bundle size is 25 MiB, but values between 5 MiB and 100 MiB
should also be feasable.
### Chunker
The chunker is the component that splits the input data into so-called *chunks*.
The main goal of the chunker is to produce as many identical chunks as possible
when only small parts of the data changed since the last backup. The identical
chunks do not have to be stored again, thus the input data is deduplicated.
To achieve this goal, the chunker splits the input data based on the data
itself, so that identical parts can be detected even when their position
changed.
ZVault offers different chunker algorithms with different properties to choose
from:
- The **rabin** chunker is a very common algorithm with a good quality but a
mediocre speed (about 350 MB/s).
- The **ae** chunker is a novel approach that can reach very high speeds
(over 750 MB/s) at a cost of deduplication rate.
- The **fastcdc** algorithm reaches a similar deduplication rate as the rabin
chunker but is faster (about 550 MB/s).
The recommended chunker is **fastcdc**.
Besides the chunker algorithm, an important setting is the target chunk size,
i.e. the planned average chunk size. Since the chunker splits the data on
data-dependent criteria, it will not achieve the configured size exactly.
The chunk size has a number of practical implications. Since deduplication works
by identifying identical chunks, smaller chunk sizes will be able to find more
identical chunks and thereby reduce the overall storage space.
On the other side, the index needs to store 24 bytes per chunk, so many small
chunks will take more space than few big chunks. Since the index of all chunks
in the repository needs to be loaded into memory during the backup, huge
repositories can get a problem with memory usage. Since the index could be only
40% filled and the chunker could yield smaller chunks than configured, 100 bytes
per chunk should be a safe value to calculate with.
The configured value for chunk size needs to be a power of 2. Here is a
selection of chunk sizes and their estimated RAM usage:
- Chunk size 4 KiB => ~40 GiB data stored in 1 GiB RAM
- Chunk size 8 KiB => ~80 GiB data stored in 1 GiB RAM
- Chunk size 16 KiB => ~160 GiB data stored in 1 GiB RAM
- Chunk size 32 KiB => ~325 GiB data stored in 1 GiB RAM
- Chunk size 64 KiB => ~650 GiB data stored in 1 GiB RAM
- Chunk size 128 KiB => ~1.3 TiB data stored in 1 GiB RAM
- Chunk size 256 KiB => ~2.5 TiB data stored in 1 GiB RAM
- Chunk size 512 KiB => ~5 TiB data stored in 1 GiB RAM
- Chunk size 1024 KiB => ~10 TiB data stored in 1 GiB RAM
The recommended chunk size for normal computers is 16 KiB. Servers with lots of
data might want to use 128 KiB or 1024 KiB instead.
The chunker algortihm and chunk size are configured together in the format
`algorithm/size` where algorithm is one of `rabin`, `ae` and `fastcdc` and size
is the size in KiB e.g. `16`. So the recommended configuration is `fastcdc/16`.
Please not that since the chunker algorithm and chunk size affect the chunks
created from the input data, any change to those values will make existing
chunks inaccessible for deduplication purposes. The old data is still readable
but new backups will have to store all data again.
### Compression
ZVault offers different compression algorithms that can be used to compress the
stored data after deduplication. The compression ratio that can be achieved
mostly depends on the input data (test data can be compressed well and media
data like music and videos are already compressed and can not be compressed
significantly).
Using a compression algorithm is a trade-off between backup speed and storage
space. Higher compression takes longer and saves more space while low
compression is faster but needs more space.
ZVault supports the following compression methods:
- **deflate** (also called *zlib* and *gzip*) is the most common algorithm today
and guarantees that backups can be decompressed in future centuries. Its
speed and compression ratio are acceptable but other algorithms are better.
This is a rather conservative choice. This algorithm supports the levels 1
(fastest) to 9 (best).
- **lz4** is a very fast compression algorithm that does not impact backup speed
very much. It does not compress as good as other algorithms but is much faster
than all other algorithms. This algorithm supports levels 1 (fastest) to 14
(best) but levels above 7 are significantly slower and not recommended.
- **brotli** is a modern compression algorithm that is both faster and
compresses better than deflate. It offers a big range of compression ratios
and speeds via its levels. This algorithm supports levels 1 (fastest) to 10
(best).
- **lzma** is about the algorithm with the best compression today. That comes
at the cost of speed. LZMA is rather slow at all levels so it can slow down
the backup speed significantly. This algorithm supports levels 1 (fastest) to
9 (best).
The recommended combinations are:
- Focusing speed: lz4 with level between 1 and 7
- Balanced focus: brotli with levels between 1 and 10
- Focusing storage space: lzma with levels between 1 and 9
The compression algorithm and level are configured together via the syntax
`algorithm/level` where `algorithm` is either `deflate`, `lz4`, `brotli` or
`lzma` and `level` is a number.
The default compression setting is **brotli/3**.
Since the compression ratio and speed hugely depend on the input data,
_zvault-algotest(1)_ should be used to compare algorithms with actual input
data.
### Encryption
When enabled, zVault uses modern encryption provided by *libsodium* to encrypt
the bundles that are stored remotely. This makes it impossible for anyone with
access to the remote bundles to read their contents or to modify them.
zVault uses asymmetric encryption, which means that encryption uses a so called
*public key* and decryption uses a different *secret key*. This makes it
possible to setup a backup configuration where the machine can only create
backups but not read them. Since lots of subcommands need to read the backups,
this setup is not recommended in general.
The key pairs used by zVault can be created by _zvault-genkey(1)_ and added to a
repository via _zvault-addkey(1)_ or upon creation via the `--encryption` flag
in _zvault-init(1)_.
**Important: The key pair is needed to read and restore any encrypted backup.
Loosing the secret key means that all data in the backups is lost forever.
There is no backdoor, even the developers of zVault can not recover a lost key
pair. So it is important to store the key pair in a safe location. The key pair
is small enough to be printed on paper for example.**
### Hash method
ZVault uses hash fingerprints to identify chunks. It is critically important
that no two chunks have the same hash value (a so-called hash collision) as this
would cause one chunk to overwrite the other chunk. For this purpose zVault uses
128 bit hashes, that have a collision probability of less than 1.5e-15 even for
1 trillion stored chunks (about 15.000 TiB stored data in 16 KiB chunks).
ZVault offers two different hash algorithms: **blake2** and **murmur3**.
Murmur3 is blazingly fast but is not cryptographically secure. That means that
while random hash collisions are negligible, an attacker with access to files
could manipulate a file so that it will cause a hash collision and affects other
data in the repository. **This hash should only be used when the security
implications of this are fully understood.**
Blake2 is slower than murmur3 but also pretty fast and this hash algorithm is
cryptographically secure, i.e. even an attacker can not cause hash collisions.
The recommended hash algorithm is **blake2**.
## EXAMPLES
This command will initialize a repository in the default location with
encryption enabled:
$> zvault init -e --remote /mnt/remote/backups
Before using this repository, the key pair located at `~/.zvault/keys` should be
backed up in a safe location (e.g. printed to paper).
This command will create a backup of the whole system tagged by date:
$> zvault backup / ::system/$(date +%F)
If the home folders are mounted on /home, the following command can be used to
backup them separatly (zVault will not backup mounted folders by default):
$> zvault backup /home ::homes/$(date +%F)
The backups can be listed by this command:
$> zvault list
and inspected by this command (the date needs to be adapted):
$> zvault info ::homes/2017-04-06
To restore some files from a backup, the following command can be used:
$> zvault restore ::homes/2017-04-06::bob/file.dat /tmp
Alternatively the repository can be mounted with this command:
$> zvault mount ::homes/2017-04-06 /mnt/tmp
A single backup can be removed with this command:
$> zvault remove ::homes/2017-04-06
Multiple backups can be removed based on their date with the following command
(add `-f` to actually remove backups):
$> zvault prune --prefix system --daily 7 --weekly 5 --monthly 12
To reclaim storage space after removing some backups vacuum needs to be run
(add `-f` to actually remove bundles):
$> zvault vacuum
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -1,37 +0,0 @@
zvault(1) -- Deduplicating backup solution
==========================================
## SYNOPSIS
`zvault ...`
## DESCRIPTION
## OPTIONS
* `-h`, `--help`:
Display the help.
## USAGE
## EXIT STATUS
## EXAMPLES
## FILES
## SEE ALSO
## COPYRIGHT
Copyright (C) 2017 Dennis Schwerdel
This software is licensed under GPL-3 or newer (see LICENSE.md)

View File

@ -235,92 +235,92 @@ fn parse_bundle_id(val: &str) -> Result<BundleId, ErrorCode> {
#[allow(unknown_lints,cyclomatic_complexity)]
pub fn parse() -> Result<Arguments, ErrorCode> {
let args = App::new("zvault").version(crate_version!()).author(crate_authors!(",\n")).about(crate_description!())
.settings(&[AppSettings::GlobalVersion, AppSettings::VersionlessSubcommands, AppSettings::SubcommandRequiredElseHelp])
.settings(&[AppSettings::AllowMissingPositional, AppSettings::VersionlessSubcommands, AppSettings::SubcommandRequiredElseHelp])
.global_settings(&[AppSettings::UnifiedHelpMessage, AppSettings::ColoredHelp, AppSettings::ColorAuto])
.subcommand(SubCommand::with_name("init").about("initializes a new repository")
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'maximal bundle size in MiB [default: 25]'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'chunker algorithm [default: fastcdc/8]'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'compression to use [default: brotli/3]'"))
.arg(Arg::from_usage("-e --encryption [ENCRYPTION] 'generate a keypair and enable encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'hash method to use [default: blake2]'"))
.arg(Arg::from_usage("-r --remote <REMOTE> 'path to the mounted remote storage'"))
.arg(Arg::from_usage("[REPO] 'path of the repository'")))
.subcommand(SubCommand::with_name("backup").about("creates a new backup")
.arg(Arg::from_usage("--full 'create a full backup'"))
.arg(Arg::from_usage("reference --ref [REF] 'the reference backup to use for partial backup'"))
.arg(Arg::from_usage("cross_device -x --xdev 'allow to cross filesystem boundaries'"))
.arg(Arg::from_usage("-e --exclude [PATTERN]... 'exclude this path or file'"))
.arg(Arg::from_usage("excludes_from --excludes-from [FILE] 'read the list of exludes from this file'"))
.arg(Arg::from_usage("no_default_excludes --no-default-excludes 'do not load the default excludes file'"))
.arg(Arg::from_usage("--tar 'the source is a tar file'"))
.arg(Arg::from_usage("<SRC> 'source path to backup'"))
.arg(Arg::from_usage("<BACKUP> 'repository::backup path'")))
.subcommand(SubCommand::with_name("restore").about("restores a backup (or subpath)")
.arg(Arg::from_usage("--tar 'restore in form of a tar file'"))
.arg(Arg::from_usage("<BACKUP> 'repository::backup[::subpath] path'"))
.arg(Arg::from_usage("<DST> 'destination path for backup'")))
.subcommand(SubCommand::with_name("remove").aliases(&["rm", "delete", "del"]).about("removes a backup or a subpath")
.arg(Arg::from_usage("<BACKUP> 'repository::backup[::subpath] path'")))
.subcommand(SubCommand::with_name("prune").about("removes backups based on age")
.arg(Arg::from_usage("--prefix [PREFIX] 'only consider backups starting with this prefix'"))
.arg(Arg::from_usage("--daily [NUM] 'keep this number of daily backups'"))
.arg(Arg::from_usage("--weekly [NUM] 'keep this number of weekly backups'"))
.arg(Arg::from_usage("--monthly [NUM] 'keep this number of monthly backups'"))
.arg(Arg::from_usage("--yearly [NUM] 'keep this number of yearly backups'"))
.arg(Arg::from_usage("-f --force 'actually run the prunce instead of simulating it'"))
.arg(Arg::from_usage("[REPO] 'path of the repository'")))
.subcommand(SubCommand::with_name("vacuum").about("saves space by combining and recompressing bundles")
.arg(Arg::from_usage("-r --ratio [NUM] 'ratio in % of unused space in a bundle to rewrite that bundle'"))
.arg(Arg::from_usage("-f --force 'actually run the vacuum instead of simulating it'"))
.arg(Arg::from_usage("[REPO] 'path of the repository'")))
.subcommand(SubCommand::with_name("check").about("checks the repository, a backup or a backup subpath")
.arg(Arg::from_usage("--full 'also check file contents'"))
.arg(Arg::from_usage("[PATH] 'repository[::backup] path'")))
.subcommand(SubCommand::with_name("list").alias("ls").about("lists backups or backup contents")
.arg(Arg::from_usage("[PATH] 'repository[::backup[::subpath]] path'")))
.subcommand(SubCommand::with_name("mount").about("mount a backup for inspection")
.arg(Arg::from_usage("[PATH] 'repository[::backup[::subpath]] path'"))
.arg(Arg::from_usage("<MOUNTPOINT> 'where to mount to backup'")))
.subcommand(SubCommand::with_name("bundlelist").about("lists bundles in a repository")
.arg(Arg::from_usage("[REPO] 'path of the repository'")))
.subcommand(SubCommand::with_name("bundleinfo").about("lists bundles in a repository")
.arg(Arg::from_usage("[REPO] 'path of the repository'"))
.arg(Arg::from_usage("<BUNDLE> 'the bundle id'")))
.subcommand(SubCommand::with_name("import").about("reconstruct a repository from the remote files")
.arg(Arg::from_usage("-k --key [FILE]... 'a file with a needed to read the bundles'"))
.arg(Arg::from_usage("<REMOTE> 'remote repository path'"))
.arg(Arg::from_usage("[REPO] 'path of the local repository to create'")))
.subcommand(SubCommand::with_name("info").about("displays information on a repository, a backup or a path in a backup")
.arg(Arg::from_usage("[PATH] 'repository[::backup[::subpath]] path'")))
.subcommand(SubCommand::with_name("analyze").about("analyze the used and reclaimable space of bundles")
.arg(Arg::from_usage("[REPO] 'repository path'")))
.subcommand(SubCommand::with_name("versions").about("display different versions of a file in all backups")
.arg(Arg::from_usage("[REPO] 'repository path'"))
.arg(Arg::from_usage("<PATH> 'the file path'")))
.subcommand(SubCommand::with_name("diff").about("display difference between two backup versions")
.arg(Arg::from_usage("<OLD> 'old repository::backup[::subpath] path'"))
.arg(Arg::from_usage("<NEW> 'new repository::backup[::subpath] path'")))
.subcommand(SubCommand::with_name("config").about("changes the configuration")
.arg(Arg::from_usage("[REPO] 'path of the repository'"))
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'maximal bundle size in MiB [default: 25]'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'chunker algorithm [default: fastcdc/16]'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'compression to use [default: brotli/3]'"))
.arg(Arg::from_usage("-e --encryption [ENCRYPTION] 'the public key to use for encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'hash method to use [default: blake2]'")))
.subcommand(SubCommand::with_name("genkey").about("generates a new key pair")
.arg(Arg::from_usage("[FILE] 'the destination file for the keypair'")))
.subcommand(SubCommand::with_name("addkey").about("adds a key to the respository")
.arg(Arg::from_usage("[REPO] 'path of the repository'"))
.arg(Arg::from_usage("-g --generate 'generate a new key'").conflicts_with("FILE"))
.arg(Arg::from_usage("set_default --default -d 'set this key as default'"))
.arg(Arg::from_usage("[FILE] 'the file containing the keypair'").conflicts_with("generate")))
.subcommand(SubCommand::with_name("algotest").about("test a specific algorithm combination")
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'maximal bundle size in MiB [default: 25]'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'chunker algorithm [default: fastcdc/16]'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'compression to use [default: brotli/3]'"))
.arg(Arg::from_usage("-e --encrypt 'enable encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'hash method to use [default: blake2]'"))
.arg(Arg::from_usage("<FILE> 'the file to test the algorithms with'"))).get_matches();
.subcommand(SubCommand::with_name("init").about("Initialize a new repository")
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'Set the target bundle size in MiB (default: 25)'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'Set the chunker algorithm and target chunk size (default: fastcdc/16)'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'Set the compression method and level (default: brotli/3)'"))
.arg(Arg::from_usage("-e --encryption 'Generate a keypair and enable encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'Set the hash method (default: blake2)'"))
.arg(Arg::from_usage("-r --remote <REMOTE> 'Set the path to the mounted remote storage'"))
.arg(Arg::from_usage("[REPO] 'The path for the new repository'")))
.subcommand(SubCommand::with_name("backup").about("Create a new backup")
.arg(Arg::from_usage("--full 'Create a full backup without using a reference'"))
.arg(Arg::from_usage("reference --ref [REF] 'Base the new backup on this reference'").conflicts_with("full"))
.arg(Arg::from_usage("cross_device -x --xdev 'Allow to cross filesystem boundaries'"))
.arg(Arg::from_usage("-e --exclude [PATTERN]... 'Exclude this path or file pattern'"))
.arg(Arg::from_usage("excludes_from --excludes-from [FILE] 'Read the list of excludes from this file'"))
.arg(Arg::from_usage("no_default_excludes --no-default-excludes 'Do not load the default excludes file'"))
.arg(Arg::from_usage("--tar 'Read the source data from a tar file'").conflicts_with_all(&["reference", "exclude", "excludes_from"]))
.arg(Arg::from_usage("<SRC> 'Source path to backup'"))
.arg(Arg::from_usage("<BACKUP> 'Backup path, [repository]::backup'")))
.subcommand(SubCommand::with_name("restore").about("Restore a backup or subtree")
.arg(Arg::from_usage("--tar 'Restore in form of a tar file'"))
.arg(Arg::from_usage("<BACKUP> 'The backup/subtree path, [repository]::backup[::subtree]'"))
.arg(Arg::from_usage("<DST> 'Destination path for backup'")))
.subcommand(SubCommand::with_name("remove").aliases(&["rm", "delete", "del"]).about("Remove a backup or a subtree")
.arg(Arg::from_usage("<BACKUP> 'The backup/subtree path, [repository]::backup[::subtree]'")))
.subcommand(SubCommand::with_name("prune").about("Remove backups based on age")
.arg(Arg::from_usage("-p --prefix [PREFIX] 'Only consider backups starting with this prefix'"))
.arg(Arg::from_usage("-d --daily [NUM] 'Keep this number of daily backups'"))
.arg(Arg::from_usage("-w --weekly [NUM] 'Keep this number of weekly backups'"))
.arg(Arg::from_usage("-m --monthly [NUM] 'Keep this number of monthly backups'"))
.arg(Arg::from_usage("-y --yearly [NUM] 'Keep this number of yearly backups'"))
.arg(Arg::from_usage("-f --force 'Actually run the prune instead of simulating it'"))
.arg(Arg::from_usage("[REPO] 'Path of the repository'")))
.subcommand(SubCommand::with_name("vacuum").about("Reclaim space by rewriting bundles")
.arg(Arg::from_usage("-r --ratio [NUM] 'Ratio in % of unused space in a bundle to rewrite that bundle'"))
.arg(Arg::from_usage("-f --force 'Actually run the vacuum instead of simulating it'"))
.arg(Arg::from_usage("[REPO] 'Path of the repository'")))
.subcommand(SubCommand::with_name("check").about("Check the repository, a backup or a backup subtree")
.arg(Arg::from_usage("--full 'Also check file contents (slow)'"))
.arg(Arg::from_usage("[PATH] 'Path of the repository/backup/subtree, [repository][::backup[::subtree]]'")))
.subcommand(SubCommand::with_name("list").alias("ls").about("List backups or backup contents")
.arg(Arg::from_usage("[PATH] 'Path of the repository/backup/subtree, [repository][::backup[::subtree]]'")))
.subcommand(SubCommand::with_name("mount").about("Mount the repository, a backup or a subtree")
.arg(Arg::from_usage("[PATH] 'Path of the repository/backup/subtree, [repository][::backup[::subtree]]'"))
.arg(Arg::from_usage("<MOUNTPOINT> 'Existing mount point'")))
.subcommand(SubCommand::with_name("bundlelist").about("List bundles in a repository")
.arg(Arg::from_usage("[REPO] 'Path of the repository'")))
.subcommand(SubCommand::with_name("bundleinfo").about("Display information on a bundle")
.arg(Arg::from_usage("[REPO] 'Path of the repository'"))
.arg(Arg::from_usage("<BUNDLE> 'Id of the bundle'")))
.subcommand(SubCommand::with_name("import").about("Reconstruct a repository from the remote storage")
.arg(Arg::from_usage("-k --key [FILE]... 'Key file needed to read the bundles'"))
.arg(Arg::from_usage("<REMOTE> 'Remote repository path'"))
.arg(Arg::from_usage("[REPO] 'The path for the new repository'")))
.subcommand(SubCommand::with_name("info").about("Display information on a repository, a backup or a subtree")
.arg(Arg::from_usage("[PATH] 'Path of the repository/backup/subtree, [repository][::backup[::subtree]]'")))
.subcommand(SubCommand::with_name("analyze").about("Analyze the used and reclaimable space of bundles")
.arg(Arg::from_usage("[REPO] 'Path of the repository'")))
.subcommand(SubCommand::with_name("versions").about("Find different versions of a file in all backups")
.arg(Arg::from_usage("[REPO] 'Path of the repository'"))
.arg(Arg::from_usage("<PATH> 'Path of the file'")))
.subcommand(SubCommand::with_name("diff").about("Display differences between two backup versions")
.arg(Arg::from_usage("<OLD> 'Old version, [repository]::backup[::subpath]'"))
.arg(Arg::from_usage("<NEW> 'New version, [repository]::backup[::subpath]'")))
.subcommand(SubCommand::with_name("config").about("Display or change the configuration")
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'Set the target bundle size in MiB (default: 25)'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'Set the chunker algorithm and target chunk size (default: fastcdc/16)'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'Set the compression method and level (default: brotli/3)'"))
.arg(Arg::from_usage("-e --encryption [PUBLIC_KEY] 'The public key to use for encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'Set the hash method (default: blake2)'"))
.arg(Arg::from_usage("[REPO] 'Path of the repository'")))
.subcommand(SubCommand::with_name("genkey").about("Generate a new key pair")
.arg(Arg::from_usage("[FILE] 'Destination file for the keypair'")))
.subcommand(SubCommand::with_name("addkey").about("Add a key pair to the repository")
.arg(Arg::from_usage("-g --generate 'Generate a new key pair'").conflicts_with("FILE"))
.arg(Arg::from_usage("set_default --default -d 'Set the key pair as default'"))
.arg(Arg::from_usage("[FILE] 'File containing the keypair'").conflicts_with("generate"))
.arg(Arg::from_usage("[REPO] 'Path of the repository'")))
.subcommand(SubCommand::with_name("algotest").about("Test a specific algorithm combination")
.arg(Arg::from_usage("bundle_size --bundle-size [SIZE] 'Set the target bundle size in MiB (default: 25)'"))
.arg(Arg::from_usage("--chunker [CHUNKER] 'Set the chunker algorithm and target chunk size (default: fastcdc/16)'"))
.arg(Arg::from_usage("-c --compression [COMPRESSION] 'Set the compression method and level (default: brotli/3)'"))
.arg(Arg::from_usage("-e --encryption 'Generate a keypair and enable encryption'"))
.arg(Arg::from_usage("--hash [HASH] 'Set the hash method (default: blake2)'"))
.arg(Arg::from_usage("<FILE> 'File with test data'"))).get_matches();
if let Some(args) = args.subcommand_matches("init") {
let (repository, _backup, _inode) = try!(parse_repo_path(args.value_of("REPO").unwrap_or(""), Some(false), Some(false)));
return Ok(Arguments::Init {

View File

@ -68,7 +68,7 @@ pub const DEFAULT_CHUNKER: &'static str = "fastcdc/16";
pub const DEFAULT_HASH: &'static str = "blake2";
pub const DEFAULT_COMPRESSION: &'static str = "brotli/3";
pub const DEFAULT_BUNDLE_SIZE: usize = 25;
pub const DEFAULT_VACUUM_RATIO: usize = 50;
pub const DEFAULT_VACUUM_RATIO: usize = 0;
lazy_static! {
pub static ref DEFAULT_REPOSITORY: String = {
env::home_dir().unwrap().join(".zvault").to_string_lossy().to_string()