mirror of
https://github.com/restic/restic.git
synced 2026-09-14 08:17:58 +00:00
Compare commits
200
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
271eabd239 | ||
|
|
0333ef3325 | ||
|
|
b7e1ece1e0 | ||
|
|
c5300a2c56 | ||
|
|
1bd92896d7 | ||
|
|
9dba01021e | ||
|
|
23f6b8c3fd | ||
|
|
79a50e3b1f | ||
|
|
b8a5ca2d10 | ||
|
|
916b2d303b | ||
|
|
a06f5c28c0 | ||
|
|
c2f3eee5af | ||
|
|
62345abe4a | ||
|
|
e024fc6d4d | ||
|
|
0db9024aad | ||
|
|
21ba15577e | ||
|
|
2fb1957ca4 | ||
|
|
9a88fb253b | ||
|
|
f14436953a | ||
|
|
11fbaaae9a | ||
|
|
3ed84ff0c6 | ||
|
|
8e965ed4eb | ||
|
|
5f0fa2129e | ||
|
|
04dfa19c7e | ||
|
|
6509c207f4 | ||
|
|
445b845267 | ||
|
|
3ff37215df | ||
|
|
5d379b5359 | ||
|
|
e708628cfd | ||
|
|
bb4b3481a6 | ||
|
|
ad3a52e6f0 | ||
|
|
e8b4d8d8bc | ||
|
|
1aa61e6def | ||
|
|
8d7d6ad2d5 | ||
|
|
fe09e6f865 | ||
|
|
1e3c9a2c11 | ||
|
|
e21dcb0eea | ||
|
|
31b8d7a639 | ||
|
|
5695f9ebd2 | ||
|
|
8091151638 | ||
|
|
ae179ee63e | ||
|
|
0590e3e12d | ||
|
|
3807d13bdc | ||
|
|
63be3704d9 | ||
|
|
35419de232 | ||
|
|
863a590a81 | ||
|
|
7c0b6a82db | ||
|
|
96a912b65a | ||
|
|
b44ecde8b0 | ||
|
|
39fe1e96fe | ||
|
|
4ba237bb93 | ||
|
|
ce87fbd7dc | ||
|
|
b27375f5ce | ||
|
|
720e0ee0c7 | ||
|
|
27db3ec262 | ||
|
|
f80b07b2c8 | ||
|
|
6003dada14 | ||
|
|
41a45ae908 | ||
|
|
8299c5559c | ||
|
|
56883817d8 | ||
|
|
f0cd16e5ea | ||
|
|
a03fe4562e | ||
|
|
efc075df87 | ||
|
|
f500b0d90e | ||
|
|
c193cea119 | ||
|
|
f0d49ca600 | ||
|
|
164d8af3dd | ||
|
|
052564007a | ||
|
|
6099f81692 | ||
|
|
9d7f616190 | ||
|
|
295ddb9e57 | ||
|
|
e638b46a13 | ||
|
|
d6cfe857b7 | ||
|
|
2964d2ad15 | ||
|
|
0c9efa9c2a | ||
|
|
37a5e2d681 | ||
|
|
4b0fcaed45 | ||
|
|
645a6efaf2 | ||
|
|
dc2e664209 | ||
|
|
a449450021 | ||
|
|
603bb0e309 | ||
|
|
27456f6545 | ||
|
|
c458e114d4 | ||
|
|
45e9a55c62 | ||
|
|
307a6ba3a3 | ||
|
|
50da20d93d | ||
|
|
5fd3dbccb7 | ||
|
|
35655a481b | ||
|
|
30cb553c8d | ||
|
|
2f3eeff2e7 | ||
|
|
356ac404cd | ||
|
|
ab769abeaf | ||
|
|
4036991c91 | ||
|
|
88c8e903d2 | ||
|
|
740758a5fa | ||
|
|
862ee4b2c9 | ||
|
|
958dc6aafc | ||
|
|
88cc444779 | ||
|
|
4a424af1d5 | ||
|
|
bc65da2baf | ||
|
|
b79f18209f | ||
|
|
8388e67c4b | ||
|
|
0acc3c5923 | ||
|
|
54a124de3b | ||
|
|
bcc3bddcf4 | ||
|
|
17c53efb0d | ||
|
|
7959796269 | ||
|
|
375c2a56de | ||
|
|
b8eacd1364 | ||
|
|
e73c281142 | ||
|
|
fdd3b14db3 | ||
|
|
f4282aa6fd | ||
|
|
40ee17167e | ||
|
|
f3e933f0c1 | ||
|
|
0ae02f3030 | ||
|
|
e401859afb | ||
|
|
af4100e07d | ||
|
|
ea5bbe0857 | ||
|
|
6822a58413 | ||
|
|
09d39e260d | ||
|
|
1579d2a8ec | ||
|
|
eba5dd831f | ||
|
|
9ffb698c8d | ||
|
|
efbb850d92 | ||
|
|
cfd57c480a | ||
|
|
e105a3f391 | ||
|
|
5d8cfff3f2 | ||
|
|
673dda77c0 | ||
|
|
1ab4c710e1 | ||
|
|
feedf0ebce | ||
|
|
1a490acd67 | ||
|
|
187518a8a3 | ||
|
|
a232c833dc | ||
|
|
c84643c6a9 | ||
|
|
8390a8aaf3 | ||
|
|
1e1a1f3078 | ||
|
|
abe9fa261f | ||
|
|
6001b45bf7 | ||
|
|
6bee0aafc2 | ||
|
|
8252ea8e3d | ||
|
|
137d20a06a | ||
|
|
c4e2203e45 | ||
|
|
7d0fa1a686 | ||
|
|
a23d90d270 | ||
|
|
2630411530 | ||
|
|
b9b82d878d | ||
|
|
8b8e230771 | ||
|
|
7c3c6fa431 | ||
|
|
29908906b7 | ||
|
|
bbeb439f41 | ||
|
|
ce14df303b | ||
|
|
3c6671b18b | ||
|
|
86ff1f2bf6 | ||
|
|
0cce6dc31c | ||
|
|
6253ff0187 | ||
|
|
e9943e864f | ||
|
|
a687261804 | ||
|
|
4df8861e09 | ||
|
|
00cedd22aa | ||
|
|
f361ed66de | ||
|
|
7b50a65492 | ||
|
|
c18b119a9b | ||
|
|
61035d68bc | ||
|
|
97f7855de3 | ||
|
|
d44df9d00d | ||
|
|
8d0ba55ecd | ||
|
|
34ea960559 | ||
|
|
5ea01b00df | ||
|
|
48d0ab5276 | ||
|
|
2a79c1a44d | ||
|
|
fd02407863 | ||
|
|
aea9f7d286 | ||
|
|
028c9a5343 | ||
|
|
94136132e3 | ||
|
|
009bd907f2 | ||
|
|
14b312f00d | ||
|
|
206cadfab4 | ||
|
|
4875f7b659 | ||
|
|
6f2093e491 | ||
|
|
16f31b2f73 | ||
|
|
0d65b78168 | ||
|
|
95ebba85ff | ||
|
|
59b343a9bf | ||
|
|
1557c58eef | ||
|
|
c504aa505c | ||
|
|
1b20f6beec | ||
|
|
10e3340863 | ||
|
|
3cf29a777d | ||
|
|
fd1f7b7268 | ||
|
|
090a73f7c5 | ||
|
|
1cfb01a8a6 | ||
|
|
ce62d3d689 | ||
|
|
8c36317b71 | ||
|
|
60a5c35de9 | ||
|
|
9333f707fa | ||
|
|
429f97b887 | ||
|
|
07f4e7d10b | ||
|
|
9ad8250a78 | ||
|
|
9abef3bf1a | ||
|
|
758b44b9c0 |
@@ -1,2 +1,3 @@
|
||||
/restic
|
||||
/.vagrant
|
||||
/.vscode
|
||||
|
||||
+175
@@ -1,3 +1,178 @@
|
||||
Changelog for restic 0.11.0 (2020-11-05)
|
||||
=======================================
|
||||
|
||||
The following sections list the changes in restic 0.11.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
* Fix #1212: Restore timestamps and permissions on intermediate directories
|
||||
* Fix #1756: Mark repository files as read-only when using the local backend
|
||||
* Fix #2241: Hide password in REST backend repository URLs
|
||||
* Fix #2319: Correctly dump directories into tar files
|
||||
* Fix #2491: Don't require `self-update --output` placeholder file
|
||||
* Fix #2834: Fix rare cases of backup command hanging forever
|
||||
* Fix #2938: Fix manpage formatting
|
||||
* Fix #2942: Make --exclude-larger-than handle disappearing files
|
||||
* Fix #2951: Restic generate, help and self-update no longer check passwords
|
||||
* Fix #2979: Make snapshots --json output [] instead of null when no snapshots
|
||||
* Enh #2969: Optimize check for unchanged files during backup
|
||||
* Enh #340: Add support for Volume Shadow Copy Service (VSS) on Windows
|
||||
* Enh #2849: Authenticate to Google Cloud Storage with access token
|
||||
* Enh #1458: New option --repository-file
|
||||
* Enh #2978: Warn if parent snapshot cannot be loaded during backup
|
||||
|
||||
Details
|
||||
-------
|
||||
|
||||
* Bugfix #1212: Restore timestamps and permissions on intermediate directories
|
||||
|
||||
When using the `--include` option of the restore command, restic restored timestamps and
|
||||
permissions only on directories selected by the include pattern. Intermediate directories,
|
||||
which are necessary to restore files located in sub- directories, were created with default
|
||||
permissions. We've fixed the restore command to restore timestamps and permissions for these
|
||||
directories as well.
|
||||
|
||||
https://github.com/restic/restic/issues/1212
|
||||
https://github.com/restic/restic/issues/1402
|
||||
https://github.com/restic/restic/pull/2906
|
||||
|
||||
* Bugfix #1756: Mark repository files as read-only when using the local backend
|
||||
|
||||
Files stored in a local repository were marked as writeable on the filesystem for non-Windows
|
||||
systems, which did not prevent accidental file modifications outside of restic. In addition,
|
||||
the local backend did not work with certain filesystems and network mounts which do not permit
|
||||
modifications of file permissions.
|
||||
|
||||
Restic now marks files stored in a local repository as read-only on the filesystem on
|
||||
non-Windows systems. The error handling is improved to support more filesystems.
|
||||
|
||||
https://github.com/restic/restic/issues/1756
|
||||
https://github.com/restic/restic/issues/2157
|
||||
https://github.com/restic/restic/pull/2989
|
||||
|
||||
* Bugfix #2241: Hide password in REST backend repository URLs
|
||||
|
||||
When using a password in the REST backend repository URL, the password could in some cases be
|
||||
included in the output from restic, e.g. when initializing a repo or during an error.
|
||||
|
||||
The password is now replaced with "***" where applicable.
|
||||
|
||||
https://github.com/restic/restic/issues/2241
|
||||
https://github.com/restic/restic/pull/2658
|
||||
|
||||
* Bugfix #2319: Correctly dump directories into tar files
|
||||
|
||||
The dump command previously wrote directories in a tar file in a way which can cause
|
||||
compatibility problems. This caused, for example, 7zip on Windows to not open tar files
|
||||
containing directories. In addition it was not possible to dump directories with extended
|
||||
attributes. These compatibility problems are now corrected.
|
||||
|
||||
In addition, a tar file now includes the name of the owner and group of a file.
|
||||
|
||||
https://github.com/restic/restic/issues/2319
|
||||
https://github.com/restic/restic/pull/3039
|
||||
|
||||
* Bugfix #2491: Don't require `self-update --output` placeholder file
|
||||
|
||||
`restic self-update --output /path/to/new-restic` used to require that new-restic was an
|
||||
existing file, to be overwritten. Now it's possible to download an updated restic binary to a
|
||||
new path, without first having to create a placeholder file.
|
||||
|
||||
https://github.com/restic/restic/issues/2491
|
||||
https://github.com/restic/restic/pull/2937
|
||||
|
||||
* Bugfix #2834: Fix rare cases of backup command hanging forever
|
||||
|
||||
We've fixed an issue with the backup progress reporting which could cause restic to hang
|
||||
forever right before finishing a backup.
|
||||
|
||||
https://github.com/restic/restic/issues/2834
|
||||
https://github.com/restic/restic/pull/2963
|
||||
|
||||
* Bugfix #2938: Fix manpage formatting
|
||||
|
||||
The manpage formatting in restic v0.10.0 was garbled, which is fixed now.
|
||||
|
||||
https://github.com/restic/restic/issues/2938
|
||||
https://github.com/restic/restic/pull/2977
|
||||
|
||||
* Bugfix #2942: Make --exclude-larger-than handle disappearing files
|
||||
|
||||
There was a small bug in the backup command's --exclude-larger-than option where files that
|
||||
disappeared between scanning and actually backing them up to the repository caused a panic.
|
||||
This is now fixed.
|
||||
|
||||
https://github.com/restic/restic/issues/2942
|
||||
|
||||
* Bugfix #2951: Restic generate, help and self-update no longer check passwords
|
||||
|
||||
The commands `restic cache`, `generate`, `help` and `self-update` don't need passwords, but
|
||||
they previously did run the RESTIC_PASSWORD_COMMAND (if set in the environment), prompting
|
||||
users to authenticate for no reason. They now skip running the password command.
|
||||
|
||||
https://github.com/restic/restic/issues/2951
|
||||
https://github.com/restic/restic/pull/2987
|
||||
|
||||
* Bugfix #2979: Make snapshots --json output [] instead of null when no snapshots
|
||||
|
||||
Restic previously output `null` instead of `[]` for the `--json snapshots` command, when
|
||||
there were no snapshots in the repository. This caused some minor problems when parsing the
|
||||
output, but is now fixed such that `[]` is output when the list of snapshots is empty.
|
||||
|
||||
https://github.com/restic/restic/issues/2979
|
||||
https://github.com/restic/restic/pull/2984
|
||||
|
||||
* Enhancement #2969: Optimize check for unchanged files during backup
|
||||
|
||||
During a backup restic skips processing files which have not changed since the last backup run.
|
||||
Previously this required opening each file once which can be slow on network filesystems. The
|
||||
backup command now checks for file changes before opening a file. This considerably reduces
|
||||
the time to create a backup on network filesystems.
|
||||
|
||||
https://github.com/restic/restic/issues/2969
|
||||
https://github.com/restic/restic/pull/2970
|
||||
|
||||
* Enhancement #340: Add support for Volume Shadow Copy Service (VSS) on Windows
|
||||
|
||||
Volume Shadow Copy Service allows read access to files that are locked by another process using
|
||||
an exclusive lock through a filesystem snapshot. Restic was unable to backup those files
|
||||
before. This update enables backing up these files.
|
||||
|
||||
This needs to be enabled explicitely using the --use-fs-snapshot option of the backup
|
||||
command.
|
||||
|
||||
https://github.com/restic/restic/issues/340
|
||||
https://github.com/restic/restic/pull/2274
|
||||
|
||||
* Enhancement #2849: Authenticate to Google Cloud Storage with access token
|
||||
|
||||
When using the GCS backend, it is now possible to authenticate with OAuth2 access tokens
|
||||
instead of a credentials file by setting the GOOGLE_ACCESS_TOKEN environment variable.
|
||||
|
||||
https://github.com/restic/restic/pull/2849
|
||||
|
||||
* Enhancement #1458: New option --repository-file
|
||||
|
||||
We've added a new command-line option --repository-file as an alternative to -r. This allows
|
||||
to read the repository URL from a file in order to prevent certain types of information leaks,
|
||||
especially for URLs containing credentials.
|
||||
|
||||
https://github.com/restic/restic/issues/1458
|
||||
https://github.com/restic/restic/issues/2900
|
||||
https://github.com/restic/restic/pull/2910
|
||||
|
||||
* Enhancement #2978: Warn if parent snapshot cannot be loaded during backup
|
||||
|
||||
During a backup restic uses the parent snapshot to check whether a file was changed and has to be
|
||||
backed up again. For this check the backup has to read the directories contained in the old
|
||||
snapshot. If a tree blob cannot be loaded, restic now warns about this problem with the backup
|
||||
repository.
|
||||
|
||||
https://github.com/restic/restic/pull/2978
|
||||
|
||||
|
||||
Changelog for restic 0.10.0 (2020-09-19)
|
||||
=======================================
|
||||
|
||||
|
||||
+8
-4
@@ -16,7 +16,8 @@ help also.
|
||||
|
||||
The restic project uses the GitHub infrastructure (see the
|
||||
[project page](https://github.com/restic/restic)) for all related discussions
|
||||
as well as the `#restic` channel on `irc.freenode.net`.
|
||||
as well as the [forum](https://forum.restic.net/) and the `#restic` channel
|
||||
on [irc.freenode.net](https://kiwiirc.com/nextclient/irc.freenode.net/restic).
|
||||
|
||||
If you want to find an area that currently needs improving have a look at the
|
||||
open issues listed at the
|
||||
@@ -25,7 +26,10 @@ for discussing enhancement to the restic tools.
|
||||
|
||||
If you are unsure what to do, please have a look at the issues, especially
|
||||
those tagged
|
||||
[minor complexity](https://github.com/restic/restic/labels/minor%20complexity).
|
||||
[minor complexity](https://github.com/restic/restic/labels/help%3A%20minor%20complexity)
|
||||
or [good first issue](https://github.com/restic/restic/labels/help%3A%20good%20first%20issue).
|
||||
If you are already a bit experienced with the restic internals, take a look
|
||||
at the issues tagged as [help wanted](https://github.com/restic/restic/labels/help%3A%20wanted).
|
||||
|
||||
|
||||
Reporting Bugs
|
||||
@@ -63,7 +67,7 @@ Development Environment
|
||||
The repository contains the code written for restic in the directories
|
||||
`cmd/` and `internal/`.
|
||||
|
||||
Restic requires Go version 1.12 or later for compiling. Clone the repo (without
|
||||
Restic requires Go version 1.13 or later for compiling. Clone the repo (without
|
||||
having `$GOPATH` set) and `cd` into the directory:
|
||||
|
||||
$ unset GOPATH
|
||||
@@ -74,7 +78,7 @@ Then use the `go` tool to build restic:
|
||||
|
||||
$ go build ./cmd/restic
|
||||
$ ./restic version
|
||||
restic 0.9.6-dev (compiled manually) compiled with go1.14 on linux/amd64
|
||||
restic 0.10.0-dev (compiled manually) compiled with go1.15.2 on linux/amd64
|
||||
|
||||
You can run all tests with the following command:
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
[](https://restic.readthedocs.io/en/latest/?badge=latest)
|
||||
[](https://travis-ci.com/restic/restic)
|
||||
[](https://ci.appveyor.com/project/fd0/restic/branch/master)
|
||||
[](https://goreportcard.com/report/github.com/restic/restic)
|
||||
|
||||
# Introduction
|
||||
|
||||
restic is a backup program that is fast, efficient and secure. It supports the three major operating systems (Linux, macOS, Windows) and a few smaller ones (FreeBSD, OpenBSD).
|
||||
|
||||
For detailed usage and installation instructions check out the [documentation](https://restic.readthedocs.io/en/latest).
|
||||
|
||||
You can ask questions in our [Discourse forum](https://forum.restic.net).
|
||||
|
||||
Quick start
|
||||
-----------
|
||||
|
||||
Once you've [installed](https://restic.readthedocs.io/en/latest/020_installation.html) restic, start
|
||||
off with creating a repository for your backups:
|
||||
|
||||
$ restic init --repo /tmp/backup
|
||||
enter password for new backend:
|
||||
enter password again:
|
||||
created restic backend 085b3c76b9 at /tmp/backup
|
||||
Please note that knowledge of your password is required to access the repository.
|
||||
Losing your password means that your data is irrecoverably lost.
|
||||
|
||||
and add some data:
|
||||
|
||||
$ restic --repo /tmp/backup backup ~/work
|
||||
enter password for repository:
|
||||
scan [/home/user/work]
|
||||
scanned 764 directories, 1816 files in 0:00
|
||||
[0:29] 100.00% 54.732 MiB/s 1.582 GiB / 1.582 GiB 2580 / 2580 items 0 errors ETA 0:00
|
||||
duration: 0:29, 54.47MiB/s
|
||||
snapshot 40dc1520 saved
|
||||
|
||||
Next you can either use `restic restore` to restore files or use `restic
|
||||
mount` to mount the repository via fuse and browse the files from previous
|
||||
snapshots.
|
||||
|
||||
For more options check out the [online documentation](https://restic.readthedocs.io/en/latest/).
|
||||
|
||||
# Backends
|
||||
|
||||
Saving a backup on the same machine is nice but not a real backup strategy.
|
||||
Therefore, restic supports the following backends for storing backups natively:
|
||||
|
||||
- [Local directory](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#local)
|
||||
- [sftp server (via SSH)](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#sftp)
|
||||
- [HTTP REST server](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#rest-server) ([protocol](doc/100_references.rst#rest-backend), [rest-server](https://github.com/restic/rest-server))
|
||||
- [AWS S3](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#amazon-s3) (either from Amazon or using the [Minio](https://minio.io) server)
|
||||
- [OpenStack Swift](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#openstack-swift)
|
||||
- [BackBlaze B2](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#backblaze-b2)
|
||||
- [Microsoft Azure Blob Storage](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#microsoft-azure-blob-storage)
|
||||
- [Google Cloud Storage](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#google-cloud-storage)
|
||||
- And many other services via the [rclone](https://rclone.org) [Backend](https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#other-services-via-rclone)
|
||||
|
||||
# Design Principles
|
||||
|
||||
Restic is a program that does backups right and was designed with the
|
||||
following principles in mind:
|
||||
|
||||
- **Easy:** Doing backups should be a frictionless process, otherwise
|
||||
you might be tempted to skip it. Restic should be easy to configure
|
||||
and use, so that, in the event of a data loss, you can just restore
|
||||
it. Likewise, restoring data should not be complicated.
|
||||
|
||||
- **Fast**: Backing up your data with restic should only be limited by
|
||||
your network or hard disk bandwidth so that you can backup your files
|
||||
every day. Nobody does backups if it takes too much time. Restoring
|
||||
backups should only transfer data that is needed for the files that
|
||||
are to be restored, so that this process is also fast.
|
||||
|
||||
- **Verifiable**: Much more important than backup is restore, so restic
|
||||
enables you to easily verify that all data can be restored.
|
||||
|
||||
- **Secure**: Restic uses cryptography to guarantee confidentiality and
|
||||
integrity of your data. The location the backup data is stored is
|
||||
assumed not to be a trusted environment (e.g. a shared space where
|
||||
others like system administrators are able to access your backups).
|
||||
Restic is built to secure your data against such attackers.
|
||||
|
||||
- **Efficient**: With the growth of data, additional snapshots should
|
||||
only take the storage of the actual increment. Even more, duplicate
|
||||
data should be de-duplicated before it is actually written to the
|
||||
storage back end to save precious backup space.
|
||||
|
||||
# Reproducible Builds
|
||||
|
||||
The binaries released with each restic version starting at 0.6.1 are
|
||||
[reproducible](https://reproducible-builds.org/), which means that you can
|
||||
reproduce a byte identical version from the source code for that
|
||||
release. Instructions on how to do that are contained in the
|
||||
[builder repository](https://github.com/restic/builder).
|
||||
|
||||
News
|
||||
----
|
||||
|
||||
You can follow the restic project on Twitter [@resticbackup](https://twitter.com/resticbackup) or by subscribing to
|
||||
the [project blog](https://restic.net/blog/).
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Restic is licensed under [BSD 2-Clause License](https://opensource.org/licenses/BSD-2-Clause). You can find the
|
||||
complete text in [``LICENSE``](LICENSE).
|
||||
|
||||
Sponsorship
|
||||
-----------
|
||||
|
||||
Backend integration tests for Google Cloud Storage and Microsoft Azure Blob
|
||||
Storage are sponsored by [AppsCode](https://appscode.com)!
|
||||
|
||||
[](https://appscode.com)
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
|Documentation| |Build Status| |Build status| |Report Card| |Say Thanks| |Reviewed by Hound|
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
restic is a backup program that is fast, efficient and secure. It supports the three major operating systems (Linux, macOS, Windows) and a few smaller ones (FreeBSD, OpenBSD).
|
||||
|
||||
For detailed usage and installation instructions check out the `documentation <https://restic.readthedocs.io/en/latest>`__.
|
||||
|
||||
You can ask questions in our `Discourse forum <https://forum.restic.net>`__.
|
||||
|
||||
Quick start
|
||||
-----------
|
||||
|
||||
Once you've `installed
|
||||
<https://restic.readthedocs.io/en/latest/020_installation.html>`__ restic, start
|
||||
off with creating a repository for your backups:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ restic init --repo /tmp/backup
|
||||
enter password for new backend:
|
||||
enter password again:
|
||||
created restic backend 085b3c76b9 at /tmp/backup
|
||||
Please note that knowledge of your password is required to access the repository.
|
||||
Losing your password means that your data is irrecoverably lost.
|
||||
|
||||
and add some data:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ restic --repo /tmp/backup backup ~/work
|
||||
enter password for repository:
|
||||
scan [/home/user/work]
|
||||
scanned 764 directories, 1816 files in 0:00
|
||||
[0:29] 100.00% 54.732 MiB/s 1.582 GiB / 1.582 GiB 2580 / 2580 items 0 errors ETA 0:00
|
||||
duration: 0:29, 54.47MiB/s
|
||||
snapshot 40dc1520 saved
|
||||
|
||||
Next you can either use ``restic restore`` to restore files or use ``restic
|
||||
mount`` to mount the repository via fuse and browse the files from previous
|
||||
snapshots.
|
||||
|
||||
For more options check out the `online documentation <https://restic.readthedocs.io/en/latest/>`__.
|
||||
|
||||
Backends
|
||||
--------
|
||||
|
||||
Saving a backup on the same machine is nice but not a real backup strategy.
|
||||
Therefore, restic supports the following backends for storing backups natively:
|
||||
|
||||
- `Local directory <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#local>`__
|
||||
- `sftp server (via SSH) <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#sftp>`__
|
||||
- `HTTP REST server <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#rest-server>`__ (`protocol <doc/100_references.rst#rest-backend>`__ `rest-server <https://github.com/restic/rest-server>`__)
|
||||
- `AWS S3 <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#amazon-s3>`__ (either from Amazon or using the `Minio <https://minio.io>`__ server)
|
||||
- `OpenStack Swift <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#openstack-swift>`__
|
||||
- `BackBlaze B2 <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#backblaze-b2>`__
|
||||
- `Microsoft Azure Blob Storage <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#microsoft-azure-blob-storage>`__
|
||||
- `Google Cloud Storage <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#google-cloud-storage>`__
|
||||
- And many other services via the `rclone <https://rclone.org>`__ `Backend <https://restic.readthedocs.io/en/latest/030_preparing_a_new_repo.html#other-services-via-rclone>`__
|
||||
|
||||
Design Principles
|
||||
-----------------
|
||||
|
||||
Restic is a program that does backups right and was designed with the
|
||||
following principles in mind:
|
||||
|
||||
- **Easy:** Doing backups should be a frictionless process, otherwise
|
||||
you might be tempted to skip it. Restic should be easy to configure
|
||||
and use, so that, in the event of a data loss, you can just restore
|
||||
it. Likewise, restoring data should not be complicated.
|
||||
|
||||
- **Fast**: Backing up your data with restic should only be limited by
|
||||
your network or hard disk bandwidth so that you can backup your files
|
||||
every day. Nobody does backups if it takes too much time. Restoring
|
||||
backups should only transfer data that is needed for the files that
|
||||
are to be restored, so that this process is also fast.
|
||||
|
||||
- **Verifiable**: Much more important than backup is restore, so restic
|
||||
enables you to easily verify that all data can be restored.
|
||||
|
||||
- **Secure**: Restic uses cryptography to guarantee confidentiality and
|
||||
integrity of your data. The location the backup data is stored is
|
||||
assumed not to be a trusted environment (e.g. a shared space where
|
||||
others like system administrators are able to access your backups).
|
||||
Restic is built to secure your data against such attackers.
|
||||
|
||||
- **Efficient**: With the growth of data, additional snapshots should
|
||||
only take the storage of the actual increment. Even more, duplicate
|
||||
data should be de-duplicated before it is actually written to the
|
||||
storage back end to save precious backup space.
|
||||
|
||||
Reproducible Builds
|
||||
-------------------
|
||||
|
||||
The binaries released with each restic version starting at 0.6.1 are
|
||||
`reproducible <https://reproducible-builds.org/>`__, which means that you can
|
||||
easily reproduce a byte identical version from the source code for that
|
||||
release. Instructions on how to do that are contained in the
|
||||
`builder repository <https://github.com/restic/builder>`__.
|
||||
|
||||
News
|
||||
----
|
||||
|
||||
You can follow the restic project on Twitter `@resticbackup <https://twitter.com/resticbackup>`__ or by subscribing to
|
||||
the `development blog <https://restic.net/blog/>`__.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Restic is licensed under `BSD 2-Clause License <https://opensource.org/licenses/BSD-2-Clause>`__. You can find the
|
||||
complete text in ``LICENSE``.
|
||||
|
||||
Sponsorship
|
||||
-----------
|
||||
|
||||
Backend integration tests for Google Cloud Storage and Microsoft Azure Blob
|
||||
Storage are sponsored by `AppsCode <https://appscode.com>`__!
|
||||
|
||||
|AppsCode|
|
||||
|
||||
.. |Documentation| image:: https://readthedocs.org/projects/restic/badge/?version=latest
|
||||
:target: https://restic.readthedocs.io/en/latest/?badge=latest
|
||||
.. |Build Status| image:: https://travis-ci.com/restic/restic.svg?branch=master
|
||||
:target: https://travis-ci.com/restic/restic
|
||||
.. |Build status| image:: https://ci.appveyor.com/api/projects/status/nuy4lfbgfbytw92q/branch/master?svg=true
|
||||
:target: https://ci.appveyor.com/project/fd0/restic/branch/master
|
||||
.. |Report Card| image:: https://goreportcard.com/badge/github.com/restic/restic
|
||||
:target: https://goreportcard.com/report/github.com/restic/restic
|
||||
.. |Say Thanks| image:: https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg
|
||||
:target: https://saythanks.io/to/restic
|
||||
.. |AppsCode| image:: https://cdn.appscode.com/images/logo/appscode/ac-logo-color.png
|
||||
:target: https://appscode.com
|
||||
.. |Reviewed by Hound| image:: https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg
|
||||
:target: https://houndci.com
|
||||
+1
-1
@@ -24,7 +24,7 @@ install:
|
||||
- msiexec /i go1.15.2.windows-amd64.msi /q
|
||||
- go version
|
||||
- go env
|
||||
- appveyor DownloadFile http://sourceforge.netcologne.de/project/gnuwin32/tar/1.13-1/tar-1.13-1-bin.zip -FileName tar.zip
|
||||
- appveyor DownloadFile https://sourceforge.netcologne.de/project/gnuwin32/tar/1.13-1/tar-1.13-1-bin.zip -FileName tar.zip
|
||||
- 7z x tar.zip bin/tar.exe
|
||||
- set PATH=bin/;%PATH%
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Bugfix: Restore timestamps and permissions on intermediate directories
|
||||
|
||||
When using the `--include` option of the restore command, restic restored
|
||||
timestamps and permissions only on directories selected by the include pattern.
|
||||
Intermediate directories, which are necessary to restore files located in sub-
|
||||
directories, were created with default permissions. We've fixed the restore
|
||||
command to restore timestamps and permissions for these directories as well.
|
||||
|
||||
https://github.com/restic/restic/issues/1212
|
||||
https://github.com/restic/restic/issues/1402
|
||||
https://github.com/restic/restic/pull/2906
|
||||
@@ -0,0 +1,15 @@
|
||||
Bugfix: Mark repository files as read-only when using the local backend
|
||||
|
||||
Files stored in a local repository were marked as writeable on the
|
||||
filesystem for non-Windows systems, which did not prevent accidental file
|
||||
modifications outside of restic. In addition, the local backend did not work
|
||||
with certain filesystems and network mounts which do not permit modifications
|
||||
of file permissions.
|
||||
|
||||
restic now marks files stored in a local repository as read-only on the
|
||||
filesystem on non-Windows systems. The error handling is improved to support
|
||||
more filesystems.
|
||||
|
||||
https://github.com/restic/restic/issues/1756
|
||||
https://github.com/restic/restic/issues/2157
|
||||
https://github.com/restic/restic/pull/2989
|
||||
@@ -0,0 +1,10 @@
|
||||
Bugfix: Hide password in REST backend repository URLs
|
||||
|
||||
When using a password in the REST backend repository URL,
|
||||
the password could in some cases be included in the output
|
||||
from restic, e.g. when initializing a repo or during an error.
|
||||
|
||||
The password is now replaced with "***" where applicable.
|
||||
|
||||
https://github.com/restic/restic/issues/2241
|
||||
https://github.com/restic/restic/pull/2658
|
||||
@@ -0,0 +1,12 @@
|
||||
Bugfix: Correctly dump directories into tar files
|
||||
|
||||
The dump command previously wrote directories in a tar file in a way which
|
||||
can cause compatibility problems. This caused, for example, 7zip on Windows
|
||||
to not open tar files containing directories. In addition it was not possible
|
||||
to dump directories with extended attributes. These compatibility problems
|
||||
are now corrected.
|
||||
|
||||
In addition, a tar file now includes the name of the owner and group of a file.
|
||||
|
||||
https://github.com/restic/restic/issues/2319
|
||||
https://github.com/restic/restic/pull/3039
|
||||
@@ -0,0 +1,9 @@
|
||||
Bugfix: Don't require `self-update --output` placeholder file
|
||||
|
||||
`restic self-update --output /path/to/new-restic` used to require that
|
||||
new-restic was an existing file, to be overwritten. Now it's possible
|
||||
to download an updated restic binary to a new path, without first
|
||||
having to create a placeholder file.
|
||||
|
||||
https://github.com/restic/restic/issues/2491
|
||||
https://github.com/restic/restic/pull/2937
|
||||
@@ -0,0 +1,7 @@
|
||||
Bugfix: Fix rare cases of backup command hanging forever
|
||||
|
||||
We've fixed an issue with the backup progress reporting which could cause
|
||||
restic to hang forever right before finishing a backup.
|
||||
|
||||
https://github.com/restic/restic/issues/2834
|
||||
https://github.com/restic/restic/pull/2963
|
||||
@@ -0,0 +1,6 @@
|
||||
Bugfix: Fix manpage formatting
|
||||
|
||||
The manpage formatting in restic v0.10.0 was garbled, which is fixed now.
|
||||
|
||||
https://github.com/restic/restic/issues/2938
|
||||
https://github.com/restic/restic/pull/2977
|
||||
@@ -0,0 +1,7 @@
|
||||
Bugfix: Make --exclude-larger-than handle disappearing files
|
||||
|
||||
There was a small bug in the backup command's --exclude-larger-than
|
||||
option where files that disappeared between scanning and actually
|
||||
backing them up to the repository caused a panic. This is now fixed.
|
||||
|
||||
https://github.com/restic/restic/issues/2942
|
||||
@@ -0,0 +1,9 @@
|
||||
Bugfix: restic generate, help and self-update no longer check passwords
|
||||
|
||||
The commands `restic cache`, `generate`, `help` and `self-update` don't need
|
||||
passwords, but they previously did run the RESTIC_PASSWORD_COMMAND (if set in
|
||||
the environment), prompting users to authenticate for no reason. They now skip
|
||||
running the password command.
|
||||
|
||||
https://github.com/restic/restic/issues/2951
|
||||
https://github.com/restic/restic/pull/2987
|
||||
@@ -0,0 +1,9 @@
|
||||
Enhancement: Optimize check for unchanged files during backup
|
||||
|
||||
During a backup restic skips processing files which have not changed since the last backup run.
|
||||
Previously this required opening each file once which can be slow on network filesystems. The
|
||||
backup command now checks for file changes before opening a file. This considerably reduces
|
||||
the time to create a backup on network filesystems.
|
||||
|
||||
https://github.com/restic/restic/issues/2969
|
||||
https://github.com/restic/restic/pull/2970
|
||||
@@ -0,0 +1,9 @@
|
||||
Bugfix: Make snapshots --json output [] instead of null when no snapshots
|
||||
|
||||
Restic previously output `null` instead of `[]` for the `--json snapshots`
|
||||
command, when there were no snapshots in the repository. This caused some
|
||||
minor problems when parsing the output, but is now fixed such that `[]` is
|
||||
output when the list of snapshots is empty.
|
||||
|
||||
https://github.com/restic/restic/issues/2979
|
||||
https://github.com/restic/restic/pull/2984
|
||||
@@ -0,0 +1,12 @@
|
||||
Enhancement: Add support for Volume Shadow Copy Service (VSS) on Windows
|
||||
|
||||
Volume Shadow Copy Service allows read access to files that are locked by
|
||||
another process using an exclusive lock through a filesystem snapshot. Restic
|
||||
was unable to backup those files before. This update enables backing up these
|
||||
files.
|
||||
|
||||
This needs to be enabled explicitely using the --use-fs-snapshot option of the
|
||||
backup command.
|
||||
|
||||
https://github.com/restic/restic/issues/340
|
||||
https://github.com/restic/restic/pull/2274
|
||||
@@ -0,0 +1,7 @@
|
||||
Enhancement: Authenticate to Google Cloud Storage with access token
|
||||
|
||||
When using the GCS backend, it is now possible to authenticate with OAuth2
|
||||
access tokens instead of a credentials file by setting the GOOGLE_ACCESS_TOKEN
|
||||
environment variable.
|
||||
|
||||
https://github.com/restic/restic/pull/2849
|
||||
@@ -0,0 +1,10 @@
|
||||
Enhancement: New option --repository-file
|
||||
|
||||
We've added a new command-line option --repository-file as an alternative
|
||||
to -r. This allows to read the repository URL from a file in order to
|
||||
prevent certain types of information leaks, especially for URLs containing
|
||||
credentials.
|
||||
|
||||
https://github.com/restic/restic/issues/1458
|
||||
https://github.com/restic/restic/issues/2900
|
||||
https://github.com/restic/restic/pull/2910
|
||||
@@ -0,0 +1,8 @@
|
||||
Enhancement: Warn if parent snapshot cannot be loaded during backup
|
||||
|
||||
During a backup restic uses the parent snapshot to check whether a file was
|
||||
changed and has to be backed up again. For this check the backup has to read
|
||||
the directories contained in the old snapshot. If a tree blob cannot be
|
||||
loaded, restic now warns about this problem with the backup repository.
|
||||
|
||||
https://github.com/restic/restic/pull/2978
|
||||
+16
-6
@@ -1,11 +1,21 @@
|
||||
Bugfix: Fix behavior for foobar (in present tense)
|
||||
# The first line must start with Bugfix:, Enhancement: or Change:,
|
||||
# including the colon. Use present use. Remove lines starting with '#'
|
||||
# from this template.
|
||||
Enhancement: Allow custom bar in the foo command
|
||||
|
||||
We've fixed the behavior for foobar, a long-standing annoyance for restic
|
||||
users.
|
||||
# Describe the problem in the past tense, the new behavior in the present
|
||||
# tense. Mention the affected commands, backends, operating systems, etc.
|
||||
# Focus on user-facing behavior, not the implementation.
|
||||
|
||||
The text in the paragraphs is written in past tense. The last section is a list
|
||||
of issue URLs, PR URLs and other URLs. The first issue ID (or the first PR ID,
|
||||
in case there aren't any issue links) is used as the primary ID.
|
||||
Restic foo always used the system-wide bar when deciding how to frob an
|
||||
item in the baz backend. It now permits selecting the bar with --bar or
|
||||
the environment variable RESTIC_BAR. The system-wide bar is still the
|
||||
default.
|
||||
|
||||
# The last section is a list of issue, PR and forum URLs.
|
||||
# The first issue ID determines the filename for the changelog entry:
|
||||
# changelog/unreleased/issue-1234. If there are no relevant issue links,
|
||||
# use the PR ID and call the file pull-55555.
|
||||
|
||||
https://github.com/restic/restic/issues/1234
|
||||
https://github.com/restic/restic/pull/55555
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# this file is here so the unreleased/ directory is tracked within git, even if
|
||||
# no other changelog files are present.
|
||||
@@ -0,0 +1,11 @@
|
||||
Bugfix: Restore timestamps and permissions on intermediate directories
|
||||
|
||||
When using the `--include` option of the restore command, restic restored
|
||||
timestamps and permissions only on directories selected by the include pattern.
|
||||
Intermediate directories, which are necessary to restore files located in sub-
|
||||
directories, were created with default permissions. We've fixed the restore
|
||||
command to restore timestamps and permissions for these directories as well.
|
||||
|
||||
https://github.com/restic/restic/issues/1212
|
||||
https://github.com/restic/restic/issues/1402
|
||||
https://github.com/restic/restic/pull/2906
|
||||
@@ -0,0 +1,15 @@
|
||||
Bugfix: Mark repository files as read-only when using the local backend
|
||||
|
||||
Files stored in a local repository were marked as writeable on the
|
||||
filesystem for non-Windows systems, which did not prevent accidental file
|
||||
modifications outside of restic. In addition, the local backend did not work
|
||||
with certain filesystems and network mounts which do not permit modifications
|
||||
of file permissions.
|
||||
|
||||
restic now marks files stored in a local repository as read-only on the
|
||||
filesystem on non-Windows systems. The error handling is improved to support
|
||||
more filesystems.
|
||||
|
||||
https://github.com/restic/restic/issues/1756
|
||||
https://github.com/restic/restic/issues/2157
|
||||
https://github.com/restic/restic/pull/2989
|
||||
@@ -0,0 +1,10 @@
|
||||
Bugfix: Hide password in REST backend repository URLs
|
||||
|
||||
When using a password in the REST backend repository URL,
|
||||
the password could in some cases be included in the output
|
||||
from restic, e.g. when initializing a repo or during an error.
|
||||
|
||||
The password is now replaced with "***" where applicable.
|
||||
|
||||
https://github.com/restic/restic/issues/2241
|
||||
https://github.com/restic/restic/pull/2658
|
||||
@@ -0,0 +1,12 @@
|
||||
Bugfix: Correctly dump directories into tar files
|
||||
|
||||
The dump command previously wrote directories in a tar file in a way which
|
||||
can cause compatibility problems. This caused, for example, 7zip on Windows
|
||||
to not open tar files containing directories. In addition it was not possible
|
||||
to dump directories with extended attributes. These compatibility problems
|
||||
are now corrected.
|
||||
|
||||
In addition, a tar file now includes the name of the owner and group of a file.
|
||||
|
||||
https://github.com/restic/restic/issues/2319
|
||||
https://github.com/restic/restic/pull/3039
|
||||
@@ -0,0 +1,9 @@
|
||||
Bugfix: Don't require `self-update --output` placeholder file
|
||||
|
||||
`restic self-update --output /path/to/new-restic` used to require that
|
||||
new-restic was an existing file, to be overwritten. Now it's possible
|
||||
to download an updated restic binary to a new path, without first
|
||||
having to create a placeholder file.
|
||||
|
||||
https://github.com/restic/restic/issues/2491
|
||||
https://github.com/restic/restic/pull/2937
|
||||
@@ -0,0 +1,7 @@
|
||||
Bugfix: Fix rare cases of backup command hanging forever
|
||||
|
||||
We've fixed an issue with the backup progress reporting which could cause
|
||||
restic to hang forever right before finishing a backup.
|
||||
|
||||
https://github.com/restic/restic/issues/2834
|
||||
https://github.com/restic/restic/pull/2963
|
||||
@@ -0,0 +1,6 @@
|
||||
Bugfix: Fix manpage formatting
|
||||
|
||||
The manpage formatting in restic v0.10.0 was garbled, which is fixed now.
|
||||
|
||||
https://github.com/restic/restic/issues/2938
|
||||
https://github.com/restic/restic/pull/2977
|
||||
@@ -0,0 +1,7 @@
|
||||
Bugfix: Make --exclude-larger-than handle disappearing files
|
||||
|
||||
There was a small bug in the backup command's --exclude-larger-than
|
||||
option where files that disappeared between scanning and actually
|
||||
backing them up to the repository caused a panic. This is now fixed.
|
||||
|
||||
https://github.com/restic/restic/issues/2942
|
||||
@@ -0,0 +1,9 @@
|
||||
Bugfix: restic generate, help and self-update no longer check passwords
|
||||
|
||||
The commands `restic cache`, `generate`, `help` and `self-update` don't need
|
||||
passwords, but they previously did run the RESTIC_PASSWORD_COMMAND (if set in
|
||||
the environment), prompting users to authenticate for no reason. They now skip
|
||||
running the password command.
|
||||
|
||||
https://github.com/restic/restic/issues/2951
|
||||
https://github.com/restic/restic/pull/2987
|
||||
@@ -0,0 +1,9 @@
|
||||
Enhancement: Optimize check for unchanged files during backup
|
||||
|
||||
During a backup restic skips processing files which have not changed since the last backup run.
|
||||
Previously this required opening each file once which can be slow on network filesystems. The
|
||||
backup command now checks for file changes before opening a file. This considerably reduces
|
||||
the time to create a backup on network filesystems.
|
||||
|
||||
https://github.com/restic/restic/issues/2969
|
||||
https://github.com/restic/restic/pull/2970
|
||||
@@ -0,0 +1,9 @@
|
||||
Bugfix: Make snapshots --json output [] instead of null when no snapshots
|
||||
|
||||
Restic previously output `null` instead of `[]` for the `--json snapshots`
|
||||
command, when there were no snapshots in the repository. This caused some
|
||||
minor problems when parsing the output, but is now fixed such that `[]` is
|
||||
output when the list of snapshots is empty.
|
||||
|
||||
https://github.com/restic/restic/issues/2979
|
||||
https://github.com/restic/restic/pull/2984
|
||||
@@ -0,0 +1,12 @@
|
||||
Enhancement: Add support for Volume Shadow Copy Service (VSS) on Windows
|
||||
|
||||
Volume Shadow Copy Service allows read access to files that are locked by
|
||||
another process using an exclusive lock through a filesystem snapshot. Restic
|
||||
was unable to backup those files before. This update enables backing up these
|
||||
files.
|
||||
|
||||
This needs to be enabled explicitely using the --use-fs-snapshot option of the
|
||||
backup command.
|
||||
|
||||
https://github.com/restic/restic/issues/340
|
||||
https://github.com/restic/restic/pull/2274
|
||||
@@ -0,0 +1,7 @@
|
||||
Enhancement: Authenticate to Google Cloud Storage with access token
|
||||
|
||||
When using the GCS backend, it is now possible to authenticate with OAuth2
|
||||
access tokens instead of a credentials file by setting the GOOGLE_ACCESS_TOKEN
|
||||
environment variable.
|
||||
|
||||
https://github.com/restic/restic/pull/2849
|
||||
@@ -0,0 +1,10 @@
|
||||
Enhancement: New option --repository-file
|
||||
|
||||
We've added a new command-line option --repository-file as an alternative
|
||||
to -r. This allows to read the repository URL from a file in order to
|
||||
prevent certain types of information leaks, especially for URLs containing
|
||||
credentials.
|
||||
|
||||
https://github.com/restic/restic/issues/1458
|
||||
https://github.com/restic/restic/issues/2900
|
||||
https://github.com/restic/restic/pull/2910
|
||||
@@ -0,0 +1,8 @@
|
||||
Enhancement: Warn if parent snapshot cannot be loaded during backup
|
||||
|
||||
During a backup restic uses the parent snapshot to check whether a file was
|
||||
changed and has to be backed up again. For this check the backup has to read
|
||||
the directories contained in the old snapshot. If a tree blob cannot be
|
||||
loaded, restic now warns about this problem with the backup repository.
|
||||
|
||||
https://github.com/restic/restic/pull/2978
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -96,6 +97,7 @@ type BackupOptions struct {
|
||||
TimeStamp string
|
||||
WithAtime bool
|
||||
IgnoreInode bool
|
||||
UseFsSnapshot bool
|
||||
}
|
||||
|
||||
var backupOptions BackupOptions
|
||||
@@ -129,6 +131,9 @@ func init() {
|
||||
f.StringVar(&backupOptions.TimeStamp, "time", "", "`time` of the backup (ex. '2012-11-01 22:08:41') (default: now)")
|
||||
f.BoolVar(&backupOptions.WithAtime, "with-atime", false, "store the atime for all files and directories")
|
||||
f.BoolVar(&backupOptions.IgnoreInode, "ignore-inode", false, "ignore inode number changes when checking for modified files")
|
||||
if runtime.GOOS == "windows" {
|
||||
f.BoolVar(&backupOptions.UseFsSnapshot, "use-fs-snapshot", false, "use filesystem snapshot where possible (currently only Windows VSS)")
|
||||
}
|
||||
}
|
||||
|
||||
// filterExisting returns a slice of all existing items, or an error if no
|
||||
@@ -394,7 +399,7 @@ func collectTargets(opts BackupOptions, args []string) (targets []string, err er
|
||||
func findParentSnapshot(ctx context.Context, repo restic.Repository, opts BackupOptions, targets []string) (parentID *restic.ID, err error) {
|
||||
// Force using a parent
|
||||
if !opts.Force && opts.Parent != "" {
|
||||
id, err := restic.FindSnapshot(repo, opts.Parent)
|
||||
id, err := restic.FindSnapshot(ctx, repo, opts.Parent)
|
||||
if err != nil {
|
||||
return nil, errors.Fatalf("invalid id %q: %v", opts.Parent, err)
|
||||
}
|
||||
@@ -496,7 +501,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
||||
if !gopts.JSON {
|
||||
p.V("lock repository")
|
||||
}
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -550,6 +555,25 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
||||
}
|
||||
|
||||
var targetFS fs.FS = fs.Local{}
|
||||
if runtime.GOOS == "windows" && opts.UseFsSnapshot {
|
||||
if err = fs.HasSufficientPrivilegesForVSS(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
errorHandler := func(item string, err error) error {
|
||||
return p.Error(item, nil, err)
|
||||
}
|
||||
|
||||
messageHandler := func(msg string, args ...interface{}) {
|
||||
if !gopts.JSON {
|
||||
p.P(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
localVss := fs.NewLocalVss(errorHandler, messageHandler)
|
||||
defer localVss.DeleteSnapshots()
|
||||
targetFS = localVss
|
||||
}
|
||||
if opts.Stdin {
|
||||
if !gopts.JSON {
|
||||
p.V("read data from stdin")
|
||||
|
||||
@@ -51,7 +51,7 @@ func init() {
|
||||
|
||||
func runCache(opts CacheOptions, gopts GlobalOptions, args []string) error {
|
||||
if len(args) > 0 {
|
||||
return errors.Fatal("the cache command has no arguments")
|
||||
return errors.Fatal("the cache command expects no arguments, only options - please see `restic help cache` for usage and flags")
|
||||
}
|
||||
|
||||
if gopts.NoCache {
|
||||
|
||||
@@ -42,7 +42,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -59,7 +59,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
// find snapshot id with prefix
|
||||
id, err = restic.FindSnapshot(repo, args[1])
|
||||
id, err = restic.FindSnapshot(gopts.ctx, repo, args[1])
|
||||
if err != nil {
|
||||
return errors.Fatalf("could not find snapshot: %v\n", err)
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ func prepareCheckCache(opts CheckOptions, gopts *GlobalOptions) (cleanup func())
|
||||
|
||||
func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||
if len(args) != 0 {
|
||||
return errors.Fatal("check has no arguments")
|
||||
return errors.Fatal("the check command expects no arguments, only options - please see `restic help check` for usage and flags")
|
||||
}
|
||||
|
||||
cleanup := prepareCheckCache(opts, &gopts)
|
||||
@@ -158,7 +158,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||
|
||||
if !gopts.NoLock {
|
||||
Verbosef("create exclusive lock for repository\n")
|
||||
lock, err := lockRepoExclusive(repo)
|
||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -65,13 +65,13 @@ func runCopy(opts CopyOptions, gopts GlobalOptions, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
srcLock, err := lockRepo(srcRepo)
|
||||
srcLock, err := lockRepo(ctx, srcRepo)
|
||||
defer unlockRepo(srcLock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dstLock, err := lockRepo(dstRepo)
|
||||
dstLock, err := lockRepo(ctx, dstRepo)
|
||||
defer unlockRepo(dstLock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+15
-15
@@ -54,9 +54,9 @@ func prettyPrintJSON(wr io.Writer, item interface{}) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func debugPrintSnapshots(repo *repository.Repository, wr io.Writer) error {
|
||||
return repo.List(context.TODO(), restic.SnapshotFile, func(id restic.ID, size int64) error {
|
||||
snapshot, err := restic.LoadSnapshot(context.TODO(), repo, id)
|
||||
func debugPrintSnapshots(ctx context.Context, repo *repository.Repository, wr io.Writer) error {
|
||||
return repo.List(ctx, restic.SnapshotFile, func(id restic.ID, size int64) error {
|
||||
snapshot, err := restic.LoadSnapshot(ctx, repo, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -82,12 +82,12 @@ type Blob struct {
|
||||
Offset uint `json:"offset"`
|
||||
}
|
||||
|
||||
func printPacks(repo *repository.Repository, wr io.Writer) error {
|
||||
func printPacks(ctx context.Context, repo *repository.Repository, wr io.Writer) error {
|
||||
|
||||
return repo.List(context.TODO(), restic.PackFile, func(id restic.ID, size int64) error {
|
||||
return repo.List(ctx, restic.PackFile, func(id restic.ID, size int64) error {
|
||||
h := restic.Handle{Type: restic.PackFile, Name: id.String()}
|
||||
|
||||
blobs, err := pack.List(repo.Key(), restic.ReaderAt(repo.Backend(), h), size)
|
||||
blobs, err := pack.List(repo.Key(), restic.ReaderAt(ctx, repo.Backend(), h), size)
|
||||
if err != nil {
|
||||
Warnf("error for pack %v: %v\n", id.Str(), err)
|
||||
return nil
|
||||
@@ -110,11 +110,11 @@ func printPacks(repo *repository.Repository, wr io.Writer) error {
|
||||
})
|
||||
}
|
||||
|
||||
func dumpIndexes(repo restic.Repository, wr io.Writer) error {
|
||||
return repo.List(context.TODO(), restic.IndexFile, func(id restic.ID, size int64) error {
|
||||
func dumpIndexes(ctx context.Context, repo restic.Repository, wr io.Writer) error {
|
||||
return repo.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
|
||||
Printf("index_id: %v\n", id)
|
||||
|
||||
idx, err := repository.LoadIndex(context.TODO(), repo, id)
|
||||
idx, err := repository.LoadIndex(ctx, repo, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -134,7 +134,7 @@ func runDebugDump(gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
if !gopts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -145,20 +145,20 @@ func runDebugDump(gopts GlobalOptions, args []string) error {
|
||||
|
||||
switch tpe {
|
||||
case "indexes":
|
||||
return dumpIndexes(repo, gopts.stdout)
|
||||
return dumpIndexes(gopts.ctx, repo, gopts.stdout)
|
||||
case "snapshots":
|
||||
return debugPrintSnapshots(repo, gopts.stdout)
|
||||
return debugPrintSnapshots(gopts.ctx, repo, gopts.stdout)
|
||||
case "packs":
|
||||
return printPacks(repo, gopts.stdout)
|
||||
return printPacks(gopts.ctx, repo, gopts.stdout)
|
||||
case "all":
|
||||
Printf("snapshots:\n")
|
||||
err := debugPrintSnapshots(repo, gopts.stdout)
|
||||
err := debugPrintSnapshots(gopts.ctx, repo, gopts.stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Printf("\nindexes:\n")
|
||||
err = dumpIndexes(repo, gopts.stdout)
|
||||
err = dumpIndexes(gopts.ctx, repo, gopts.stdout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func init() {
|
||||
}
|
||||
|
||||
func loadSnapshot(ctx context.Context, repo *repository.Repository, desc string) (*restic.Snapshot, error) {
|
||||
id, err := restic.FindSnapshot(repo, desc)
|
||||
id, err := restic.FindSnapshot(ctx, repo, desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -332,7 +332,7 @@ func runDiff(opts DiffOptions, gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
if !gopts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -140,7 +140,7 @@ func runDump(opts DumpOptions, gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
if !gopts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -160,7 +160,7 @@ func runDump(opts DumpOptions, gopts GlobalOptions, args []string) error {
|
||||
Exitf(1, "latest snapshot for criteria not found: %v Paths:%v Hosts:%v", err, opts.Paths, opts.Hosts)
|
||||
}
|
||||
} else {
|
||||
id, err = restic.FindSnapshot(repo, snapshotIDString)
|
||||
id, err = restic.FindSnapshot(ctx, repo, snapshotIDString)
|
||||
if err != nil {
|
||||
Exitf(1, "invalid id %q: %v", snapshotIDString, err)
|
||||
}
|
||||
|
||||
@@ -529,7 +529,7 @@ func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
if !gopts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -73,7 +73,7 @@ func init() {
|
||||
f.Var(&forgetOptions.Tags, "tag", "only consider snapshots which include this `taglist` in the format `tag[,tag,...]` (can be specified multiple times)")
|
||||
|
||||
f.StringArrayVar(&forgetOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path` (can be specified multiple times)")
|
||||
f.BoolVarP(&forgetOptions.Compact, "compact", "c", false, "use compact format")
|
||||
f.BoolVarP(&forgetOptions.Compact, "compact", "c", false, "use compact output format")
|
||||
|
||||
f.StringVarP(&forgetOptions.GroupBy, "group-by", "g", "host,paths", "string for grouping snapshots by host,paths,tags")
|
||||
f.BoolVarP(&forgetOptions.DryRun, "dry-run", "n", false, "do not delete anything, just print what would be done")
|
||||
@@ -88,7 +88,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
lock, err := lockRepoExclusive(repo)
|
||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+10
-4
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"github.com/restic/chunker"
|
||||
"github.com/restic/restic/internal/backend/location"
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/repository"
|
||||
|
||||
@@ -51,9 +52,14 @@ func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
be, err := create(gopts.Repo, gopts.extended)
|
||||
repo, err := ReadRepo(gopts)
|
||||
if err != nil {
|
||||
return errors.Fatalf("create repository at %s failed: %v\n", gopts.Repo, err)
|
||||
return err
|
||||
}
|
||||
|
||||
be, err := create(repo, gopts.extended)
|
||||
if err != nil {
|
||||
return errors.Fatalf("create repository at %s failed: %v\n", location.StripPassword(gopts.Repo), err)
|
||||
}
|
||||
|
||||
gopts.password, err = ReadPasswordTwice(gopts,
|
||||
@@ -67,10 +73,10 @@ func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
|
||||
|
||||
err = s.Init(gopts.ctx, gopts.password, chunkerPolynomial)
|
||||
if err != nil {
|
||||
return errors.Fatalf("create key in repository at %s failed: %v\n", gopts.Repo, err)
|
||||
return errors.Fatalf("create key in repository at %s failed: %v\n", location.StripPassword(gopts.Repo), err)
|
||||
}
|
||||
|
||||
Verbosef("created restic repository %v at %s\n", s.Config().ID[:10], gopts.Repo)
|
||||
Verbosef("created restic repository %v at %s\n", s.Config().ID[:10], location.StripPassword(gopts.Repo))
|
||||
Verbosef("\n")
|
||||
Verbosef("Please note that knowledge of your password is required to access\n")
|
||||
Verbosef("the repository. Losing your password means that your data is\n")
|
||||
|
||||
@@ -188,7 +188,7 @@ func runKey(gopts GlobalOptions, args []string) error {
|
||||
|
||||
switch args[0] {
|
||||
case "list":
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -196,7 +196,7 @@ func runKey(gopts GlobalOptions, args []string) error {
|
||||
|
||||
return listKeys(ctx, repo, gopts)
|
||||
case "add":
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -204,20 +204,20 @@ func runKey(gopts GlobalOptions, args []string) error {
|
||||
|
||||
return addKey(gopts, repo)
|
||||
case "remove":
|
||||
lock, err := lockRepoExclusive(repo)
|
||||
lock, err := lockRepoExclusive(ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
id, err := restic.Find(repo.Backend(), restic.KeyFile, args[1])
|
||||
id, err := restic.Find(ctx, repo.Backend(), restic.KeyFile, args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return deleteKey(gopts.ctx, repo, id)
|
||||
case "passwd":
|
||||
lock, err := lockRepoExclusive(repo)
|
||||
lock, err := lockRepoExclusive(ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -40,7 +40,7 @@ func runList(cmd *cobra.Command, opts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
if !opts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(opts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -99,7 +99,7 @@ func runMigrate(opts MigrateOptions, gopts GlobalOptions, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
lock, err := lockRepoExclusive(repo)
|
||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+23
-30
@@ -81,7 +81,17 @@ func init() {
|
||||
mountFlags.StringVar(&mountOptions.SnapshotTemplate, "snapshot-template", time.RFC3339, "set `template` to use for snapshot dirs")
|
||||
}
|
||||
|
||||
func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
|
||||
func runMount(opts MountOptions, gopts GlobalOptions, args []string) error {
|
||||
if opts.SnapshotTemplate == "" {
|
||||
return errors.Fatal("snapshot template string cannot be empty")
|
||||
}
|
||||
if strings.ContainsAny(opts.SnapshotTemplate, `\/`) {
|
||||
return errors.Fatal("snapshot template string contains a slash (/) or backslash (\\) character")
|
||||
}
|
||||
if len(args) == 0 {
|
||||
return errors.Fatal("wrong number of parameters")
|
||||
}
|
||||
|
||||
debug.Log("start mount")
|
||||
defer debug.Log("finish mount")
|
||||
|
||||
@@ -91,7 +101,7 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
|
||||
}
|
||||
|
||||
if !gopts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -103,6 +113,8 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
mountpoint := args[0]
|
||||
|
||||
if _, err := resticfs.Stat(mountpoint); os.IsNotExist(errors.Cause(err)) {
|
||||
Verbosef("Mountpoint %s doesn't exist, creating it\n", mountpoint)
|
||||
err = resticfs.Mkdir(mountpoint, os.ModeDir|0700)
|
||||
@@ -110,7 +122,6 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
mountOptions := []systemFuse.MountOption{
|
||||
systemFuse.ReadOnly(),
|
||||
systemFuse.FSName("restic"),
|
||||
@@ -125,6 +136,15 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
|
||||
}
|
||||
}
|
||||
|
||||
AddCleanupHandler(func() error {
|
||||
debug.Log("running umount cleanup handler for mount at %v", mountpoint)
|
||||
err := umount(mountpoint)
|
||||
if err != nil {
|
||||
Warnf("unable to umount (maybe already umounted or still in use?): %v\n", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
c, err := systemFuse.Mount(mountpoint, mountOptions...)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -159,30 +179,3 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
|
||||
func umount(mountpoint string) error {
|
||||
return systemFuse.Unmount(mountpoint)
|
||||
}
|
||||
|
||||
func runMount(opts MountOptions, gopts GlobalOptions, args []string) error {
|
||||
if opts.SnapshotTemplate == "" {
|
||||
return errors.Fatal("snapshot template string cannot be empty")
|
||||
}
|
||||
|
||||
if strings.ContainsAny(opts.SnapshotTemplate, `\/`) {
|
||||
return errors.Fatal("snapshot template string contains a slash (/) or backslash (\\) character")
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
return errors.Fatal("wrong number of parameters")
|
||||
}
|
||||
|
||||
mountpoint := args[0]
|
||||
|
||||
AddCleanupHandler(func() error {
|
||||
debug.Log("running umount cleanup handler for mount at %v", mountpoint)
|
||||
err := umount(mountpoint)
|
||||
if err != nil {
|
||||
Warnf("unable to umount (maybe already umounted or still in use?): %v\n", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
return mount(opts, gopts, mountpoint)
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ func runPrune(gopts GlobalOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
lock, err := lockRepoExclusive(repo)
|
||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -38,7 +38,7 @@ func runRebuildIndex(gopts GlobalOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
lock, err := lockRepoExclusive(repo)
|
||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -13,7 +13,7 @@ var cmdRecover = &cobra.Command{
|
||||
Use: "recover [flags]",
|
||||
Short: "Recover data from the repository",
|
||||
Long: `
|
||||
The "recover" command build a new snapshot from all directories it can find in
|
||||
The "recover" command builds a new snapshot from all directories it can find in
|
||||
the raw data of the repository. It can be used if, for example, a snapshot has
|
||||
been removed by accident with "forget".
|
||||
|
||||
@@ -43,7 +43,7 @@ func runRecover(gopts GlobalOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -102,7 +102,7 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
if !gopts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -122,13 +122,13 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||
Exitf(1, "latest snapshot for criteria not found: %v Paths:%v Hosts:%v", err, opts.Paths, opts.Hosts)
|
||||
}
|
||||
} else {
|
||||
id, err = restic.FindSnapshot(repo, snapshotIDString)
|
||||
id, err = restic.FindSnapshot(ctx, repo, snapshotIDString)
|
||||
if err != nil {
|
||||
Exitf(1, "invalid id %q: %v", snapshotIDString, err)
|
||||
}
|
||||
}
|
||||
|
||||
res, err := restorer.NewRestorer(repo, id)
|
||||
res, err := restorer.NewRestorer(ctx, repo, id)
|
||||
if err != nil {
|
||||
Exitf(2, "creating restorer failed: %v\n", err)
|
||||
}
|
||||
@@ -140,13 +140,15 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
excludePatterns := filter.ParsePatterns(opts.Exclude)
|
||||
insensitiveExcludePatterns := filter.ParsePatterns(opts.InsensitiveExclude)
|
||||
selectExcludeFilter := func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
|
||||
matched, _, err := filter.List(opts.Exclude, item)
|
||||
matched, err := filter.List(excludePatterns, item)
|
||||
if err != nil {
|
||||
Warnf("error for exclude pattern: %v", err)
|
||||
}
|
||||
|
||||
matchedInsensitive, _, err := filter.List(opts.InsensitiveExclude, strings.ToLower(item))
|
||||
matchedInsensitive, err := filter.List(insensitiveExcludePatterns, strings.ToLower(item))
|
||||
if err != nil {
|
||||
Warnf("error for iexclude pattern: %v", err)
|
||||
}
|
||||
@@ -161,13 +163,15 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||
return selectedForRestore, childMayBeSelected
|
||||
}
|
||||
|
||||
includePatterns := filter.ParsePatterns(opts.Include)
|
||||
insensitiveIncludePatterns := filter.ParsePatterns(opts.InsensitiveInclude)
|
||||
selectIncludeFilter := func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
|
||||
matched, childMayMatch, err := filter.List(opts.Include, item)
|
||||
matched, childMayMatch, err := filter.ListWithChild(includePatterns, item)
|
||||
if err != nil {
|
||||
Warnf("error for include pattern: %v", err)
|
||||
}
|
||||
|
||||
matchedInsensitive, childMayMatchInsensitive, err := filter.List(opts.InsensitiveInclude, strings.ToLower(item))
|
||||
matchedInsensitive, childMayMatchInsensitive, err := filter.ListWithChild(insensitiveIncludePatterns, strings.ToLower(item))
|
||||
if err != nil {
|
||||
Warnf("error for iexclude pattern: %v", err)
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/restic/restic/internal/errors"
|
||||
"github.com/restic/restic/internal/selfupdate"
|
||||
@@ -56,11 +57,18 @@ func runSelfUpdate(opts SelfUpdateOptions, gopts GlobalOptions, args []string) e
|
||||
|
||||
fi, err := os.Lstat(opts.Output)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !fi.Mode().IsRegular() {
|
||||
return errors.Errorf("output file %v is not a normal file, use --output to specify a different file", opts.Output)
|
||||
dirname := filepath.Dir(opts.Output)
|
||||
di, err := os.Lstat(dirname)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !di.Mode().IsDir() {
|
||||
return errors.Fatalf("output parent path %v is not a directory, use --output to specify a different file path", dirname)
|
||||
}
|
||||
} else {
|
||||
if !fi.Mode().IsRegular() {
|
||||
return errors.Fatalf("output path %v is not a normal file, use --output to specify a different file path", opts.Output)
|
||||
}
|
||||
}
|
||||
|
||||
Printf("writing restic to %v\n", opts.Output)
|
||||
|
||||
@@ -49,7 +49,7 @@ func init() {
|
||||
f.StringArrayVarP(&snapshotOptions.Hosts, "host", "H", nil, "only consider snapshots for this `host` (can be specified multiple times)")
|
||||
f.Var(&snapshotOptions.Tags, "tag", "only consider snapshots which include this `taglist` (can be specified multiple times)")
|
||||
f.StringArrayVar(&snapshotOptions.Paths, "path", nil, "only consider snapshots for this `path` (can be specified multiple times)")
|
||||
f.BoolVarP(&snapshotOptions.Compact, "compact", "c", false, "use compact format")
|
||||
f.BoolVarP(&snapshotOptions.Compact, "compact", "c", false, "use compact output format")
|
||||
f.BoolVar(&snapshotOptions.Last, "last", false, "only show the last snapshot for each host and path")
|
||||
f.StringVarP(&snapshotOptions.GroupBy, "group-by", "g", "", "string for grouping snapshots by host,paths,tags")
|
||||
}
|
||||
@@ -61,7 +61,7 @@ func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) erro
|
||||
}
|
||||
|
||||
if !gopts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -298,7 +298,7 @@ type SnapshotGroup struct {
|
||||
// printSnapshotsJSON writes the JSON representation of list to stdout.
|
||||
func printSnapshotGroupJSON(stdout io.Writer, snGroups map[string]restic.Snapshots, grouped bool) error {
|
||||
if grouped {
|
||||
var snapshotGroups []SnapshotGroup
|
||||
snapshotGroups := []SnapshotGroup{}
|
||||
|
||||
for k, list := range snGroups {
|
||||
var key restic.SnapshotGroupKey
|
||||
@@ -330,7 +330,7 @@ func printSnapshotGroupJSON(stdout io.Writer, snGroups map[string]restic.Snapsho
|
||||
}
|
||||
|
||||
// Old behavior
|
||||
var snapshots []Snapshot
|
||||
snapshots := []Snapshot{}
|
||||
|
||||
for _, list := range snGroups {
|
||||
for _, sn := range list {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
)
|
||||
|
||||
// Regression test for #2979: no snapshots should print as [], not null.
|
||||
func TestEmptySnapshotGroupJSON(t *testing.T) {
|
||||
for _, grouped := range []bool{false, true} {
|
||||
var w strings.Builder
|
||||
printSnapshotGroupJSON(&w, nil, grouped)
|
||||
|
||||
rtest.Equals(t, "[]", strings.TrimSpace(w.String()))
|
||||
}
|
||||
}
|
||||
@@ -91,7 +91,7 @@ func runStats(gopts GlobalOptions, args []string) error {
|
||||
}
|
||||
|
||||
if !gopts.NoLock {
|
||||
lock, err := lockRepo(repo)
|
||||
lock, err := lockRepo(ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -119,7 +119,7 @@ func runTag(opts TagOptions, gopts GlobalOptions, args []string) error {
|
||||
|
||||
if !gopts.NoLock {
|
||||
Verbosef("create exclusive lock for repository\n")
|
||||
lock, err := lockRepoExclusive(repo)
|
||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
||||
defer unlockRepo(lock)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -48,7 +48,7 @@ func deleteFiles(gopts GlobalOptions, ignoreError bool, repo restic.Repository,
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !gopts.JSON && gopts.verbosity >= 2 {
|
||||
if !gopts.JSON && gopts.verbosity > 2 {
|
||||
Verbosef("removed %v\n", h)
|
||||
}
|
||||
bar.Report(restic.Stat{Blobs: 1})
|
||||
|
||||
@@ -74,8 +74,9 @@ type RejectFunc func(path string, fi os.FileInfo) bool
|
||||
// rejectByPattern returns a RejectByNameFunc which rejects files that match
|
||||
// one of the patterns.
|
||||
func rejectByPattern(patterns []string) RejectByNameFunc {
|
||||
parsedPatterns := filter.ParsePatterns(patterns)
|
||||
return func(item string) bool {
|
||||
matched, _, err := filter.List(patterns, item)
|
||||
matched, err := filter.List(parsedPatterns, item)
|
||||
if err != nil {
|
||||
Warnf("error for exclude pattern: %v", err)
|
||||
}
|
||||
@@ -234,10 +235,6 @@ func rejectByDevice(samples []string) (RejectFunc, error) {
|
||||
debug.Log("allowed devices: %v\n", allowed)
|
||||
|
||||
return func(item string, fi os.FileInfo) bool {
|
||||
if fi == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
item = filepath.Clean(item)
|
||||
|
||||
id, err := fs.DeviceID(fi)
|
||||
@@ -317,6 +314,10 @@ func rejectBySize(maxSizeStr string) (RejectFunc, error) {
|
||||
}
|
||||
|
||||
func parseSizeStr(sizeStr string) (int64, error) {
|
||||
if sizeStr == "" {
|
||||
return 0, errors.New("expected size, got empty string")
|
||||
}
|
||||
|
||||
numStr := sizeStr[:len(sizeStr)-1]
|
||||
var unit int64 = 1
|
||||
|
||||
@@ -336,7 +337,7 @@ func parseSizeStr(sizeStr string) (int64, error) {
|
||||
}
|
||||
value, err := strconv.ParseInt(numStr, 10, 64)
|
||||
if err != nil {
|
||||
return 0, nil
|
||||
return 0, err
|
||||
}
|
||||
return value * unit, nil
|
||||
}
|
||||
|
||||
@@ -219,6 +219,25 @@ func TestParseSizeStr(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseInvalidSizeStr(t *testing.T) {
|
||||
invalidSizes := []string{
|
||||
"",
|
||||
" ",
|
||||
"foobar",
|
||||
"zzz",
|
||||
}
|
||||
|
||||
for _, s := range invalidSizes {
|
||||
v, err := parseSizeStr(s)
|
||||
if err == nil {
|
||||
t.Errorf("wanted error for invalid value %q, got nil", s)
|
||||
}
|
||||
if v != 0 {
|
||||
t.Errorf("wanted zero for invalid value %q, got: %v", s, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestIsExcludedByFileSize is for testing the instance of
|
||||
// --exclude-larger-than parameters
|
||||
func TestIsExcludedByFileSize(t *testing.T) {
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ func FindFilteredSnapshots(ctx context.Context, repo *repository.Repository, hos
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
id, err = restic.FindSnapshot(repo, s)
|
||||
id, err = restic.FindSnapshot(ctx, repo, s)
|
||||
if err != nil {
|
||||
Warnf("Ignoring %q, it is not a snapshot id\n", s)
|
||||
continue
|
||||
|
||||
+46
-18
@@ -39,7 +39,7 @@ import (
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
var version = "0.10.0"
|
||||
var version = "0.11.0"
|
||||
|
||||
// TimeFormat is the format used for all timestamps printed by restic.
|
||||
const TimeFormat = "2006-01-02 15:04:05"
|
||||
@@ -49,6 +49,7 @@ type backendWrapper func(r restic.Backend) (restic.Backend, error)
|
||||
// GlobalOptions hold all global options for restic.
|
||||
type GlobalOptions struct {
|
||||
Repo string
|
||||
RepositoryFile string
|
||||
PasswordFile string
|
||||
PasswordCommand string
|
||||
KeyHint string
|
||||
@@ -101,12 +102,13 @@ func init() {
|
||||
|
||||
f := cmdRoot.PersistentFlags()
|
||||
f.StringVarP(&globalOptions.Repo, "repo", "r", os.Getenv("RESTIC_REPOSITORY"), "`repository` to backup to or restore from (default: $RESTIC_REPOSITORY)")
|
||||
f.StringVarP(&globalOptions.RepositoryFile, "repository-file", "", os.Getenv("RESTIC_REPOSITORY_FILE"), "`file` to read the repository location from (default: $RESTIC_REPOSITORY_FILE)")
|
||||
f.StringVarP(&globalOptions.PasswordFile, "password-file", "p", os.Getenv("RESTIC_PASSWORD_FILE"), "`file` to read the repository password from (default: $RESTIC_PASSWORD_FILE)")
|
||||
f.StringVarP(&globalOptions.KeyHint, "key-hint", "", os.Getenv("RESTIC_KEY_HINT"), "`key` ID of key to try decrypting first (default: $RESTIC_KEY_HINT)")
|
||||
f.StringVarP(&globalOptions.PasswordCommand, "password-command", "", os.Getenv("RESTIC_PASSWORD_COMMAND"), "shell `command` to obtain the repository password from (default: $RESTIC_PASSWORD_COMMAND)")
|
||||
f.BoolVarP(&globalOptions.Quiet, "quiet", "q", false, "do not output comprehensive progress report")
|
||||
f.CountVarP(&globalOptions.Verbose, "verbose", "v", "be verbose (specify --verbose multiple times or level --verbose=`n`)")
|
||||
f.BoolVar(&globalOptions.NoLock, "no-lock", false, "do not lock the repo, this allows some operations on read-only repos")
|
||||
f.CountVarP(&globalOptions.Verbose, "verbose", "v", "be verbose (specify multiple times or a level using --verbose=`n`, max level/times is 3)")
|
||||
f.BoolVar(&globalOptions.NoLock, "no-lock", false, "do not lock the repository, this allows some operations on read-only repositories")
|
||||
f.BoolVarP(&globalOptions.JSON, "json", "", false, "set output mode to JSON for commands that support it")
|
||||
f.StringVar(&globalOptions.CacheDir, "cache-dir", "", "set the cache `directory`. (default: use system default cache directory)")
|
||||
f.BoolVar(&globalOptions.NoCache, "no-cache", false, "do not use a local cache")
|
||||
@@ -347,7 +349,7 @@ func ReadPassword(opts GlobalOptions, prompt string) (string, error) {
|
||||
password, err = readPasswordTerminal(os.Stdin, os.Stderr, prompt)
|
||||
} else {
|
||||
password, err = readPassword(os.Stdin)
|
||||
Verbosef("read password from stdin\n")
|
||||
Verbosef("reading repository password from stdin\n")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -382,15 +384,41 @@ func ReadPasswordTwice(gopts GlobalOptions, prompt1, prompt2 string) (string, er
|
||||
return pw1, nil
|
||||
}
|
||||
|
||||
func ReadRepo(opts GlobalOptions) (string, error) {
|
||||
if opts.Repo == "" && opts.RepositoryFile == "" {
|
||||
return "", errors.Fatal("Please specify repository location (-r or --repository-file)")
|
||||
}
|
||||
|
||||
repo := opts.Repo
|
||||
if opts.RepositoryFile != "" {
|
||||
if repo != "" {
|
||||
return "", errors.Fatal("Options -r and --repository-file are mutually exclusive, please specify only one")
|
||||
}
|
||||
|
||||
s, err := textfile.Read(opts.RepositoryFile)
|
||||
if os.IsNotExist(errors.Cause(err)) {
|
||||
return "", errors.Fatalf("%s does not exist", opts.RepositoryFile)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
repo = strings.TrimSpace(string(s))
|
||||
}
|
||||
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
const maxKeys = 20
|
||||
|
||||
// OpenRepository reads the password and opens the repository.
|
||||
func OpenRepository(opts GlobalOptions) (*repository.Repository, error) {
|
||||
if opts.Repo == "" {
|
||||
return nil, errors.Fatal("Please specify repository location (-r)")
|
||||
repo, err := ReadRepo(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
be, err := open(opts.Repo, opts, opts.extended)
|
||||
be, err := open(repo, opts, opts.extended)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -631,7 +659,7 @@ func parseConfig(loc location.Location, opts options.Options) (interface{}, erro
|
||||
|
||||
// Open the backend specified by a location config.
|
||||
func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend, error) {
|
||||
debug.Log("parsing location %v", s)
|
||||
debug.Log("parsing location %v", location.StripPassword(s))
|
||||
loc, err := location.Parse(s)
|
||||
if err != nil {
|
||||
return nil, errors.Fatalf("parsing repository location failed: %v", err)
|
||||
@@ -659,15 +687,15 @@ func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend,
|
||||
|
||||
switch loc.Scheme {
|
||||
case "local":
|
||||
be, err = local.Open(cfg.(local.Config))
|
||||
be, err = local.Open(globalOptions.ctx, cfg.(local.Config))
|
||||
// wrap the backend in a LimitBackend so that the throughput is limited
|
||||
be = limiter.LimitBackend(be, lim)
|
||||
case "sftp":
|
||||
be, err = sftp.Open(cfg.(sftp.Config))
|
||||
be, err = sftp.Open(globalOptions.ctx, cfg.(sftp.Config))
|
||||
// wrap the backend in a LimitBackend so that the throughput is limited
|
||||
be = limiter.LimitBackend(be, lim)
|
||||
case "s3":
|
||||
be, err = s3.Open(cfg.(s3.Config), rt)
|
||||
be, err = s3.Open(globalOptions.ctx, cfg.(s3.Config), rt)
|
||||
case "gs":
|
||||
be, err = gs.Open(cfg.(gs.Config), rt)
|
||||
case "azure":
|
||||
@@ -686,13 +714,13 @@ func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Fatalf("unable to open repo at %v: %v", s, err)
|
||||
return nil, errors.Fatalf("unable to open repo at %v: %v", location.StripPassword(s), err)
|
||||
}
|
||||
|
||||
// check if config is there
|
||||
fi, err := be.Stat(globalOptions.ctx, restic.Handle{Type: restic.ConfigFile})
|
||||
if err != nil {
|
||||
return nil, errors.Fatalf("unable to open config file: %v\nIs there a repository at the following location?\n%v", err, s)
|
||||
return nil, errors.Fatalf("unable to open config file: %v\nIs there a repository at the following location?\n%v", err, location.StripPassword(s))
|
||||
}
|
||||
|
||||
if fi.Size == 0 {
|
||||
@@ -726,11 +754,11 @@ func create(s string, opts options.Options) (restic.Backend, error) {
|
||||
|
||||
switch loc.Scheme {
|
||||
case "local":
|
||||
return local.Create(cfg.(local.Config))
|
||||
return local.Create(globalOptions.ctx, cfg.(local.Config))
|
||||
case "sftp":
|
||||
return sftp.Create(cfg.(sftp.Config))
|
||||
return sftp.Create(globalOptions.ctx, cfg.(sftp.Config))
|
||||
case "s3":
|
||||
return s3.Create(cfg.(s3.Config), rt)
|
||||
return s3.Create(globalOptions.ctx, cfg.(s3.Config), rt)
|
||||
case "gs":
|
||||
return gs.Create(cfg.(gs.Config), rt)
|
||||
case "azure":
|
||||
@@ -740,9 +768,9 @@ func create(s string, opts options.Options) (restic.Backend, error) {
|
||||
case "b2":
|
||||
return b2.Create(globalOptions.ctx, cfg.(b2.Config), rt)
|
||||
case "rest":
|
||||
return rest.Create(cfg.(rest.Config), rt)
|
||||
return rest.Create(globalOptions.ctx, cfg.(rest.Config), rt)
|
||||
case "rclone":
|
||||
return rclone.Open(cfg.(rclone.Config), nil)
|
||||
return rclone.Create(globalOptions.ctx, cfg.(rclone.Config))
|
||||
}
|
||||
|
||||
debug.Log("invalid repository scheme: %v", s)
|
||||
|
||||
@@ -2,8 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/test"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
)
|
||||
|
||||
@@ -26,3 +29,33 @@ func Test_PrintFunctionsRespectsGlobalStdout(t *testing.T) {
|
||||
buf.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadRepo(t *testing.T) {
|
||||
tempDir, cleanup := test.TempDir(t)
|
||||
defer cleanup()
|
||||
|
||||
// test --repo option
|
||||
var opts GlobalOptions
|
||||
opts.Repo = tempDir
|
||||
repo, err := ReadRepo(opts)
|
||||
rtest.OK(t, err)
|
||||
rtest.Equals(t, tempDir, repo)
|
||||
|
||||
// test --repository-file option
|
||||
foo := filepath.Join(tempDir, "foo")
|
||||
err = ioutil.WriteFile(foo, []byte(tempDir+"\n"), 0666)
|
||||
rtest.OK(t, err)
|
||||
|
||||
var opts2 GlobalOptions
|
||||
opts2.RepositoryFile = foo
|
||||
repo, err = ReadRepo(opts2)
|
||||
rtest.OK(t, err)
|
||||
rtest.Equals(t, tempDir, repo)
|
||||
|
||||
var opts3 GlobalOptions
|
||||
opts3.RepositoryFile = foo + "-invalid"
|
||||
repo, err = ReadRepo(opts3)
|
||||
if err == nil {
|
||||
t.Fatal("must not read repository path from invalid file path")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -122,7 +121,7 @@ func checkSnapshots(t testing.TB, global GlobalOptions, repo *repository.Reposit
|
||||
}
|
||||
|
||||
for _, id := range snapshotIDs {
|
||||
snapshot, err := restic.LoadSnapshot(context.TODO(), repo, id)
|
||||
snapshot, err := restic.LoadSnapshot(global.ctx, repo, id)
|
||||
rtest.OK(t, err)
|
||||
|
||||
ts := snapshot.Time.Format(time.RFC3339)
|
||||
|
||||
@@ -44,7 +44,6 @@ func createFileSetPerHardlink(dir string) map[uint64][]string {
|
||||
}
|
||||
for i, f := range files {
|
||||
linkTests[uint64(i)] = append(linkTests[uint64(i)], f.Name())
|
||||
i++
|
||||
}
|
||||
return linkTests
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func testRunBackupAssumeFailure(t testing.TB, dir string, target []string, opts
|
||||
gopts.stdout = ioutil.Discard
|
||||
t.Logf("backing up %v in %v", target, dir)
|
||||
if dir != "" {
|
||||
cleanup := fs.TestChdir(t, dir)
|
||||
cleanup := rtest.Chdir(t, dir)
|
||||
defer cleanup()
|
||||
}
|
||||
|
||||
@@ -282,11 +282,21 @@ func testSetupBackupData(t testing.TB, env *testEnvironment) string {
|
||||
}
|
||||
|
||||
func TestBackup(t *testing.T) {
|
||||
testBackup(t, false)
|
||||
}
|
||||
|
||||
func TestBackupWithFilesystemSnapshots(t *testing.T) {
|
||||
if runtime.GOOS == "windows" && fs.HasSufficientPrivilegesForVSS() == nil {
|
||||
testBackup(t, true)
|
||||
}
|
||||
}
|
||||
|
||||
func testBackup(t *testing.T, useFsSnapshot bool) {
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
testSetupBackupData(t, env)
|
||||
opts := BackupOptions{}
|
||||
opts := BackupOptions{UseFsSnapshot: useFsSnapshot}
|
||||
|
||||
// first backup
|
||||
testRunBackup(t, filepath.Dir(env.testdata), []string{"testdata"}, opts, env.gopts)
|
||||
@@ -358,7 +368,7 @@ func TestBackupNonExistingFile(t *testing.T) {
|
||||
testRunBackup(t, "", dirs, opts, env.gopts)
|
||||
}
|
||||
|
||||
func removeDataPacksExcept(gopts GlobalOptions, t *testing.T, keep restic.IDSet) {
|
||||
func removePacksExcept(gopts GlobalOptions, t *testing.T, keep restic.IDSet, removeTreePacks bool) {
|
||||
r, err := OpenRepository(gopts)
|
||||
rtest.OK(t, err)
|
||||
|
||||
@@ -373,7 +383,7 @@ func removeDataPacksExcept(gopts GlobalOptions, t *testing.T, keep restic.IDSet)
|
||||
|
||||
// remove all packs containing data blobs
|
||||
rtest.OK(t, r.List(gopts.ctx, restic.PackFile, func(id restic.ID, size int64) error {
|
||||
if treePacks.Has(id) || keep.Has(id) {
|
||||
if treePacks.Has(id) != removeTreePacks || keep.Has(id) {
|
||||
return nil
|
||||
}
|
||||
return r.Backend().Remove(gopts.ctx, restic.Handle{Type: restic.PackFile, Name: id.String()})
|
||||
@@ -396,7 +406,7 @@ func TestBackupSelfHealing(t *testing.T) {
|
||||
testRunCheck(t, env.gopts)
|
||||
|
||||
// remove all data packs
|
||||
removeDataPacksExcept(env.gopts, t, restic.NewIDSet())
|
||||
removePacksExcept(env.gopts, t, restic.NewIDSet(), false)
|
||||
|
||||
testRunRebuildIndex(t, env.gopts)
|
||||
// now the repo is also missing the data blob in the index; check should report this
|
||||
@@ -410,6 +420,56 @@ func TestBackupSelfHealing(t *testing.T) {
|
||||
testRunCheck(t, env.gopts)
|
||||
}
|
||||
|
||||
func TestBackupTreeLoadError(t *testing.T) {
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
testRunInit(t, env.gopts)
|
||||
p := filepath.Join(env.testdata, "test/test")
|
||||
rtest.OK(t, os.MkdirAll(filepath.Dir(p), 0755))
|
||||
rtest.OK(t, appendRandomData(p, 5))
|
||||
|
||||
opts := BackupOptions{}
|
||||
// Backup a subdirectory first, such that we can remove the tree pack for the subdirectory
|
||||
testRunBackup(t, env.testdata, []string{"test"}, opts, env.gopts)
|
||||
|
||||
r, err := OpenRepository(env.gopts)
|
||||
rtest.OK(t, err)
|
||||
rtest.OK(t, r.LoadIndex(env.gopts.ctx))
|
||||
// collect tree packs of subdirectory
|
||||
subTreePacks := restic.NewIDSet()
|
||||
for _, idx := range r.Index().(*repository.MasterIndex).All() {
|
||||
for _, id := range idx.TreePacks() {
|
||||
subTreePacks.Insert(id)
|
||||
}
|
||||
}
|
||||
|
||||
testRunBackup(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
||||
testRunCheck(t, env.gopts)
|
||||
|
||||
// delete the subdirectory pack first
|
||||
for id := range subTreePacks {
|
||||
rtest.OK(t, r.Backend().Remove(env.gopts.ctx, restic.Handle{Type: restic.PackFile, Name: id.String()}))
|
||||
}
|
||||
testRunRebuildIndex(t, env.gopts)
|
||||
// now the repo is missing the tree blob in the index; check should report this
|
||||
rtest.Assert(t, runCheck(CheckOptions{}, env.gopts, nil) != nil, "check should have reported an error")
|
||||
// second backup should report an error but "heal" this situation
|
||||
err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
||||
rtest.Assert(t, err != nil, "backup should have reported an error for the subdirectory")
|
||||
testRunCheck(t, env.gopts)
|
||||
|
||||
// remove all tree packs
|
||||
removePacksExcept(env.gopts, t, restic.NewIDSet(), true)
|
||||
testRunRebuildIndex(t, env.gopts)
|
||||
// now the repo is also missing the data blob in the index; check should report this
|
||||
rtest.Assert(t, runCheck(CheckOptions{}, env.gopts, nil) != nil, "check should have reported an error")
|
||||
// second backup should report an error but "heal" this situation
|
||||
err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
||||
rtest.Assert(t, err != nil, "backup should have reported an error")
|
||||
testRunCheck(t, env.gopts)
|
||||
}
|
||||
|
||||
func includes(haystack []string, needle string) bool {
|
||||
for _, s := range haystack {
|
||||
if s == needle {
|
||||
@@ -514,7 +574,7 @@ func TestBackupErrors(t *testing.T) {
|
||||
gopts := env.gopts
|
||||
gopts.stderr = ioutil.Discard
|
||||
err := testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{"testdata"}, opts, gopts)
|
||||
rtest.Assert(t, err != nil, "Assumed failure, but no error occured.")
|
||||
rtest.Assert(t, err != nil, "Assumed failure, but no error occurred.")
|
||||
rtest.Assert(t, err == ErrInvalidSourceData, "Wrong error returned")
|
||||
snapshotIDs := testRunList(t, "snapshots", env.gopts)
|
||||
rtest.Assert(t, len(snapshotIDs) == 1,
|
||||
@@ -1035,7 +1095,7 @@ func TestRestoreLatest(t *testing.T) {
|
||||
|
||||
// chdir manually here so we can get the current directory. This is not the
|
||||
// same as the temp dir returned by ioutil.TempDir() on darwin.
|
||||
back := fs.TestChdir(t, filepath.Dir(env.testdata))
|
||||
back := rtest.Chdir(t, filepath.Dir(env.testdata))
|
||||
defer back()
|
||||
|
||||
curdir, err := os.Getwd()
|
||||
@@ -1386,7 +1446,7 @@ func TestPruneWithDamagedRepository(t *testing.T) {
|
||||
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "3")}, opts, env.gopts)
|
||||
snapshotIDs := testRunList(t, "snapshots", env.gopts)
|
||||
|
||||
removeDataPacksExcept(env.gopts, t, oldPacks)
|
||||
removePacksExcept(env.gopts, t, oldPacks, false)
|
||||
|
||||
rtest.Assert(t, len(snapshotIDs) == 1,
|
||||
"expected one snapshot, got %v", snapshotIDs)
|
||||
@@ -1402,6 +1462,81 @@ func TestPruneWithDamagedRepository(t *testing.T) {
|
||||
t.Log(err)
|
||||
}
|
||||
|
||||
// Test repos for edge cases
|
||||
func TestEdgeCaseRepos(t *testing.T) {
|
||||
opts := CheckOptions{}
|
||||
|
||||
// repo where index is completely missing
|
||||
// => check and prune should fail
|
||||
t.Run("no-index", func(t *testing.T) {
|
||||
testEdgeCaseRepo(t, "repo-index-missing.tar.gz", opts, false, false)
|
||||
})
|
||||
|
||||
// repo where an existing and used blob is missing from the index
|
||||
// => check should fail, prune should heal this
|
||||
t.Run("index-missing-blob", func(t *testing.T) {
|
||||
testEdgeCaseRepo(t, "repo-index-missing-blob.tar.gz", opts, false, true)
|
||||
})
|
||||
|
||||
// repo where a blob is missing
|
||||
// => check and prune should fail
|
||||
t.Run("no-data", func(t *testing.T) {
|
||||
testEdgeCaseRepo(t, "repo-data-missing.tar.gz", opts, false, false)
|
||||
})
|
||||
|
||||
// repo where data exists that is not referenced
|
||||
// => check and prune should fully work
|
||||
t.Run("unreferenced-data", func(t *testing.T) {
|
||||
testEdgeCaseRepo(t, "repo-unreferenced-data.tar.gz", opts, true, true)
|
||||
})
|
||||
|
||||
// repo where an obsolete index still exists
|
||||
// => check and prune should fully work
|
||||
t.Run("obsolete-index", func(t *testing.T) {
|
||||
testEdgeCaseRepo(t, "repo-obsolete-index.tar.gz", opts, true, true)
|
||||
})
|
||||
|
||||
// repo which contains mixed (data/tree) packs
|
||||
// => check and prune should fully work
|
||||
t.Run("mixed-packs", func(t *testing.T) {
|
||||
testEdgeCaseRepo(t, "repo-mixed.tar.gz", opts, true, true)
|
||||
})
|
||||
|
||||
// repo which contains duplicate blobs
|
||||
// => checking for unused data should report an error and prune resolves the
|
||||
// situation
|
||||
opts = CheckOptions{
|
||||
ReadData: true,
|
||||
CheckUnused: true,
|
||||
}
|
||||
t.Run("duplicates", func(t *testing.T) {
|
||||
testEdgeCaseRepo(t, "repo-duplicates.tar.gz", opts, false, true)
|
||||
})
|
||||
}
|
||||
|
||||
func testEdgeCaseRepo(t *testing.T, tarfile string, options CheckOptions, checkOK, pruneOK bool) {
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
defer cleanup()
|
||||
|
||||
datafile := filepath.Join("testdata", tarfile)
|
||||
rtest.SetupTarTestFixture(t, env.base, datafile)
|
||||
|
||||
if checkOK {
|
||||
testRunCheck(t, env.gopts)
|
||||
} else {
|
||||
rtest.Assert(t, runCheck(options, env.gopts, nil) != nil,
|
||||
"check should have reported an error")
|
||||
}
|
||||
|
||||
if pruneOK {
|
||||
testRunPrune(t, env.gopts)
|
||||
testRunCheck(t, env.gopts)
|
||||
} else {
|
||||
rtest.Assert(t, runPrune(env.gopts) != nil,
|
||||
"prune should have reported an error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHardLink(t *testing.T) {
|
||||
// this test assumes a test set with a single directory containing hard linked files
|
||||
env, cleanup := withTestEnvironment(t)
|
||||
@@ -1591,7 +1726,7 @@ func TestDiff(t *testing.T) {
|
||||
rtest.OK(t, os.Mkdir(modfile+"4", 0755))
|
||||
|
||||
testRunBackup(t, "", []string{datadir}, opts, env.gopts)
|
||||
snapshots, secondSnapshotID := lastSnapshot(snapshots, loadSnapshotMap(t, env.gopts))
|
||||
_, secondSnapshotID := lastSnapshot(snapshots, loadSnapshotMap(t, env.gopts))
|
||||
|
||||
_, err := testRunDiffOutput(env.gopts, "", secondSnapshotID)
|
||||
rtest.Assert(t, err != nil, "expected error on invalid snapshot id")
|
||||
|
||||
+10
-6
@@ -18,21 +18,21 @@ var globalLocks struct {
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func lockRepo(repo *repository.Repository) (*restic.Lock, error) {
|
||||
return lockRepository(repo, false)
|
||||
func lockRepo(ctx context.Context, repo *repository.Repository) (*restic.Lock, error) {
|
||||
return lockRepository(ctx, repo, false)
|
||||
}
|
||||
|
||||
func lockRepoExclusive(repo *repository.Repository) (*restic.Lock, error) {
|
||||
return lockRepository(repo, true)
|
||||
func lockRepoExclusive(ctx context.Context, repo *repository.Repository) (*restic.Lock, error) {
|
||||
return lockRepository(ctx, repo, true)
|
||||
}
|
||||
|
||||
func lockRepository(repo *repository.Repository, exclusive bool) (*restic.Lock, error) {
|
||||
func lockRepository(ctx context.Context, repo *repository.Repository, exclusive bool) (*restic.Lock, error) {
|
||||
lockFn := restic.NewLock
|
||||
if exclusive {
|
||||
lockFn = restic.NewExclusiveLock
|
||||
}
|
||||
|
||||
lock, err := lockFn(context.TODO(), repo)
|
||||
lock, err := lockFn(ctx, repo)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessage(err, "unable to create lock in backend")
|
||||
}
|
||||
@@ -86,6 +86,10 @@ func refreshLocks(wg *sync.WaitGroup, done <-chan struct{}) {
|
||||
}
|
||||
|
||||
func unlockRepo(lock *restic.Lock) error {
|
||||
if lock == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
globalLocks.Lock()
|
||||
defer globalLocks.Unlock()
|
||||
|
||||
|
||||
+13
-1
@@ -51,7 +51,7 @@ directories in an encrypted repository stored on different backends.
|
||||
return err
|
||||
}
|
||||
globalOptions.extended = opts
|
||||
if c.Name() == "version" {
|
||||
if !needsPassword(c.Name()) {
|
||||
return nil
|
||||
}
|
||||
pwd, err := resolvePassword(globalOptions, "RESTIC_PASSWORD")
|
||||
@@ -71,6 +71,18 @@ directories in an encrypted repository stored on different backends.
|
||||
},
|
||||
}
|
||||
|
||||
// Distinguish commands that need the password from those that work without,
|
||||
// so we don't run $RESTIC_PASSWORD_COMMAND for no reason (it might prompt the
|
||||
// user for authentication).
|
||||
func needsPassword(cmd string) bool {
|
||||
switch cmd {
|
||||
case "cache", "generate", "help", "options", "self-update", "version":
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
var logBuffer = bytes.NewBuffer(nil)
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -16,7 +16,7 @@ type secondaryRepoOptions struct {
|
||||
}
|
||||
|
||||
func initSecondaryRepoOptions(f *pflag.FlagSet, opts *secondaryRepoOptions, repoPrefix string, repoUsage string) {
|
||||
f.StringVarP(&opts.Repo, "repo2", "", os.Getenv("RESTIC_REPOSITORY2"), repoPrefix+" repository "+repoUsage+" (default: $RESTIC_REPOSITORY2)")
|
||||
f.StringVarP(&opts.Repo, "repo2", "", os.Getenv("RESTIC_REPOSITORY2"), repoPrefix+" `repository` "+repoUsage+" (default: $RESTIC_REPOSITORY2)")
|
||||
f.StringVarP(&opts.PasswordFile, "password-file2", "", os.Getenv("RESTIC_PASSWORD_FILE2"), "`file` to read the "+repoPrefix+" repository password from (default: $RESTIC_PASSWORD_FILE2)")
|
||||
f.StringVarP(&opts.KeyHint, "key-hint2", "", os.Getenv("RESTIC_KEY_HINT2"), "key ID of key to try decrypting the "+repoPrefix+" repository first (default: $RESTIC_KEY_HINT2)")
|
||||
f.StringVarP(&opts.PasswordCommand, "password-command2", "", os.Getenv("RESTIC_PASSWORD_COMMAND2"), "shell `command` to obtain the "+repoPrefix+" repository password from (default: $RESTIC_PASSWORD_COMMAND2)")
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
@@ -27,6 +27,16 @@ Please see the :ref:`official_binaries` section below for various downloads.
|
||||
Official binaries can be updated in place by using the ``restic self-update``
|
||||
command.
|
||||
|
||||
Alpine Linux
|
||||
============
|
||||
|
||||
On `Alpine Linux <https://www.alpinelinux.org>`__ you can install the ``restic``
|
||||
package from the official community repos, e.g. using ``apk``:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ apk add restic
|
||||
|
||||
Arch Linux
|
||||
==========
|
||||
|
||||
|
||||
@@ -22,8 +22,10 @@ other options. You can skip to the next chapter once you've read the relevant
|
||||
section here.
|
||||
|
||||
For automated backups, restic accepts the repository location in the
|
||||
environment variable ``RESTIC_REPOSITORY``. For the password, several options
|
||||
exist:
|
||||
environment variable ``RESTIC_REPOSITORY``. Restic can also read the repository
|
||||
location from a file specified via the ``--repository-file`` option or the
|
||||
environment variable ``RESTIC_REPOSITORY_FILE``. For the password, several
|
||||
options exist:
|
||||
|
||||
* Setting the environment variable ``RESTIC_PASSWORD``
|
||||
|
||||
@@ -458,6 +460,18 @@ which means if you're running in Google Container Engine or are otherwise
|
||||
located on an instance with default service accounts then these should work out of
|
||||
the box.
|
||||
|
||||
Alternatively, you can specify an existing access token directly:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ export GOOGLE_ACCESS_TOKEN=ya29.a0AfH6SMC78...
|
||||
|
||||
If ``GOOGLE_ACCESS_TOKEN`` is set all other authentication mechanisms are
|
||||
disabled. The access token must have at least the
|
||||
``https://www.googleapis.com/auth/devstorage.read_write`` scope. Keep in mind
|
||||
that access tokens are short-lived (usually one hour), so they are not suitable
|
||||
if creating a backup takes longer than that, for instance.
|
||||
|
||||
Once authenticated, you can use the ``gs:`` backend type to create a new
|
||||
repository in the bucket ``foo`` at the root path:
|
||||
|
||||
|
||||
+26
-6
@@ -50,7 +50,24 @@ still get a nice live status display. Be aware that the live status shows the
|
||||
processed files and not the transferred data. Transferred volume might be lower
|
||||
(due to de-duplication) or higher.
|
||||
|
||||
If you run the command again, restic will create another snapshot of
|
||||
On Windows, the ``--use-fs-snapshot`` option will use Windows' Volume Shadow Copy
|
||||
Service (VSS) when creating backups. Restic will transparently create a VSS
|
||||
snapshot for each volume that contains files to backup. Files are read from the
|
||||
VSS snapshot instead of the regular filesystem. This allows to backup files that are
|
||||
exclusively locked by another process during the backup.
|
||||
|
||||
By default VSS ignores Outlook OST files. This is not a restriction of restic
|
||||
but the default Windows VSS configuration. The files not to snapshot are
|
||||
configured in the Windows registry under the following key:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\BackupRestore\FilesNotToSnapshot
|
||||
|
||||
For more details refer the official Windows documentation e.g. the article
|
||||
``Registry Keys and Values for Backup and Restore``.
|
||||
|
||||
If you run the backup command again, restic will create another snapshot of
|
||||
your data, but this time it's even faster and no new data was added to the
|
||||
repository (since all data is already there). This is de-duplication at work!
|
||||
|
||||
@@ -407,6 +424,7 @@ environment variables. The following lists these environment variables:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
RESTIC_REPOSITORY_FILE Name of file containing the repository location (replaces --repository-file)
|
||||
RESTIC_REPOSITORY Location of repository (replaces -r)
|
||||
RESTIC_PASSWORD_FILE Location of password file (replaces --password-file)
|
||||
RESTIC_PASSWORD The actual password for the repository
|
||||
@@ -415,6 +433,8 @@ environment variables. The following lists these environment variables:
|
||||
RESTIC_CACHE_DIR Location of the cache directory
|
||||
RESTIC_PROGRESS_FPS Frames per second by which the progress bar is updated
|
||||
|
||||
TMPDIR Location for temporary files
|
||||
|
||||
AWS_ACCESS_KEY_ID Amazon S3 access key ID
|
||||
AWS_SECRET_ACCESS_KEY Amazon S3 secret access key
|
||||
AWS_DEFAULT_REGION Amazon S3 default region
|
||||
@@ -452,12 +472,12 @@ environment variables. The following lists these environment variables:
|
||||
|
||||
RCLONE_BWLIMIT rclone bandwidth limit
|
||||
|
||||
In addition to restic-specific environment variables, the following system-wide environment variables
|
||||
are taken into account for various operations:
|
||||
See :ref:`caching` for the rules concerning cache locations when
|
||||
``RESTIC_CACHE_DIR`` is not set.
|
||||
|
||||
* ``$XDG_CACHE_HOME/restic``, ``$HOME/.cache/restic``: :ref:`caching`.
|
||||
* ``$TMPDIR``: :ref:`temporary_files`.
|
||||
* ``$PATH/fusermount``: Binary for ``restic mount``.
|
||||
The external programs that restic may execute include ``rclone`` (for rclone
|
||||
backends) and ``ssh`` (for the SFTP backend). These may respond to further
|
||||
environment variables and configuration files; see their respective manuals.
|
||||
|
||||
|
||||
Exit status codes
|
||||
|
||||
+5
-4
@@ -71,10 +71,11 @@ command to serve the repository with FUSE:
|
||||
Now serving /srv/restic-repo at /mnt/restic
|
||||
When finished, quit with Ctrl-c or umount the mountpoint.
|
||||
|
||||
Mounting repositories via FUSE is not possible on OpenBSD, Solaris/illumos
|
||||
and Windows. For Linux, the ``fuse`` kernel module needs to be loaded. For
|
||||
FreeBSD, you may need to install FUSE and load the kernel module (``kldload
|
||||
fuse``).
|
||||
Mounting repositories via FUSE is only possible on Linux, macOS and FreeBSD.
|
||||
On Linux, the ``fuse`` kernel module needs to be loaded and the ``fusermount``
|
||||
command needs to be in the ``PATH``. On macOS, you need `FUSE for macOS
|
||||
<https://osxfuse.github.io/>`__. On FreeBSD, you may need to install FUSE
|
||||
and load the kernel module (``kldload fuse``).
|
||||
|
||||
Restic supports storage and preservation of hard links. However, since
|
||||
hard links exist in the scope of a filesystem by definition, restoring
|
||||
|
||||
+58
-77
@@ -36,71 +36,9 @@ __restic_contains_word()
|
||||
return 1
|
||||
}
|
||||
|
||||
__restic_handle_go_custom_completion()
|
||||
{
|
||||
__restic_debug "${FUNCNAME[0]}: cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}"
|
||||
|
||||
local out requestComp lastParam lastChar comp directive args
|
||||
|
||||
# Prepare the command to request completions for the program.
|
||||
# Calling ${words[0]} instead of directly restic allows to handle aliases
|
||||
args=("${words[@]:1}")
|
||||
requestComp="${words[0]} __completeNoDesc ${args[*]}"
|
||||
|
||||
lastParam=${words[$((${#words[@]}-1))]}
|
||||
lastChar=${lastParam:$((${#lastParam}-1)):1}
|
||||
__restic_debug "${FUNCNAME[0]}: lastParam ${lastParam}, lastChar ${lastChar}"
|
||||
|
||||
if [ -z "${cur}" ] && [ "${lastChar}" != "=" ]; then
|
||||
# If the last parameter is complete (there is a space following it)
|
||||
# We add an extra empty parameter so we can indicate this to the go method.
|
||||
__restic_debug "${FUNCNAME[0]}: Adding extra empty parameter"
|
||||
requestComp="${requestComp} \"\""
|
||||
fi
|
||||
|
||||
__restic_debug "${FUNCNAME[0]}: calling ${requestComp}"
|
||||
# Use eval to handle any environment variables and such
|
||||
out=$(eval "${requestComp}" 2>/dev/null)
|
||||
|
||||
# Extract the directive integer at the very end of the output following a colon (:)
|
||||
directive=${out##*:}
|
||||
# Remove the directive
|
||||
out=${out%:*}
|
||||
if [ "${directive}" = "${out}" ]; then
|
||||
# There is not directive specified
|
||||
directive=0
|
||||
fi
|
||||
__restic_debug "${FUNCNAME[0]}: the completion directive is: ${directive}"
|
||||
__restic_debug "${FUNCNAME[0]}: the completions are: ${out[*]}"
|
||||
|
||||
if [ $((directive & 1)) -ne 0 ]; then
|
||||
# Error code. No completion.
|
||||
__restic_debug "${FUNCNAME[0]}: received error from custom completion go code"
|
||||
return
|
||||
else
|
||||
if [ $((directive & 2)) -ne 0 ]; then
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
__restic_debug "${FUNCNAME[0]}: activating no space"
|
||||
compopt -o nospace
|
||||
fi
|
||||
fi
|
||||
if [ $((directive & 4)) -ne 0 ]; then
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
__restic_debug "${FUNCNAME[0]}: activating no file completion"
|
||||
compopt +o default
|
||||
fi
|
||||
fi
|
||||
|
||||
while IFS='' read -r comp; do
|
||||
COMPREPLY+=("$comp")
|
||||
done < <(compgen -W "${out[*]}" -- "$cur")
|
||||
fi
|
||||
}
|
||||
|
||||
__restic_handle_reply()
|
||||
{
|
||||
__restic_debug "${FUNCNAME[0]}"
|
||||
local comp
|
||||
case $cur in
|
||||
-*)
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
@@ -112,9 +50,7 @@ __restic_handle_reply()
|
||||
else
|
||||
allflags=("${flags[*]} ${two_word_flags[*]}")
|
||||
fi
|
||||
while IFS='' read -r comp; do
|
||||
COMPREPLY+=("$comp")
|
||||
done < <(compgen -W "${allflags[*]}" -- "$cur")
|
||||
COMPREPLY=( $(compgen -W "${allflags[*]}" -- "$cur") )
|
||||
if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
[[ "${COMPREPLY[0]}" == *= ]] || compopt +o nospace
|
||||
fi
|
||||
@@ -160,22 +96,14 @@ __restic_handle_reply()
|
||||
completions=("${commands[@]}")
|
||||
if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then
|
||||
completions=("${must_have_one_noun[@]}")
|
||||
elif [[ -n "${has_completion_function}" ]]; then
|
||||
# if a go completion function is provided, defer to that function
|
||||
completions=()
|
||||
__restic_handle_go_custom_completion
|
||||
fi
|
||||
if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then
|
||||
completions+=("${must_have_one_flag[@]}")
|
||||
fi
|
||||
while IFS='' read -r comp; do
|
||||
COMPREPLY+=("$comp")
|
||||
done < <(compgen -W "${completions[*]}" -- "$cur")
|
||||
COMPREPLY=( $(compgen -W "${completions[*]}" -- "$cur") )
|
||||
|
||||
if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then
|
||||
while IFS='' read -r comp; do
|
||||
COMPREPLY+=("$comp")
|
||||
done < <(compgen -W "${noun_aliases[*]}" -- "$cur")
|
||||
COMPREPLY=( $(compgen -W "${noun_aliases[*]}" -- "$cur") )
|
||||
fi
|
||||
|
||||
if [[ ${#COMPREPLY[@]} -eq 0 ]]; then
|
||||
@@ -210,7 +138,7 @@ __restic_handle_filename_extension_flag()
|
||||
__restic_handle_subdirs_in_dir_flag()
|
||||
{
|
||||
local dir="$1"
|
||||
pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return
|
||||
pushd "${dir}" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1
|
||||
}
|
||||
|
||||
__restic_handle_flag()
|
||||
@@ -418,6 +346,8 @@ _restic_backup()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -479,6 +409,8 @@ _restic_cache()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -533,6 +465,8 @@ _restic_cat()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -596,6 +530,8 @@ _restic_check()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -672,6 +608,8 @@ _restic_copy()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -728,6 +666,8 @@ _restic_diff()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -792,6 +732,8 @@ _restic_dump()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -882,6 +824,8 @@ _restic_find()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -987,6 +931,8 @@ _restic_forget()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1050,6 +996,8 @@ _restic_generate()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1118,6 +1066,8 @@ _restic_init()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1181,6 +1131,8 @@ _restic_key()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1235,6 +1187,8 @@ _restic_list()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1304,6 +1258,8 @@ _restic_ls()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1361,6 +1317,8 @@ _restic_migrate()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1434,6 +1392,8 @@ _restic_mount()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1488,6 +1448,8 @@ _restic_prune()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1542,6 +1504,8 @@ _restic_rebuild-index()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1596,6 +1560,8 @@ _restic_recover()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1680,6 +1646,8 @@ _restic_restore()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1737,6 +1705,8 @@ _restic_self-update()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1810,6 +1780,8 @@ _restic_snapshots()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1877,6 +1849,8 @@ _restic_stats()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -1950,6 +1924,8 @@ _restic_tag()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -2006,6 +1982,8 @@ _restic_unlock()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -2060,6 +2038,8 @@ _restic_version()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -2140,6 +2120,8 @@ _restic_root_command()
|
||||
flags+=("--repo=")
|
||||
two_word_flags+=("--repo")
|
||||
two_word_flags+=("-r")
|
||||
flags+=("--repository-file=")
|
||||
two_word_flags+=("--repository-file")
|
||||
flags+=("--tls-client-cert=")
|
||||
two_word_flags+=("--tls-client-cert")
|
||||
flags+=("--verbose")
|
||||
@@ -2170,7 +2152,6 @@ __start_restic()
|
||||
local commands=("restic")
|
||||
local must_have_one_flag=()
|
||||
local must_have_one_noun=()
|
||||
local has_completion_function
|
||||
local last_command
|
||||
local nouns=()
|
||||
|
||||
|
||||
+2
-12
@@ -3,23 +3,13 @@ Local Cache
|
||||
***********
|
||||
|
||||
In order to speed up certain operations, restic manages a local cache of data.
|
||||
This document describes the data structures for the local cache with version 1.
|
||||
The location of the cache directory depends on the operating system and the
|
||||
environment; see :ref:`caching`.
|
||||
|
||||
Versions
|
||||
========
|
||||
|
||||
The cache directory is selected according to the `XDG base dir specification
|
||||
<https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`__.
|
||||
Each repository has its own cache sub-directory, consisting of the repository ID
|
||||
which is chosen at ``init``. All cache directories for different repos are
|
||||
independent of each other.
|
||||
|
||||
The cache dir for a repo contains a file named ``version``, which contains a
|
||||
single ASCII integer line that stands for the current version of the cache. If
|
||||
a lower version number is found the cache is recreated with the current
|
||||
version. If a higher version number is found the cache is ignored and left as
|
||||
is.
|
||||
|
||||
Snapshots, Data and Indexes
|
||||
===========================
|
||||
|
||||
|
||||
@@ -5,8 +5,9 @@ Reproducible Builds
|
||||
*******************
|
||||
|
||||
This section describes how to reproduce the official released binaries for
|
||||
restic for version 0.9.3 and later. The binary produced depends on the
|
||||
following things:
|
||||
restic for version 0.10.0 and later. For restic versions down to 0.9.3 please
|
||||
refer to the documentation for the respective version. The binary produced
|
||||
depends on the following things:
|
||||
|
||||
* The source code for the release
|
||||
* The exact version of the official `Go compiler <https://golang.org>`__ used to produce the binaries (running ``restic version`` will print this)
|
||||
@@ -17,19 +18,21 @@ following things:
|
||||
* The environment variables (mostly ``$GOOS``, ``$GOARCH``, ``$CGO_ENABLED``)
|
||||
|
||||
In addition, The compressed ZIP files for Windows depends on the modification
|
||||
timestamp of the binary contained in it. In order to reproduce the exact same
|
||||
ZIP file every time, we update the timestamp of the file ``VERSION`` in the
|
||||
source code archive and set the timezone to Europe/Berlin.
|
||||
timestamp and filename of the binary contained in it. In order to reproduce the
|
||||
exact same ZIP file every time, we update the timestamp of the file ``VERSION``
|
||||
in the source code archive and set the timezone to Europe/Berlin.
|
||||
|
||||
In the following example, we'll use the file ``restic-0.9.3.tar.gz`` and Go
|
||||
1.11.1 to reproduce the released binaries.
|
||||
In the following example, we'll use the file ``restic-0.10.0.tar.gz`` and Go
|
||||
1.15.2 to reproduce the released binaries.
|
||||
|
||||
1. Download and extract the Go compiler into ``/usr/local/go``:
|
||||
1. Determine the Go compiler version used to build the released binaries, then download and extract the Go compiler into ``/usr/local/go``:
|
||||
|
||||
.. code::
|
||||
|
||||
$ restic version
|
||||
restic 0.10.0 compiled with go1.15.2 on linux/amd64
|
||||
$ cd /usr/local
|
||||
$ curl -L https://dl.google.com/go/go1.11.1.linux-amd64.tar.gz | tar xz
|
||||
$ curl -L https://dl.google.com/go/go1.15.2.linux-amd64.tar.gz | tar xz
|
||||
|
||||
2. Extract the restic source code into ``/restic``
|
||||
|
||||
@@ -37,7 +40,7 @@ In the following example, we'll use the file ``restic-0.9.3.tar.gz`` and Go
|
||||
|
||||
$ mkdir /restic
|
||||
$ cd /restic
|
||||
$ TZ=Europe/Berlin curl -L https://github.com/restic/restic/releases/download/v0.9.3/restic-0.9.3.tar.gz | tar xz --strip-components=1
|
||||
$ TZ=Europe/Berlin curl -L https://github.com/restic/restic/releases/download/v0.10.0/restic-0.10.0.tar.gz | tar xz --strip-components=1
|
||||
|
||||
3. Build the binaries for Windows and Linux:
|
||||
|
||||
@@ -45,14 +48,14 @@ In the following example, we'll use the file ``restic-0.9.3.tar.gz`` and Go
|
||||
|
||||
$ export PATH=/usr/local/go/bin:$PATH
|
||||
$ go version
|
||||
go version go1.11.1 linux/amd64
|
||||
go version go1.15.2 linux/amd64
|
||||
|
||||
$ GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-s -w" -tags selfupdate -o restic_linux_amd64 ./cmd/restic
|
||||
$ bzip2 restic_linux_amd64
|
||||
|
||||
$ GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-s -w" -tags selfupdate -o restic_windows_amd64.exe ./cmd/restic
|
||||
$ touch --reference VERSION restic_windows_amd64.exe
|
||||
$ TZ=Europe/Berlin zip -q -X restic_windows_amd64.zip restic_windows_amd64.exe
|
||||
$ GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "-s -w" -tags selfupdate -o restic_0.10.0_windows_amd64.exe ./cmd/restic
|
||||
$ touch --reference VERSION restic_0.10.0_windows_amd64.exe
|
||||
$ TZ=Europe/Berlin zip -q -X restic_0.10.0_windows_amd64.zip restic_0.10.0_windows_amd64.exe
|
||||
|
||||
Building the Official Binaries
|
||||
******************************
|
||||
@@ -80,7 +83,7 @@ The following steps are necessary to build the binaries:
|
||||
|
||||
.. code::
|
||||
|
||||
tar xvzf restic-0.9.3.tar.gz
|
||||
tar xvzf restic-0.10.0.tar.gz
|
||||
|
||||
3. Create a directory to place the resulting binaries in:
|
||||
|
||||
@@ -93,19 +96,20 @@ The following steps are necessary to build the binaries:
|
||||
.. code::
|
||||
|
||||
docker run --rm \
|
||||
--volume "$PWD/restic-0.9.3:/restic" \
|
||||
--volume "$PWD/restic-0.10.0:/restic" \
|
||||
--volume "$PWD/output:/output" \
|
||||
restic/builder
|
||||
restic/builder \
|
||||
go run helpers/build-release-binaries/main.go --version 0.10.0
|
||||
|
||||
4. If anything goes wrong, you can enable debug output by specifying the call to ``helpers/build-release-binaries/main.go`` like this:
|
||||
4. If anything goes wrong, you can enable debug output like this:
|
||||
|
||||
.. code::
|
||||
|
||||
docker run --rm \
|
||||
--volume "$PWD/restic-0.9.3:/restic" \
|
||||
--volume "$PWD/restic-0.10.0:/restic" \
|
||||
--volume "$PWD/output:/output" \
|
||||
restic/builder \
|
||||
go run helpers/build-release-binaries/main.go --verbose
|
||||
go run helpers/build-release-binaries/main.go --version 0.10.0 --verbose
|
||||
|
||||
Prepare a New Release
|
||||
*********************
|
||||
@@ -118,6 +122,6 @@ required argument is the new version number (in `Semantic Versioning
|
||||
|
||||
.. code::
|
||||
|
||||
go run helpers/prepare-release/main.go 0.9.3
|
||||
go run helpers/prepare-release/main.go 0.10.0
|
||||
|
||||
Checks can be skipped on demand via flags, please see ``--help`` for details.
|
||||
|
||||
+26
@@ -3,6 +3,32 @@ FAQ
|
||||
|
||||
This is the list of Frequently Asked Questions for restic.
|
||||
|
||||
Will restic resume an interrupted backup?
|
||||
-----------------------------------------
|
||||
|
||||
Yes, restic will resume interrupted backups when they are re-run.
|
||||
|
||||
When backing up, restic periodically writes index files to keep a record of
|
||||
the uploaded data. Even if there's no snapshot created in the end (due to the
|
||||
backup being interrupted), these indexes are stored in the repository for the
|
||||
data that has been uploaded so far. Next time restic runs, it is then able to
|
||||
find the uploaded data through these indexes, and thereby reference it again
|
||||
without having to upload it a second time. This effectively makes it continue
|
||||
from where it saved the last index, which should be up to a few minutes ago.
|
||||
|
||||
It does not matter if the backup was interrupted by the user or if it was due
|
||||
to unforeseen circumstances such as connectivity issues, power loss, etc.
|
||||
Simply re-run the backup again and restic should only upload what it needs to
|
||||
in order to complete the interrupted backup and create a snapshot.
|
||||
|
||||
Note however that during the initial backup run and any re-tries, until there
|
||||
has been a first snapshot created for the backup set (list of files and
|
||||
directories to be backed up), restic will need to re-scan the files on disk as
|
||||
there is no parent snapshot to compare the filesystem with to determine which
|
||||
files have changed. This process should however be far quicker than the
|
||||
uploading, and it's normal to see restic scan the files again when re-running
|
||||
the backup.
|
||||
|
||||
``restic check`` reports packs that aren't referenced in any index, is my repository broken?
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
+43
-37
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -28,145 +29,150 @@ Exit status is 3 if some source data could not be read (incomplete snapshot crea
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-e\fP, \fB\-\-exclude\fP=[]
|
||||
exclude a \fB\fCpattern\fR (can be specified multiple times)
|
||||
exclude a \fB\fCpattern\fR (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-exclude\-caches\fP[=false]
|
||||
excludes cache directories that are marked with a CACHEDIR.TAG file. See https://bford.info/cachedir/ for the Cache Directory Tagging Standard
|
||||
excludes cache directories that are marked with a CACHEDIR.TAG file. See
|
||||
\[la]https://bford.info/cachedir/\[ra] for the Cache Directory Tagging Standard
|
||||
|
||||
.PP
|
||||
\fB\-\-exclude\-file\fP=[]
|
||||
read exclude patterns from a \fB\fCfile\fR (can be specified multiple times)
|
||||
read exclude patterns from a \fB\fCfile\fR (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-exclude\-if\-present\fP=[]
|
||||
takes \fB\fCfilename[:header]\fR, exclude contents of directories containing filename (except filename itself) if header of that file is as provided (can be specified multiple times)
|
||||
takes \fB\fCfilename[:header]\fR, exclude contents of directories containing filename (except filename itself) if header of that file is as provided (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-exclude\-larger\-than\fP=""
|
||||
max \fB\fCsize\fR of the files to be backed up (allowed suffixes: k/K, m/M, g/G, t/T)
|
||||
max \fB\fCsize\fR of the files to be backed up (allowed suffixes: k/K, m/M, g/G, t/T)
|
||||
|
||||
.PP
|
||||
\fB\-\-files\-from\fP=[]
|
||||
read the files to backup from \fB\fCfile\fR (can be combined with file args/can be specified multiple times)
|
||||
read the files to backup from \fB\fCfile\fR (can be combined with file args/can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-f\fP, \fB\-\-force\fP[=false]
|
||||
force re\-reading the target files/directories (overrides the "parent" flag)
|
||||
force re\-reading the target files/directories (overrides the "parent" flag)
|
||||
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for backup
|
||||
help for backup
|
||||
|
||||
.PP
|
||||
\fB\-H\fP, \fB\-\-host\fP=""
|
||||
set the \fB\fChostname\fR for the snapshot manually. To prevent an expensive rescan use the "parent" flag
|
||||
set the \fB\fChostname\fR for the snapshot manually. To prevent an expensive rescan use the "parent" flag
|
||||
|
||||
.PP
|
||||
\fB\-\-iexclude\fP=[]
|
||||
same as \-\-exclude \fB\fCpattern\fR but ignores the casing of filenames
|
||||
same as \-\-exclude \fB\fCpattern\fR but ignores the casing of filenames
|
||||
|
||||
.PP
|
||||
\fB\-\-iexclude\-file\fP=[]
|
||||
same as \-\-exclude\-file but ignores casing of \fB\fCfile\fRnames in patterns
|
||||
same as \-\-exclude\-file but ignores casing of \fB\fCfile\fRnames in patterns
|
||||
|
||||
.PP
|
||||
\fB\-\-ignore\-inode\fP[=false]
|
||||
ignore inode number changes when checking for modified files
|
||||
ignore inode number changes when checking for modified files
|
||||
|
||||
.PP
|
||||
\fB\-x\fP, \fB\-\-one\-file\-system\fP[=false]
|
||||
exclude other file systems
|
||||
exclude other file systems
|
||||
|
||||
.PP
|
||||
\fB\-\-parent\fP=""
|
||||
use this parent \fB\fCsnapshot\fR (default: last snapshot in the repo that has the same target files/directories)
|
||||
use this parent \fB\fCsnapshot\fR (default: last snapshot in the repo that has the same target files/directories)
|
||||
|
||||
.PP
|
||||
\fB\-\-stdin\fP[=false]
|
||||
read backup from stdin
|
||||
read backup from stdin
|
||||
|
||||
.PP
|
||||
\fB\-\-stdin\-filename\fP="stdin"
|
||||
\fB\fCfilename\fR to use when reading from stdin
|
||||
\fB\fCfilename\fR to use when reading from stdin
|
||||
|
||||
.PP
|
||||
\fB\-\-tag\fP=[]
|
||||
add a \fB\fCtag\fR for the new snapshot (can be specified multiple times)
|
||||
add a \fB\fCtag\fR for the new snapshot (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-time\fP=""
|
||||
\fB\fCtime\fR of the backup (ex. '2012\-11\-01 22:08:41') (default: now)
|
||||
\fB\fCtime\fR of the backup (ex. '2012\-11\-01 22:08:41') (default: now)
|
||||
|
||||
.PP
|
||||
\fB\-\-with\-atime\fP[=false]
|
||||
store the atime for all files and directories
|
||||
store the atime for all files and directories
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
+27
-22
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -25,85 +26,89 @@ Exit status is 0 if the command was successful, and non\-zero if there was any e
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-\-cleanup\fP[=false]
|
||||
remove old cache directories
|
||||
remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for cache
|
||||
help for cache
|
||||
|
||||
.PP
|
||||
\fB\-\-max\-age\fP=30
|
||||
max age in \fB\fCdays\fR for cache directories to be considered old
|
||||
max age in \fB\fCdays\fR for cache directories to be considered old
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-size\fP[=false]
|
||||
do not output the size of the cache directories
|
||||
do not output the size of the cache directories
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
+24
-19
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -25,73 +26,77 @@ Exit status is 0 if the command was successful, and non\-zero if there was any e
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for cat
|
||||
help for cat
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
+28
-23
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -30,89 +31,93 @@ Exit status is 0 if the command was successful, and non\-zero if there was any e
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-\-check\-unused\fP[=false]
|
||||
find unused blobs
|
||||
find unused blobs
|
||||
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for check
|
||||
help for check
|
||||
|
||||
.PP
|
||||
\fB\-\-read\-data\fP[=false]
|
||||
read all data blobs
|
||||
read all data blobs
|
||||
|
||||
.PP
|
||||
\fB\-\-read\-data\-subset\fP=""
|
||||
read subset n of m data packs (format: \fB\fCn/m\fR)
|
||||
read subset n of m data packs (format: \fB\fCn/m\fR)
|
||||
|
||||
.PP
|
||||
\fB\-\-with\-cache\fP[=false]
|
||||
use the cache
|
||||
use the cache
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
+31
-26
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -25,101 +26,105 @@ option when initializing a new destination repository using the "init" command.
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for copy
|
||||
help for copy
|
||||
|
||||
.PP
|
||||
\fB\-H\fP, \fB\-\-host\fP=[]
|
||||
only consider snapshots for this \fB\fChost\fR, when no snapshot ID is given (can be specified multiple times)
|
||||
only consider snapshots for this \fB\fChost\fR, when no snapshot ID is given (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint2\fP=""
|
||||
key ID of key to try decrypting the destination repository first (default: $RESTIC\_KEY\_HINT2)
|
||||
key ID of key to try decrypting the destination repository first (default: $RESTIC\_KEY\_HINT2)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command2\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the destination repository password from (default: $RESTIC\_PASSWORD\_COMMAND2)
|
||||
shell \fB\fCcommand\fR to obtain the destination repository password from (default: $RESTIC\_PASSWORD\_COMMAND2)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-file2\fP=""
|
||||
\fB\fCfile\fR to read the destination repository password from (default: $RESTIC\_PASSWORD\_FILE2)
|
||||
\fB\fCfile\fR to read the destination repository password from (default: $RESTIC\_PASSWORD\_FILE2)
|
||||
|
||||
.PP
|
||||
\fB\-\-path\fP=[]
|
||||
only consider snapshots which include this (absolute) \fB\fCpath\fR, when no snapshot ID is given
|
||||
only consider snapshots which include this (absolute) \fB\fCpath\fR, when no snapshot ID is given
|
||||
|
||||
.PP
|
||||
\fB\-\-repo2\fP=""
|
||||
destination repository to copy snapshots to (default: $RESTIC\_REPOSITORY2)
|
||||
destination \fB\fCrepository\fR to copy snapshots to (default: $RESTIC\_REPOSITORY2)
|
||||
|
||||
.PP
|
||||
\fB\-\-tag\fP=[]
|
||||
only consider snapshots which include this \fB\fCtaglist\fR, when no snapshot ID is given
|
||||
only consider snapshots which include this \fB\fCtaglist\fR, when no snapshot ID is given
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
+25
-20
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -41,77 +42,81 @@ Exit status is 0 if the command was successful, and non\-zero if there was any e
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for diff
|
||||
help for diff
|
||||
|
||||
.PP
|
||||
\fB\-\-metadata\fP[=false]
|
||||
print changes in metadata
|
||||
print changes in metadata
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
+27
-22
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -32,85 +33,89 @@ Exit status is 0 if the command was successful, and non\-zero if there was any e
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for dump
|
||||
help for dump
|
||||
|
||||
.PP
|
||||
\fB\-H\fP, \fB\-\-host\fP=[]
|
||||
only consider snapshots for this host when the snapshot ID is "latest" (can be specified multiple times)
|
||||
only consider snapshots for this host when the snapshot ID is "latest" (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-path\fP=[]
|
||||
only consider snapshots which include this (absolute) \fB\fCpath\fR for snapshot ID "latest"
|
||||
only consider snapshots which include this (absolute) \fB\fCpath\fR for snapshot ID "latest"
|
||||
|
||||
.PP
|
||||
\fB\-\-tag\fP=[]
|
||||
only consider snapshots which include this \fB\fCtaglist\fR for snapshot ID "latest"
|
||||
only consider snapshots which include this \fB\fCtaglist\fR for snapshot ID "latest"
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
+36
-31
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -22,121 +23,125 @@ It can also be used to search for restic blobs or trees for troubleshooting.
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-\-blob\fP[=false]
|
||||
pattern is a blob\-ID
|
||||
pattern is a blob\-ID
|
||||
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for find
|
||||
help for find
|
||||
|
||||
.PP
|
||||
\fB\-H\fP, \fB\-\-host\fP=[]
|
||||
only consider snapshots for this \fB\fChost\fR, when no snapshot ID is given (can be specified multiple times)
|
||||
only consider snapshots for this \fB\fChost\fR, when no snapshot ID is given (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-i\fP, \fB\-\-ignore\-case\fP[=false]
|
||||
ignore case for pattern
|
||||
ignore case for pattern
|
||||
|
||||
.PP
|
||||
\fB\-l\fP, \fB\-\-long\fP[=false]
|
||||
use a long listing format showing size and mode
|
||||
use a long listing format showing size and mode
|
||||
|
||||
.PP
|
||||
\fB\-N\fP, \fB\-\-newest\fP=""
|
||||
newest modification date/time
|
||||
newest modification date/time
|
||||
|
||||
.PP
|
||||
\fB\-O\fP, \fB\-\-oldest\fP=""
|
||||
oldest modification date/time
|
||||
oldest modification date/time
|
||||
|
||||
.PP
|
||||
\fB\-\-pack\fP[=false]
|
||||
pattern is a pack\-ID
|
||||
pattern is a pack\-ID
|
||||
|
||||
.PP
|
||||
\fB\-\-path\fP=[]
|
||||
only consider snapshots which include this (absolute) \fB\fCpath\fR, when no snapshot\-ID is given
|
||||
only consider snapshots which include this (absolute) \fB\fCpath\fR, when no snapshot\-ID is given
|
||||
|
||||
.PP
|
||||
\fB\-\-show\-pack\-id\fP[=false]
|
||||
display the pack\-ID the blobs belong to (with \-\-blob or \-\-tree)
|
||||
display the pack\-ID the blobs belong to (with \-\-blob or \-\-tree)
|
||||
|
||||
.PP
|
||||
\fB\-s\fP, \fB\-\-snapshot\fP=[]
|
||||
snapshot \fB\fCid\fR to search in (can be given multiple times)
|
||||
snapshot \fB\fCid\fR to search in (can be given multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-tag\fP=[]
|
||||
only consider snapshots which include this \fB\fCtaglist\fR, when no snapshot\-ID is given
|
||||
only consider snapshots which include this \fB\fCtaglist\fR, when no snapshot\-ID is given
|
||||
|
||||
.PP
|
||||
\fB\-\-tree\fP[=false]
|
||||
pattern is a tree\-ID
|
||||
pattern is a tree\-ID
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH EXAMPLE
|
||||
|
||||
+39
-34
@@ -1,6 +1,7 @@
|
||||
.TH "restic backup" "1" "Jan 2017" "generated by `restic generate`" ""
|
||||
.nh
|
||||
.TH restic backup(1)Jan 2017
|
||||
generated by \fB\fCrestic generate\fR
|
||||
.ad l
|
||||
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
@@ -28,133 +29,137 @@ Exit status is 0 if the command was successful, and non\-zero if there was any e
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
\fB\-l\fP, \fB\-\-keep\-last\fP=0
|
||||
keep the last \fB\fCn\fR snapshots
|
||||
keep the last \fB\fCn\fR snapshots
|
||||
|
||||
.PP
|
||||
\fB\-H\fP, \fB\-\-keep\-hourly\fP=0
|
||||
keep the last \fB\fCn\fR hourly snapshots
|
||||
keep the last \fB\fCn\fR hourly snapshots
|
||||
|
||||
.PP
|
||||
\fB\-d\fP, \fB\-\-keep\-daily\fP=0
|
||||
keep the last \fB\fCn\fR daily snapshots
|
||||
keep the last \fB\fCn\fR daily snapshots
|
||||
|
||||
.PP
|
||||
\fB\-w\fP, \fB\-\-keep\-weekly\fP=0
|
||||
keep the last \fB\fCn\fR weekly snapshots
|
||||
keep the last \fB\fCn\fR weekly snapshots
|
||||
|
||||
.PP
|
||||
\fB\-m\fP, \fB\-\-keep\-monthly\fP=0
|
||||
keep the last \fB\fCn\fR monthly snapshots
|
||||
keep the last \fB\fCn\fR monthly snapshots
|
||||
|
||||
.PP
|
||||
\fB\-y\fP, \fB\-\-keep\-yearly\fP=0
|
||||
keep the last \fB\fCn\fR yearly snapshots
|
||||
keep the last \fB\fCn\fR yearly snapshots
|
||||
|
||||
.PP
|
||||
\fB\-\-keep\-within\fP=
|
||||
keep snapshots that are newer than \fB\fCduration\fR (eg. 1y5m7d2h) relative to the latest snapshot
|
||||
keep snapshots that are newer than \fB\fCduration\fR (eg. 1y5m7d2h) relative to the latest snapshot
|
||||
|
||||
.PP
|
||||
\fB\-\-keep\-tag\fP=[]
|
||||
keep snapshots with this \fB\fCtaglist\fR (can be specified multiple times)
|
||||
keep snapshots with this \fB\fCtaglist\fR (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-host\fP=[]
|
||||
only consider snapshots with the given \fB\fChost\fR (can be specified multiple times)
|
||||
only consider snapshots with the given \fB\fChost\fR (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-tag\fP=[]
|
||||
only consider snapshots which include this \fB\fCtaglist\fR in the format \fB\fCtag[,tag,...]\fR (can be specified multiple times)
|
||||
only consider snapshots which include this \fB\fCtaglist\fR in the format \fB\fCtag[,tag,...]\fR (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-path\fP=[]
|
||||
only consider snapshots which include this (absolute) \fB\fCpath\fR (can be specified multiple times)
|
||||
only consider snapshots which include this (absolute) \fB\fCpath\fR (can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-c\fP, \fB\-\-compact\fP[=false]
|
||||
use compact format
|
||||
use compact output format
|
||||
|
||||
.PP
|
||||
\fB\-g\fP, \fB\-\-group\-by\fP="host,paths"
|
||||
string for grouping snapshots by host,paths,tags
|
||||
string for grouping snapshots by host,paths,tags
|
||||
|
||||
.PP
|
||||
\fB\-n\fP, \fB\-\-dry\-run\fP[=false]
|
||||
do not delete anything, just print what would be done
|
||||
do not delete anything, just print what would be done
|
||||
|
||||
.PP
|
||||
\fB\-\-prune\fP[=false]
|
||||
automatically run the 'prune' command if snapshots have been removed
|
||||
automatically run the 'prune' command if snapshots have been removed
|
||||
|
||||
.PP
|
||||
\fB\-h\fP, \fB\-\-help\fP[=false]
|
||||
help for forget
|
||||
help for forget
|
||||
|
||||
|
||||
.SH OPTIONS INHERITED FROM PARENT COMMANDS
|
||||
.PP
|
||||
\fB\-\-cacert\fP=[]
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
\fB\fCfile\fR to load root certificates from (default: use system certificates)
|
||||
|
||||
.PP
|
||||
\fB\-\-cache\-dir\fP=""
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
set the cache \fB\fCdirectory\fR\&. (default: use system default cache directory)
|
||||
|
||||
.PP
|
||||
\fB\-\-cleanup\-cache\fP[=false]
|
||||
auto remove old cache directories
|
||||
auto remove old cache directories
|
||||
|
||||
.PP
|
||||
\fB\-\-json\fP[=false]
|
||||
set output mode to JSON for commands that support it
|
||||
set output mode to JSON for commands that support it
|
||||
|
||||
.PP
|
||||
\fB\-\-key\-hint\fP=""
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
\fB\fCkey\fR ID of key to try decrypting first (default: $RESTIC\_KEY\_HINT)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-download\fP=0
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits downloads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-limit\-upload\fP=0
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
limits uploads to a maximum rate in KiB/s. (default: unlimited)
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-cache\fP[=false]
|
||||
do not use a local cache
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB\-\-no\-lock\fP[=false]
|
||||
do not lock the repo, this allows some operations on read\-only repos
|
||||
do not lock the repository, this allows some operations on read\-only repositories
|
||||
|
||||
.PP
|
||||
\fB\-o\fP, \fB\-\-option\fP=[]
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
set extended option (\fB\fCkey=value\fR, can be specified multiple times)
|
||||
|
||||
.PP
|
||||
\fB\-\-password\-command\fP=""
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
shell \fB\fCcommand\fR to obtain the repository password from (default: $RESTIC\_PASSWORD\_COMMAND)
|
||||
|
||||
.PP
|
||||
\fB\-p\fP, \fB\-\-password\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
\fB\fCfile\fR to read the repository password from (default: $RESTIC\_PASSWORD\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-q\fP, \fB\-\-quiet\fP[=false]
|
||||
do not output comprehensive progress report
|
||||
do not output comprehensive progress report
|
||||
|
||||
.PP
|
||||
\fB\-r\fP, \fB\-\-repo\fP=""
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
\fB\fCrepository\fR to backup to or restore from (default: $RESTIC\_REPOSITORY)
|
||||
|
||||
.PP
|
||||
\fB\-\-repository\-file\fP=""
|
||||
\fB\fCfile\fR to read the repository location from (default: $RESTIC\_REPOSITORY\_FILE)
|
||||
|
||||
.PP
|
||||
\fB\-\-tls\-client\-cert\fP=""
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
path to a \fB\fCfile\fR containing PEM encoded TLS client certificate and private key
|
||||
|
||||
.PP
|
||||
\fB\-v\fP, \fB\-\-verbose\fP[=0]
|
||||
be verbose (specify \-\-verbose multiple times or level \-\-verbose=\fB\fCn\fR)
|
||||
be verbose (specify multiple times or a level using \-\-verbose=\fB\fCn\fR, max level/times is 3)
|
||||
|
||||
|
||||
.SH SEE ALSO
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user