mirror of
https://github.com/restic/restic.git
synced 2025-08-17 22:07:27 +00:00
Compare commits
74 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fe9f142b52 | ||
![]() |
6ae760751a | ||
![]() |
2fa1b42706 | ||
![]() |
ca04a88e65 | ||
![]() |
12e858b7af | ||
![]() |
834f08fe2d | ||
![]() |
814ef4901f | ||
![]() |
84bc9432de | ||
![]() |
e9d711422a | ||
![]() |
0f9fa44de5 | ||
![]() |
3786536dc1 | ||
![]() |
811be5984d | ||
![]() |
b0ead75de5 | ||
![]() |
6cd2804bff | ||
![]() |
a72c2b74f3 | ||
![]() |
261b1455c7 | ||
![]() |
2a0bd2b637 | ||
![]() |
4589da7eb9 | ||
![]() |
75e72d826c | ||
![]() |
d8916bc3d9 | ||
![]() |
dc11d012bb | ||
![]() |
8ef5425351 | ||
![]() |
885431ec2b | ||
![]() |
cb85fb46dd | ||
![]() |
2f30c940b2 | ||
![]() |
0ea62b5ac6 | ||
![]() |
29e1caf825 | ||
![]() |
0164f5310d | ||
![]() |
0ec9383ba2 | ||
![]() |
abca112404 | ||
![]() |
b70b94507a | ||
![]() |
d987582594 | ||
![]() |
ef2e473b99 | ||
![]() |
e4bbde7036 | ||
![]() |
ec0fb46f6c | ||
![]() |
103beb96bc | ||
![]() |
f0f89d7f27 | ||
![]() |
cf352ccafb | ||
![]() |
b856e9489a | ||
![]() |
ce7db90e08 | ||
![]() |
620518aec6 | ||
![]() |
f2fafbffaa | ||
![]() |
7a3a884874 | ||
![]() |
772a907533 | ||
![]() |
a9446c1184 | ||
![]() |
1bab29c336 | ||
![]() |
e886c3f6b2 | ||
![]() |
c95de54726 | ||
![]() |
d4b8abd3e2 | ||
![]() |
948ab3ccaf | ||
![]() |
bb0c923298 | ||
![]() |
ff0c975443 | ||
![]() |
7e61e117d6 | ||
![]() |
220a28582e | ||
![]() |
f44fd73230 | ||
![]() |
76bd975e03 | ||
![]() |
64b7aed362 | ||
![]() |
3fa6b2de4a | ||
![]() |
5cd000f4b0 | ||
![]() |
59fe24cb2b | ||
![]() |
1a5efcf680 | ||
![]() |
d33fe6dd3c | ||
![]() |
c8dd95f104 | ||
![]() |
7d980b469d | ||
![]() |
d863234e3e | ||
![]() |
4be45de1c2 | ||
![]() |
8c1125fe13 | ||
![]() |
0b6ccea461 | ||
![]() |
de6135351e | ||
![]() |
d47581b25e | ||
![]() |
69dec02a14 | ||
![]() |
826d880614 | ||
![]() |
dbf7ef72b9 | ||
![]() |
27ec320eae |
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@b4bedf8053341df3b5a9f9e0f2cf4e79e27360c6
|
||||
uses: docker/login-action@3d58c274f17dffee475a5520cbe67f0a882c4dbb
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
|
8
.github/workflows/tests.yml
vendored
8
.github/workflows/tests.yml
vendored
@@ -62,7 +62,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go }}
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
|
||||
@@ -226,7 +226,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Set up Go ${{ env.latest_go }}
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.latest_go }}
|
||||
|
||||
@@ -244,7 +244,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go ${{ env.latest_go }}
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.latest_go }}
|
||||
|
||||
@@ -255,7 +255,7 @@ jobs:
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||
version: v1.52.2
|
||||
version: v1.55.2
|
||||
args: --verbose --timeout 5m
|
||||
|
||||
# only run golangci-lint for pull requests, otherwise ALL hints get
|
||||
|
18
.readthedocs.yaml
Normal file
18
.readthedocs.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: doc/conf.py
|
||||
|
||||
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
|
||||
python:
|
||||
install:
|
||||
- requirements: doc/requirements.txt
|
494
CHANGELOG.md
494
CHANGELOG.md
@@ -1,11 +1,220 @@
|
||||
Changelog for restic 0.16.1 (2023-10-24)
|
||||
=======================================
|
||||
# Table of Contents
|
||||
|
||||
* [Changelog for 0.16.5](#changelog-for-restic-0165-2024-07-01)
|
||||
* [Changelog for 0.16.4](#changelog-for-restic-0164-2024-02-04)
|
||||
* [Changelog for 0.16.3](#changelog-for-restic-0163-2024-01-14)
|
||||
* [Changelog for 0.16.2](#changelog-for-restic-0162-2023-10-29)
|
||||
* [Changelog for 0.16.1](#changelog-for-restic-0161-2023-10-24)
|
||||
* [Changelog for 0.16.0](#changelog-for-restic-0160-2023-07-31)
|
||||
* [Changelog for 0.15.2](#changelog-for-restic-0152-2023-04-24)
|
||||
* [Changelog for 0.15.1](#changelog-for-restic-0151-2023-01-30)
|
||||
* [Changelog for 0.15.0](#changelog-for-restic-0150-2023-01-12)
|
||||
* [Changelog for 0.14.0](#changelog-for-restic-0140-2022-08-25)
|
||||
* [Changelog for 0.13.0](#changelog-for-restic-0130-2022-03-26)
|
||||
* [Changelog for 0.12.1](#changelog-for-restic-0121-2021-08-03)
|
||||
* [Changelog for 0.12.0](#changelog-for-restic-0120-2021-02-14)
|
||||
* [Changelog for 0.11.0](#changelog-for-restic-0110-2020-11-05)
|
||||
* [Changelog for 0.10.0](#changelog-for-restic-0100-2020-09-19)
|
||||
* [Changelog for 0.9.6](#changelog-for-restic-096-2019-11-22)
|
||||
* [Changelog for 0.9.5](#changelog-for-restic-095-2019-04-23)
|
||||
* [Changelog for 0.9.4](#changelog-for-restic-094-2019-01-06)
|
||||
* [Changelog for 0.9.3](#changelog-for-restic-093-2018-10-13)
|
||||
* [Changelog for 0.9.2](#changelog-for-restic-092-2018-08-06)
|
||||
* [Changelog for 0.9.1](#changelog-for-restic-091-2018-06-10)
|
||||
* [Changelog for 0.9.0](#changelog-for-restic-090-2018-05-21)
|
||||
* [Changelog for 0.8.3](#changelog-for-restic-083-2018-02-26)
|
||||
* [Changelog for 0.8.2](#changelog-for-restic-082-2018-02-17)
|
||||
* [Changelog for 0.8.1](#changelog-for-restic-081-2017-12-27)
|
||||
* [Changelog for 0.8.0](#changelog-for-restic-080-2017-11-26)
|
||||
* [Changelog for 0.7.3](#changelog-for-restic-073-2017-09-20)
|
||||
* [Changelog for 0.7.2](#changelog-for-restic-072-2017-09-13)
|
||||
* [Changelog for 0.7.1](#changelog-for-restic-071-2017-07-22)
|
||||
* [Changelog for 0.7.0](#changelog-for-restic-070-2017-07-01)
|
||||
* [Changelog for 0.6.1](#changelog-for-restic-061-2017-06-01)
|
||||
* [Changelog for 0.6.0](#changelog-for-restic-060-2017-05-29)
|
||||
|
||||
|
||||
# Changelog for restic 0.16.5 (2024-07-01)
|
||||
The following sections list the changes in restic 0.16.5 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
## Summary
|
||||
|
||||
* Enh #4799: Add option to force use of Azure CLI credential
|
||||
* Enh #4873: Update dependencies
|
||||
|
||||
## Details
|
||||
|
||||
* Enhancement #4799: Add option to force use of Azure CLI credential
|
||||
|
||||
A new environment variable `AZURE_FORCE_CLI_CREDENTIAL=true` allows forcing the use of
|
||||
Azure CLI credential, ignoring other credentials like managed identity.
|
||||
|
||||
https://github.com/restic/restic/pull/4799
|
||||
|
||||
* Enhancement #4873: Update dependencies
|
||||
|
||||
A few potentially vulnerable dependencies were updated.
|
||||
|
||||
https://github.com/restic/restic/issues/4873
|
||||
https://github.com/restic/restic/pull/4878
|
||||
|
||||
|
||||
# Changelog for restic 0.16.4 (2024-02-04)
|
||||
The following sections list the changes in restic 0.16.4 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
## Summary
|
||||
|
||||
* Fix #4677: Downgrade zstd library to fix rare data corruption at max. compression
|
||||
* Enh #4529: Add extra verification of data integrity before upload
|
||||
|
||||
## Details
|
||||
|
||||
* Bugfix #4677: Downgrade zstd library to fix rare data corruption at max. compression
|
||||
|
||||
In restic 0.16.3, backups where the compression level was set to `max` (using `--compression
|
||||
max`) could in rare and very specific circumstances result in data corruption due to a bug in the
|
||||
library used for compressing data. Restic 0.16.1 and 0.16.2 were not affected.
|
||||
|
||||
Restic now uses the previous version of the library used to compress data, the same version used
|
||||
by restic 0.16.2. Please note that the `auto` compression level (which restic uses by default)
|
||||
was never affected, and even if you used `max` compression, chances of being affected by this
|
||||
issue are small.
|
||||
|
||||
To check a repository for any corruption, run `restic check --read-data`. This will download
|
||||
and verify the whole repository and can be used at any time to completely verify the integrity of
|
||||
a repository. If the `check` command detects anomalies, follow the suggested steps.
|
||||
|
||||
https://github.com/restic/restic/issues/4677
|
||||
https://github.com/restic/restic/pull/4679
|
||||
|
||||
* Enhancement #4529: Add extra verification of data integrity before upload
|
||||
|
||||
Hardware issues, or a bug in restic or its dependencies, could previously cause corruption in
|
||||
the files restic created and stored in the repository. Detecting such corruption previously
|
||||
required explicitly running the `check --read-data` or `check --read-data-subset`
|
||||
commands.
|
||||
|
||||
To further ensure data integrity, even in the case of hardware issues or software bugs, restic
|
||||
now performs additional verification of the files about to be uploaded to the repository.
|
||||
|
||||
These extra checks will increase CPU usage during backups. They can therefore, if absolutely
|
||||
necessary, be disabled using the `--no-extra-verify` global option. Please note that this
|
||||
should be combined with more active checking using the previously mentioned check commands.
|
||||
|
||||
https://github.com/restic/restic/issues/4529
|
||||
https://github.com/restic/restic/pull/4681
|
||||
|
||||
|
||||
# Changelog for restic 0.16.3 (2024-01-14)
|
||||
The following sections list the changes in restic 0.16.3 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
## Summary
|
||||
|
||||
* Fix #4560: Improve errors for irregular files on Windows
|
||||
* Fix #4574: Support backup of deduplicated files on Windows again
|
||||
* Fix #4612: Improve error handling for `rclone` backend
|
||||
* Fix #4624: Correct `restore` progress information if an error occurs
|
||||
* Fix #4626: Improve reliability of restoring large files
|
||||
|
||||
## Details
|
||||
|
||||
* Bugfix #4560: Improve errors for irregular files on Windows
|
||||
|
||||
Since Go 1.21, most filesystem reparse points on Windows are considered to be irregular files.
|
||||
This caused restic to show an `error: invalid node type ""` error message for those files.
|
||||
|
||||
This error message has now been improved and includes the relevant file path: `error:
|
||||
nodeFromFileInfo path/to/file: unsupported file type "irregular"`. As irregular files are
|
||||
not required to behave like regular files, it is not possible to provide a generic way to back up
|
||||
those files.
|
||||
|
||||
https://github.com/restic/restic/issues/4560
|
||||
https://github.com/restic/restic/pull/4620
|
||||
https://forum.restic.net/t/windows-backup-error-invalid-node-type/6875
|
||||
|
||||
* Bugfix #4574: Support backup of deduplicated files on Windows again
|
||||
|
||||
With the official release builds of restic 0.16.1 and 0.16.2, it was not possible to back up
|
||||
files that were deduplicated by the corresponding Windows Server feature. This also applied
|
||||
to restic versions built using Go 1.21.0-1.21.4.
|
||||
|
||||
The Go version used to build restic has now been updated to fix this.
|
||||
|
||||
https://github.com/restic/restic/issues/4574
|
||||
https://github.com/restic/restic/pull/4621
|
||||
|
||||
* Bugfix #4612: Improve error handling for `rclone` backend
|
||||
|
||||
Since restic 0.16.0, if rclone encountered an error while listing files, this could in rare
|
||||
circumstances cause restic to assume that there are no files. Although unlikely, this
|
||||
situation could result in data loss if it were to happen right when the `prune` command is
|
||||
listing existing snapshots.
|
||||
|
||||
Error handling has now been improved to detect and work around this case.
|
||||
|
||||
https://github.com/restic/restic/issues/4612
|
||||
https://github.com/restic/restic/pull/4618
|
||||
|
||||
* Bugfix #4624: Correct `restore` progress information if an error occurs
|
||||
|
||||
If an error occurred while restoring a snapshot, this could cause the `restore` progress bar to
|
||||
show incorrect information. In addition, if a data file could not be loaded completely, then
|
||||
errors would also be reported for some already restored files.
|
||||
|
||||
Error reporting of the `restore` command has now been made more accurate.
|
||||
|
||||
https://github.com/restic/restic/pull/4624
|
||||
https://forum.restic.net/t/errors-restoring-with-restic-on-windows-server-s3/6943
|
||||
|
||||
* Bugfix #4626: Improve reliability of restoring large files
|
||||
|
||||
In some cases restic failed to restore large files that frequently contain the same file chunk.
|
||||
In combination with certain backends, this could result in network connection timeouts that
|
||||
caused incomplete restores.
|
||||
|
||||
Restic now includes special handling for such file chunks to ensure reliable restores.
|
||||
|
||||
https://github.com/restic/restic/pull/4626
|
||||
https://forum.restic.net/t/errors-restoring-with-restic-on-windows-server-s3/6943
|
||||
|
||||
|
||||
# Changelog for restic 0.16.2 (2023-10-29)
|
||||
The following sections list the changes in restic 0.16.2 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
## Summary
|
||||
|
||||
* Fix #4540: Restore ARMv5 support for ARM binaries
|
||||
* Fix #4545: Repair documentation build on Read the Docs
|
||||
|
||||
## Details
|
||||
|
||||
* Bugfix #4540: Restore ARMv5 support for ARM binaries
|
||||
|
||||
The official release binaries for restic 0.16.1 were accidentally built to require ARMv7. The
|
||||
build process is now updated to restore support for ARMv5.
|
||||
|
||||
Please note that restic 0.17.0 will drop support for ARMv5 and require at least ARMv6.
|
||||
|
||||
https://github.com/restic/restic/issues/4540
|
||||
|
||||
* Bugfix #4545: Repair documentation build on Read the Docs
|
||||
|
||||
For restic 0.16.1, no documentation was available at https://restic.readthedocs.io/ .
|
||||
|
||||
The documentation build process is now updated to work again.
|
||||
|
||||
https://github.com/restic/restic/pull/4545
|
||||
|
||||
|
||||
# Changelog for restic 0.16.1 (2023-10-24)
|
||||
The following sections list the changes in restic 0.16.1 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #4513: Make `key list` command honor `--no-lock`
|
||||
* Fix #4516: Do not try to load password on command line autocomplete
|
||||
@@ -17,8 +226,7 @@ Summary
|
||||
* Enh #4511: Include inode numbers in JSON output for `find` and `ls` commands
|
||||
* Enh #4519: Add config option to set SFTP command arguments
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #4513: Make `key list` command honor `--no-lock`
|
||||
|
||||
@@ -119,14 +327,11 @@ Details
|
||||
https://github.com/restic/restic/pull/4519
|
||||
|
||||
|
||||
Changelog for restic 0.16.0 (2023-07-31)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.16.0 (2023-07-31)
|
||||
The following sections list the changes in restic 0.16.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #2565: Support "unlimited" in `forget --keep-*` options
|
||||
* Fix #3311: Support non-UTF8 paths as symlink target
|
||||
@@ -158,8 +363,7 @@ Summary
|
||||
* Enh #4226: Allow specifying region of new buckets in the `gs` backend
|
||||
* Enh #4375: Add support for extended attributes on symlinks
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #2565: Support "unlimited" in `forget --keep-*` options
|
||||
|
||||
@@ -466,14 +670,11 @@ Details
|
||||
https://github.com/restic/restic/pull/4379
|
||||
|
||||
|
||||
Changelog for restic 0.15.2 (2023-04-24)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.15.2 (2023-04-24)
|
||||
The following sections list the changes in restic 0.15.2 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Sec #4275: Update golang.org/x/net to address CVE-2022-41723
|
||||
* Fix #2260: Sanitize filenames printed by `backup` during processing
|
||||
@@ -483,8 +684,7 @@ Summary
|
||||
* Enh #4180: Add release binaries for riscv64 architecture on Linux
|
||||
* Enh #4219: Upgrade Minio to version 7.0.49
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Security #4275: Update golang.org/x/net to address CVE-2022-41723
|
||||
|
||||
@@ -555,14 +755,11 @@ Details
|
||||
https://github.com/restic/restic/pull/4219
|
||||
|
||||
|
||||
Changelog for restic 0.15.1 (2023-01-30)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.15.1 (2023-01-30)
|
||||
The following sections list the changes in restic 0.15.1 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #3750: Remove `b2_download_file_by_name: 404` warning from B2 backend
|
||||
* Fix #4147: Make `prune --quiet` not print progress bar
|
||||
@@ -570,8 +767,7 @@ Summary
|
||||
* Fix #4167: Add missing ETA in `backup` progress bar
|
||||
* Enh #4143: Ignore empty lock files
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #3750: Remove `b2_download_file_by_name: 404` warning from B2 backend
|
||||
|
||||
@@ -630,14 +826,11 @@ Details
|
||||
https://github.com/restic/restic/pull/4152
|
||||
|
||||
|
||||
Changelog for restic 0.15.0 (2023-01-12)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.15.0 (2023-01-12)
|
||||
The following sections list the changes in restic 0.15.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #2015: Make `mount` return exit code 0 after receiving Ctrl-C / SIGINT
|
||||
* Fix #2578: Make `restore` replace existing symlinks
|
||||
@@ -679,8 +872,7 @@ Summary
|
||||
* Enh #3943: Ignore additional/unknown files in repository
|
||||
* Enh #3955: Improve `backup` performance for small files
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #2015: Make `mount` return exit code 0 after receiving Ctrl-C / SIGINT
|
||||
|
||||
@@ -1111,14 +1303,11 @@ Details
|
||||
https://github.com/restic/restic/pull/3955
|
||||
|
||||
|
||||
Changelog for restic 0.14.0 (2022-08-25)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.14.0 (2022-08-25)
|
||||
The following sections list the changes in restic 0.14.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #2248: Support `self-update` on Windows
|
||||
* Fix #3428: List snapshots in backend at most once to resolve snapshot IDs
|
||||
@@ -1154,8 +1343,7 @@ Summary
|
||||
* Enh #3819: Validate include/exclude patterns before restoring
|
||||
* Enh #3837: Improve SFTP repository initialization over slow links
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #2248: Support `self-update` on Windows
|
||||
|
||||
@@ -1492,7 +1680,7 @@ Details
|
||||
|
||||
Restic did not support limiting the IO concurrency / number of connections for accessing
|
||||
repositories stored using the local or SFTP backends. The number of connections is now limited
|
||||
as for other backends, and can be configured via the the `-o local.connections=2` and `-o
|
||||
as for other backends, and can be configured via the `-o local.connections=2` and `-o
|
||||
sftp.connections=5` options. This ensures that restic does not overwhelm the backend with
|
||||
concurrent IO operations.
|
||||
|
||||
@@ -1561,14 +1749,11 @@ Details
|
||||
https://github.com/restic/restic/pull/3840
|
||||
|
||||
|
||||
Changelog for restic 0.13.0 (2022-03-26)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.13.0 (2022-03-26)
|
||||
The following sections list the changes in restic 0.13.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1106: Never lock repository for `list locks`
|
||||
* Fix #2345: Make cache crash-resistant and usable by multiple concurrent processes
|
||||
@@ -1605,8 +1790,7 @@ Summary
|
||||
* Enh #3542: Add file mode in symbolic notation to `ls --json`
|
||||
* Enh #3593: Improve `copy` performance by parallelizing IO
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1106: Never lock repository for `list locks`
|
||||
|
||||
@@ -1966,14 +2150,11 @@ Details
|
||||
https://github.com/restic/restic/pull/3593
|
||||
|
||||
|
||||
Changelog for restic 0.12.1 (2021-08-03)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.12.1 (2021-08-03)
|
||||
The following sections list the changes in restic 0.12.1 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #2742: Improve error handling for rclone and REST backend over HTTP2
|
||||
* Fix #3111: Fix terminal output redirection for PowerShell
|
||||
@@ -1998,8 +2179,7 @@ Summary
|
||||
* Enh #3427: `find --pack` fallback to index if data file is missing
|
||||
* Enh #3456: Support filtering and specifying untagged snapshots
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #2742: Improve error handling for rclone and REST backend over HTTP2
|
||||
|
||||
@@ -2212,14 +2392,11 @@ Details
|
||||
https://github.com/restic/restic/pull/3457
|
||||
|
||||
|
||||
Changelog for restic 0.12.0 (2021-02-14)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.12.0 (2021-02-14)
|
||||
The following sections list the changes in restic 0.12.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1681: Make `mount` not create missing mount point directory
|
||||
* Fix #1800: Ignore `no data available` filesystem error during backup
|
||||
@@ -2257,8 +2434,7 @@ Summary
|
||||
* Enh #3250: Add several more error checks
|
||||
* Enh #3254: Enable HTTP/2 for backend connections
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1681: Make `mount` not create missing mount point directory
|
||||
|
||||
@@ -2709,14 +2885,11 @@ Details
|
||||
https://github.com/restic/restic/pull/3254
|
||||
|
||||
|
||||
Changelog for restic 0.11.0 (2020-11-05)
|
||||
=======================================
|
||||
|
||||
# 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
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1212: Restore timestamps and permissions on intermediate directories
|
||||
* Fix #1756: Mark repository files as read-only when using the local backend
|
||||
@@ -2734,8 +2907,7 @@ Summary
|
||||
* Enh #2969: Optimize check for unchanged files during backup
|
||||
* Enh #2978: Warn if parent snapshot cannot be loaded during backup
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1212: Restore timestamps and permissions on intermediate directories
|
||||
|
||||
@@ -2884,14 +3056,11 @@ Details
|
||||
https://github.com/restic/restic/pull/2978
|
||||
|
||||
|
||||
Changelog for restic 0.10.0 (2020-09-19)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.10.0 (2020-09-19)
|
||||
The following sections list the changes in restic 0.10.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1863: Report correct number of directories processed by backup
|
||||
* Fix #2254: Fix tar issues when dumping `/`
|
||||
@@ -2938,8 +3107,7 @@ Summary
|
||||
* Enh #2840: Speed-up file deletion in forget, prune and rebuild-index
|
||||
* Enh #2858: Support filtering snapshots by tag and path in the stats command
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1863: Report correct number of directories processed by backup
|
||||
|
||||
@@ -3348,14 +3516,11 @@ Details
|
||||
https://forum.restic.net/t/stats-for-a-host-and-filtered-snapshots/3020
|
||||
|
||||
|
||||
Changelog for restic 0.9.6 (2019-11-22)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.9.6 (2019-11-22)
|
||||
The following sections list the changes in restic 0.9.6 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #2063: Allow absolute path for filename when backing up from stdin
|
||||
* Fix #2174: Save files with invalid timestamps
|
||||
@@ -3367,8 +3532,7 @@ Summary
|
||||
* Enh #2330: Make `--group-by` accept both singular and plural
|
||||
* Enh #2350: Add option to configure S3 region
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #2063: Allow absolute path for filename when backing up from stdin
|
||||
|
||||
@@ -3451,14 +3615,11 @@ Details
|
||||
https://github.com/restic/restic/pull/2350
|
||||
|
||||
|
||||
Changelog for restic 0.9.5 (2019-04-23)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.9.5 (2019-04-23)
|
||||
The following sections list the changes in restic 0.9.5 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #2135: Return error when no bytes could be read from stdin
|
||||
* Fix #2181: Don't cancel timeout after 30 seconds for self-update
|
||||
@@ -3474,8 +3635,7 @@ Summary
|
||||
* Enh #2205: Add --ignore-inode option to backup cmd
|
||||
* Enh #2220: Add config option to set S3 storage class
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #2135: Return error when no bytes could be read from stdin
|
||||
|
||||
@@ -3593,14 +3753,11 @@ Details
|
||||
https://github.com/restic/restic/pull/2220
|
||||
|
||||
|
||||
Changelog for restic 0.9.4 (2019-01-06)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.9.4 (2019-01-06)
|
||||
The following sections list the changes in restic 0.9.4 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1989: Google Cloud Storage: Respect bandwidth limit
|
||||
* Fix #2040: Add host name filter shorthand flag for `stats` command
|
||||
@@ -3614,8 +3771,7 @@ Summary
|
||||
* Enh #2094: Run command to get password
|
||||
* Enh #2097: Add key hinting
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1989: Google Cloud Storage: Respect bandwidth limit
|
||||
|
||||
@@ -3721,14 +3877,11 @@ Details
|
||||
https://github.com/restic/restic/issues/2097
|
||||
|
||||
|
||||
Changelog for restic 0.9.3 (2018-10-13)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.9.3 (2018-10-13)
|
||||
The following sections list the changes in restic 0.9.3 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1935: Remove truncated files from cache
|
||||
* Fix #1978: Do not return an error when the scanner is slower than backup
|
||||
@@ -3745,8 +3898,7 @@ Summary
|
||||
* Enh #1967: Use `--host` everywhere
|
||||
* Enh #2028: Display size of cache directories
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1935: Remove truncated files from cache
|
||||
|
||||
@@ -3892,14 +4044,11 @@ Details
|
||||
https://github.com/restic/restic/pull/2033
|
||||
|
||||
|
||||
Changelog for restic 0.9.2 (2018-08-06)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.9.2 (2018-08-06)
|
||||
The following sections list the changes in restic 0.9.2 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1854: Allow saving files/dirs on different fs with `--one-file-system`
|
||||
* Fix #1861: Fix case-insensitive search with restic find
|
||||
@@ -3913,8 +4062,7 @@ Summary
|
||||
* Enh #1901: Update the Backblaze B2 library
|
||||
* Enh #1906: Add support for B2 application keys
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1854: Allow saving files/dirs on different fs with `--one-file-system`
|
||||
|
||||
@@ -4014,14 +4162,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1914
|
||||
|
||||
|
||||
Changelog for restic 0.9.1 (2018-06-10)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.9.1 (2018-06-10)
|
||||
The following sections list the changes in restic 0.9.1 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1801: Add limiting bandwidth to the rclone backend
|
||||
* Fix #1822: Allow uploading large files to MS Azure
|
||||
@@ -4029,8 +4174,7 @@ Summary
|
||||
* Fix #1833: Fix caching files on error
|
||||
* Fix #1834: Resolve deadlock
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1801: Add limiting bandwidth to the rclone backend
|
||||
|
||||
@@ -4081,14 +4225,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1835
|
||||
|
||||
|
||||
Changelog for restic 0.9.0 (2018-05-21)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.9.0 (2018-05-21)
|
||||
The following sections list the changes in restic 0.9.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1608: Respect time stamp for new backup when reading from stdin
|
||||
* Fix #1652: Ignore/remove invalid lock files
|
||||
@@ -4110,8 +4251,7 @@ Summary
|
||||
* Enh #1758: Allow saving OneDrive folders in Windows
|
||||
* Enh #1782: Use default AWS credentials chain for S3 backend
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1608: Respect time stamp for new backup when reading from stdin
|
||||
|
||||
@@ -4333,14 +4473,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1782
|
||||
|
||||
|
||||
Changelog for restic 0.8.3 (2018-02-26)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.8.3 (2018-02-26)
|
||||
The following sections list the changes in restic 0.8.3 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1633: Fixed unexpected 'pack file cannot be listed' error
|
||||
* Fix #1638: Handle errors listing files in the backend
|
||||
@@ -4350,8 +4487,7 @@ Summary
|
||||
* Enh #1623: Don't check for presence of files in the backend before writing
|
||||
* Enh #1634: Upgrade B2 client library, reduce HTTP requests
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1633: Fixed unexpected 'pack file cannot be listed' error
|
||||
|
||||
@@ -4421,14 +4557,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1634
|
||||
|
||||
|
||||
Changelog for restic 0.8.2 (2018-02-17)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.8.2 (2018-02-17)
|
||||
The following sections list the changes in restic 0.8.2 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1506: Limit bandwith at the http.RoundTripper for HTTP based backends
|
||||
* Fix #1512: Restore directory permissions as the last step
|
||||
@@ -4448,8 +4581,7 @@ Summary
|
||||
* Enh #1579: Retry Backend.List() in case of errors
|
||||
* Enh #1584: Limit index file size
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1506: Limit bandwith at the http.RoundTripper for HTTP based backends
|
||||
|
||||
@@ -4594,14 +4726,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1584
|
||||
|
||||
|
||||
Changelog for restic 0.8.1 (2017-12-27)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.8.1 (2017-12-27)
|
||||
The following sections list the changes in restic 0.8.1 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1454: Correct cache dir location for Windows and Darwin
|
||||
* Fix #1457: Improve s3 backend with DigitalOcean Spaces
|
||||
@@ -4611,8 +4740,7 @@ Summary
|
||||
* Enh #1436: Add code to detect old cache directories
|
||||
* Enh #1439: Improve cancellation logic
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1454: Correct cache dir location for Windows and Darwin
|
||||
|
||||
@@ -4670,14 +4798,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1439
|
||||
|
||||
|
||||
Changelog for restic 0.8.0 (2017-11-26)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.8.0 (2017-11-26)
|
||||
The following sections list the changes in restic 0.8.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Sec #1445: Prevent writing outside the target directory during restore
|
||||
* Fix #1256: Re-enable workaround for S3 backend
|
||||
@@ -4699,8 +4824,7 @@ Summary
|
||||
* Enh #1353: Retry failed backend requests
|
||||
* Enh #1367: Allow comments in files read from via `--file-from`
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Security #1445: Prevent writing outside the target directory during restore
|
||||
|
||||
@@ -4878,19 +5002,15 @@ Details
|
||||
https://github.com/restic/restic/pull/1368
|
||||
|
||||
|
||||
Changelog for restic 0.7.3 (2017-09-20)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.7.3 (2017-09-20)
|
||||
The following sections list the changes in restic 0.7.3 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1246: List all files stored in Google Cloud Storage
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1246: List all files stored in Google Cloud Storage
|
||||
|
||||
@@ -4902,14 +5022,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1247
|
||||
|
||||
|
||||
Changelog for restic 0.7.2 (2017-09-13)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.7.2 (2017-09-13)
|
||||
The following sections list the changes in restic 0.7.2 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1164: Make the `key remove` command behave as documented
|
||||
* Fix #1167: Do not create a local repo unless `init` is used
|
||||
@@ -4929,8 +5046,7 @@ Summary
|
||||
* Enh #1205: Allow specifying time/date for a backup with `--time`
|
||||
* Enh #1218: Add `--compact` to `snapshots` command
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1164: Make the `key remove` command behave as documented
|
||||
|
||||
@@ -5038,14 +5154,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1223
|
||||
|
||||
|
||||
Changelog for restic 0.7.1 (2017-07-22)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.7.1 (2017-07-22)
|
||||
The following sections list the changes in restic 0.7.1 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #1115: Fix `prune`, only include existing files in indexes
|
||||
* Enh #1055: Create subdirs below `data/` for local/sftp backends
|
||||
@@ -5055,8 +5168,7 @@ Summary
|
||||
* Enh #1081: Clarify semantic for `--tag` for the `forget` command
|
||||
* Enh #1082: Print stats on SIGINFO on Darwin and FreeBSD (ctrl+t)
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #1115: Fix `prune`, only include existing files in indexes
|
||||
|
||||
@@ -5110,14 +5222,11 @@ Details
|
||||
https://github.com/restic/restic/pull/1082
|
||||
|
||||
|
||||
Changelog for restic 0.7.0 (2017-07-01)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.7.0 (2017-07-01)
|
||||
The following sections list the changes in restic 0.7.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Fix #965: Switch to `default` repo layout for the s3 backend
|
||||
* Fix #1013: Switch back to using the high-level minio-go API for s3
|
||||
@@ -5129,8 +5238,7 @@ Summary
|
||||
* Enh #1021: Detect invalid backend name and print error
|
||||
* Enh #1029: Remove invalid pack files when `prune` is run
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Bugfix #965: Switch to `default` repo layout for the s3 backend
|
||||
|
||||
@@ -5201,21 +5309,17 @@ Details
|
||||
https://github.com/restic/restic/pull/1036
|
||||
|
||||
|
||||
Changelog for restic 0.6.1 (2017-06-01)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.6.1 (2017-06-01)
|
||||
The following sections list the changes in restic 0.6.1 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Enh #974: Remove regular status reports
|
||||
* Enh #981: Remove temporary path from binary in `build.go`
|
||||
* Enh #985: Allow multiple parallel idle HTTP connections
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Enhancement #974: Remove regular status reports
|
||||
|
||||
@@ -5242,21 +5346,17 @@ Details
|
||||
https://github.com/restic/restic/pull/986
|
||||
|
||||
|
||||
Changelog for restic 0.6.0 (2017-05-29)
|
||||
=======================================
|
||||
|
||||
# Changelog for restic 0.6.0 (2017-05-29)
|
||||
The following sections list the changes in restic 0.6.0 relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
|
||||
* Enh #957: Make `forget` consistent
|
||||
* Enh #962: Improve memory and runtime for the s3 backend
|
||||
* Enh #966: Unify repository layout for all backends
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
|
||||
* Enhancement #957: Make `forget` consistent
|
||||
|
||||
@@ -5292,5 +5392,3 @@ Details
|
||||
|
||||
https://github.com/restic/restic/issues/965
|
||||
https://github.com/restic/restic/pull/966
|
||||
|
||||
|
||||
|
@@ -3,7 +3,7 @@ Enhancement: Allow limiting IO concurrency for local and SFTP backend
|
||||
Restic did not support limiting the IO concurrency / number of connections for
|
||||
accessing repositories stored using the local or SFTP backends. The number of
|
||||
connections is now limited as for other backends, and can be configured via the
|
||||
the `-o local.connections=2` and `-o sftp.connections=5` options. This ensures
|
||||
that restic does not overwhelm the backend with concurrent IO operations.
|
||||
`-o local.connections=2` and `-o sftp.connections=5` options. This ensures that
|
||||
restic does not overwhelm the backend with concurrent IO operations.
|
||||
|
||||
https://github.com/restic/restic/pull/3475
|
||||
|
9
changelog/0.16.2_2023-10-29/issue-4540
Normal file
9
changelog/0.16.2_2023-10-29/issue-4540
Normal file
@@ -0,0 +1,9 @@
|
||||
Bugfix: Restore ARMv5 support for ARM binaries
|
||||
|
||||
The official release binaries for restic 0.16.1 were accidentally built to
|
||||
require ARMv7. The build process is now updated to restore support for ARMv5.
|
||||
|
||||
Please note that restic 0.17.0 will drop support for ARMv5 and require at least
|
||||
ARMv6.
|
||||
|
||||
https://github.com/restic/restic/issues/4540
|
8
changelog/0.16.2_2023-10-29/pull-4545
Normal file
8
changelog/0.16.2_2023-10-29/pull-4545
Normal file
@@ -0,0 +1,8 @@
|
||||
Bugfix: Repair documentation build on Read the Docs
|
||||
|
||||
For restic 0.16.1, no documentation was available at
|
||||
https://restic.readthedocs.io/ .
|
||||
|
||||
The documentation build process is now updated to work again.
|
||||
|
||||
https://github.com/restic/restic/pull/4545
|
14
changelog/0.16.3_2024-01-14/issue-4560
Normal file
14
changelog/0.16.3_2024-01-14/issue-4560
Normal file
@@ -0,0 +1,14 @@
|
||||
Bugfix: Improve errors for irregular files on Windows
|
||||
|
||||
Since Go 1.21, most filesystem reparse points on Windows are considered to be
|
||||
irregular files. This caused restic to show an `error: invalid node type ""`
|
||||
error message for those files.
|
||||
|
||||
This error message has now been improved and includes the relevant file path:
|
||||
`error: nodeFromFileInfo path/to/file: unsupported file type "irregular"`.
|
||||
As irregular files are not required to behave like regular files, it is not
|
||||
possible to provide a generic way to back up those files.
|
||||
|
||||
https://github.com/restic/restic/issues/4560
|
||||
https://github.com/restic/restic/pull/4620
|
||||
https://forum.restic.net/t/windows-backup-error-invalid-node-type/6875
|
11
changelog/0.16.3_2024-01-14/issue-4574
Normal file
11
changelog/0.16.3_2024-01-14/issue-4574
Normal file
@@ -0,0 +1,11 @@
|
||||
Bugfix: Support backup of deduplicated files on Windows again
|
||||
|
||||
With the official release builds of restic 0.16.1 and 0.16.2, it was not
|
||||
possible to back up files that were deduplicated by the corresponding
|
||||
Windows Server feature. This also applied to restic versions built using
|
||||
Go 1.21.0-1.21.4.
|
||||
|
||||
The Go version used to build restic has now been updated to fix this.
|
||||
|
||||
https://github.com/restic/restic/issues/4574
|
||||
https://github.com/restic/restic/pull/4621
|
11
changelog/0.16.3_2024-01-14/issue-4612
Normal file
11
changelog/0.16.3_2024-01-14/issue-4612
Normal file
@@ -0,0 +1,11 @@
|
||||
Bugfix: Improve error handling for `rclone` backend
|
||||
|
||||
Since restic 0.16.0, if rclone encountered an error while listing files,
|
||||
this could in rare circumstances cause restic to assume that there are no
|
||||
files. Although unlikely, this situation could result in data loss if it
|
||||
were to happen right when the `prune` command is listing existing snapshots.
|
||||
|
||||
Error handling has now been improved to detect and work around this case.
|
||||
|
||||
https://github.com/restic/restic/issues/4612
|
||||
https://github.com/restic/restic/pull/4618
|
11
changelog/0.16.3_2024-01-14/pull-4624
Normal file
11
changelog/0.16.3_2024-01-14/pull-4624
Normal file
@@ -0,0 +1,11 @@
|
||||
Bugfix: Correct `restore` progress information if an error occurs
|
||||
|
||||
If an error occurred while restoring a snapshot, this could cause the `restore`
|
||||
progress bar to show incorrect information. In addition, if a data file could
|
||||
not be loaded completely, then errors would also be reported for some already
|
||||
restored files.
|
||||
|
||||
Error reporting of the `restore` command has now been made more accurate.
|
||||
|
||||
https://github.com/restic/restic/pull/4624
|
||||
https://forum.restic.net/t/errors-restoring-with-restic-on-windows-server-s3/6943
|
11
changelog/0.16.3_2024-01-14/pull-4626
Normal file
11
changelog/0.16.3_2024-01-14/pull-4626
Normal file
@@ -0,0 +1,11 @@
|
||||
Bugfix: Improve reliability of restoring large files
|
||||
|
||||
In some cases restic failed to restore large files that frequently contain the
|
||||
same file chunk. In combination with certain backends, this could result in
|
||||
network connection timeouts that caused incomplete restores.
|
||||
|
||||
Restic now includes special handling for such file chunks to ensure reliable
|
||||
restores.
|
||||
|
||||
https://github.com/restic/restic/pull/4626
|
||||
https://forum.restic.net/t/errors-restoring-with-restic-on-windows-server-s3/6943
|
18
changelog/0.16.4_2024-02-04/issue-4529
Normal file
18
changelog/0.16.4_2024-02-04/issue-4529
Normal file
@@ -0,0 +1,18 @@
|
||||
Enhancement: Add extra verification of data integrity before upload
|
||||
|
||||
Hardware issues, or a bug in restic or its dependencies, could previously cause
|
||||
corruption in the files restic created and stored in the repository. Detecting
|
||||
such corruption previously required explicitly running the `check --read-data`
|
||||
or `check --read-data-subset` commands.
|
||||
|
||||
To further ensure data integrity, even in the case of hardware issues or
|
||||
software bugs, restic now performs additional verification of the files about
|
||||
to be uploaded to the repository.
|
||||
|
||||
These extra checks will increase CPU usage during backups. They can therefore,
|
||||
if absolutely necessary, be disabled using the `--no-extra-verify` global
|
||||
option. Please note that this should be combined with more active checking
|
||||
using the previously mentioned check commands.
|
||||
|
||||
https://github.com/restic/restic/issues/4529
|
||||
https://github.com/restic/restic/pull/4681
|
19
changelog/0.16.4_2024-02-04/issue-4677
Normal file
19
changelog/0.16.4_2024-02-04/issue-4677
Normal file
@@ -0,0 +1,19 @@
|
||||
Bugfix: Downgrade zstd library to fix rare data corruption at max. compression
|
||||
|
||||
In restic 0.16.3, backups where the compression level was set to `max` (using
|
||||
`--compression max`) could in rare and very specific circumstances result in
|
||||
data corruption due to a bug in the library used for compressing data. Restic
|
||||
0.16.1 and 0.16.2 were not affected.
|
||||
|
||||
Restic now uses the previous version of the library used to compress data, the
|
||||
same version used by restic 0.16.2. Please note that the `auto` compression
|
||||
level (which restic uses by default) was never affected, and even if you used
|
||||
`max` compression, chances of being affected by this issue are small.
|
||||
|
||||
To check a repository for any corruption, run `restic check --read-data`. This
|
||||
will download and verify the whole repository and can be used at any time to
|
||||
completely verify the integrity of a repository. If the `check` command detects
|
||||
anomalies, follow the suggested steps.
|
||||
|
||||
https://github.com/restic/restic/issues/4677
|
||||
https://github.com/restic/restic/pull/4679
|
6
changelog/0.16.5_2024-07-01/issue-4873
Normal file
6
changelog/0.16.5_2024-07-01/issue-4873
Normal file
@@ -0,0 +1,6 @@
|
||||
Enhancement: Update dependencies
|
||||
|
||||
A few potentially vulnerable dependencies were updated.
|
||||
|
||||
https://github.com/restic/restic/issues/4873
|
||||
https://github.com/restic/restic/pull/4878
|
5
changelog/0.16.5_2024-07-01/pull-4799
Normal file
5
changelog/0.16.5_2024-07-01/pull-4799
Normal file
@@ -0,0 +1,5 @@
|
||||
Enhancement: Add option to force use of Azure CLI credential
|
||||
|
||||
A new environment variable `AZURE_FORCE_CLI_CREDENTIAL=true` allows forcing the use of Azure CLI credential, ignoring other credentials like managed identity.
|
||||
|
||||
https://github.com/restic/restic/pull/4799
|
@@ -1,18 +1,21 @@
|
||||
{{- range $changes := . }}{{ with $changes -}}
|
||||
Changelog for restic {{ .Version }} ({{ .Date }})
|
||||
=======================================
|
||||
# Table of Contents
|
||||
|
||||
{{ range . -}}
|
||||
* [Changelog for {{ .Version }}](#changelog-for-restic-{{ .Version | replace "." ""}}-{{ .Date | lower -}})
|
||||
{{ end -}}
|
||||
|
||||
{{- range $changes := . }}{{ with $changes }}
|
||||
|
||||
# Changelog for restic {{ .Version }} ({{ .Date }})
|
||||
The following sections list the changes in restic {{ .Version }} relevant to
|
||||
restic users. The changes are ordered by importance.
|
||||
|
||||
Summary
|
||||
-------
|
||||
## Summary
|
||||
{{ range $entry := .Entries }}{{ with $entry }}
|
||||
* {{ .TypeShort }} #{{ .PrimaryID }}: {{ .Title }}
|
||||
{{- end }}{{ end }}
|
||||
|
||||
Details
|
||||
-------
|
||||
## Details
|
||||
{{ range $entry := .Entries }}{{ with $entry }}
|
||||
* {{ .Type }} #{{ .PrimaryID }}: {{ .Title }}
|
||||
{{ range $par := .Paragraphs }}
|
||||
@@ -27,6 +30,5 @@ Details
|
||||
{{ range $url := .OtherURLs }}
|
||||
{{ $url -}}
|
||||
{{ end }}
|
||||
{{ end }}{{ end }}
|
||||
|
||||
{{ end }}{{ end -}}
|
||||
{{ end }}{{ end -}}
|
||||
|
@@ -75,7 +75,7 @@ func runInit(ctx context.Context, opts InitOptions, gopts GlobalOptions, args []
|
||||
return err
|
||||
}
|
||||
|
||||
repo, err := ReadRepo(gopts)
|
||||
gopts.Repo, err = ReadRepo(gopts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -87,7 +87,7 @@ func runInit(ctx context.Context, opts InitOptions, gopts GlobalOptions, args []
|
||||
return err
|
||||
}
|
||||
|
||||
be, err := create(ctx, repo, gopts, gopts.extended)
|
||||
be, err := create(ctx, gopts.Repo, gopts, gopts.extended)
|
||||
if err != nil {
|
||||
return errors.Fatalf("create repository at %s failed: %v\n", location.StripPassword(gopts.backends, gopts.Repo), err)
|
||||
}
|
||||
|
@@ -43,7 +43,7 @@ import (
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
var version = "0.16.1"
|
||||
var version = "0.16.5"
|
||||
|
||||
// TimeFormat is the format used for all timestamps printed by restic.
|
||||
const TimeFormat = "2006-01-02 15:04:05"
|
||||
@@ -67,6 +67,7 @@ type GlobalOptions struct {
|
||||
CleanupCache bool
|
||||
Compression repository.CompressionMode
|
||||
PackSize uint
|
||||
NoExtraVerify bool
|
||||
|
||||
backend.TransportOptions
|
||||
limiter.Limits
|
||||
@@ -139,6 +140,7 @@ func init() {
|
||||
f.BoolVar(&globalOptions.InsecureTLS, "insecure-tls", false, "skip TLS certificate verification when connecting to the repository (insecure)")
|
||||
f.BoolVar(&globalOptions.CleanupCache, "cleanup-cache", false, "auto remove old cache directories")
|
||||
f.Var(&globalOptions.Compression, "compression", "compression mode (only available for repository format version 2), one of (auto|off|max) (default: $RESTIC_COMPRESSION)")
|
||||
f.BoolVar(&globalOptions.NoExtraVerify, "no-extra-verify", false, "skip additional verification of data before upload (see documentation)")
|
||||
f.IntVar(&globalOptions.Limits.UploadKb, "limit-upload", 0, "limits uploads to a maximum `rate` in KiB/s. (default: unlimited)")
|
||||
f.IntVar(&globalOptions.Limits.DownloadKb, "limit-download", 0, "limits downloads to a maximum `rate` in KiB/s. (default: unlimited)")
|
||||
f.UintVar(&globalOptions.PackSize, "pack-size", 0, "set target pack `size` in MiB, created pack files may be larger (default: $RESTIC_PACK_SIZE)")
|
||||
@@ -455,6 +457,7 @@ func OpenRepository(ctx context.Context, opts GlobalOptions) (*repository.Reposi
|
||||
s, err := repository.New(be, repository.Options{
|
||||
Compression: opts.Compression,
|
||||
PackSize: opts.PackSize * 1024 * 1024,
|
||||
NoExtraVerify: opts.NoExtraVerify,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Fatal(err.Error())
|
||||
|
@@ -123,9 +123,8 @@ func directoriesContentsDiff(dir1, dir2 string) string {
|
||||
fmt.Fprintf(&out, "+%v\n", b.path)
|
||||
b = nil
|
||||
continue
|
||||
} else {
|
||||
fmt.Fprintf(&out, "%%%v\n", a.path)
|
||||
}
|
||||
fmt.Fprintf(&out, "%%%v\n", a.path)
|
||||
}
|
||||
|
||||
a, b = nil, nil
|
||||
|
@@ -84,6 +84,12 @@ If you are using macOS, you can install restic using the
|
||||
|
||||
$ brew install restic
|
||||
|
||||
On Linux and macOS, you can also install it using `pkgx <https://pkgx.sh/>`__:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pkgx install restic
|
||||
|
||||
You may also install it using `MacPorts <https://www.macports.org/>`__:
|
||||
|
||||
.. code-block:: console
|
||||
|
@@ -331,7 +331,7 @@ Wasabi
|
||||
************
|
||||
|
||||
`Wasabi <https://wasabi.com>`__ is a low cost Amazon S3 conformant object storage provider.
|
||||
Due to it's S3 conformance, Wasabi can be used as a storage provider for a restic repository.
|
||||
Due to its S3 conformance, Wasabi can be used as a storage provider for a restic repository.
|
||||
|
||||
- Create a Wasabi bucket using the `Wasabi Console <https://console.wasabisys.com>`__.
|
||||
- Determine the correct Wasabi service URL for your bucket `here <https://wasabi-support.zendesk.com/hc/en-us/articles/360015106031-What-are-the-service-URLs-for-Wasabi-s-different-regions->`__.
|
||||
@@ -548,9 +548,23 @@ For authentication export one of the following variables:
|
||||
# For SAS
|
||||
$ export AZURE_ACCOUNT_SAS=<SAS_TOKEN>
|
||||
|
||||
Alternatively, if run on Azure, restic will automatically uses service accounts configured
|
||||
For authentication using ``az login`` ensure the user has
|
||||
the minimum permissions of the role assignment ``Storage Blob Data Contributor`` on Azure RBAC
|
||||
for the storage account.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ az login
|
||||
|
||||
Alternatively, if run on Azure, restic will automatically use service accounts configured
|
||||
via the standard environment variables or Workload / Managed Identities.
|
||||
|
||||
To enforce the use of the Azure CLI credential when other credentials are present, set the following environment variable:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ export AZURE_FORCE_CLI_CREDENTIAL=true
|
||||
|
||||
Restic will by default use Azure's global domain ``core.windows.net`` as endpoint suffix.
|
||||
You can specify other suffixes as follows:
|
||||
|
||||
@@ -822,7 +836,7 @@ To make this work we can employ the help of the ``setgid`` permission bit
|
||||
available on Linux and most other Unix systems. This permission bit makes
|
||||
newly created directories inherit both the group owner (gid) and setgid bit
|
||||
from the parent directory. Setting this bit requires root but since it
|
||||
propagates down to any new directories we only have to do this priviledged
|
||||
propagates down to any new directories we only have to do this privileged
|
||||
setup once:
|
||||
|
||||
.. code-block:: console
|
||||
|
@@ -146,7 +146,7 @@ change detection rule based on file metadata to determine whether a file is
|
||||
likely unchanged since a previous backup. If it is, the file is not scanned
|
||||
again.
|
||||
|
||||
The previous backup snapshot, called "parent" snaphot in restic terminology,
|
||||
The previous backup snapshot, called "parent" snapshot in restic terminology,
|
||||
is determined as follows. By default restic groups snapshots by hostname and
|
||||
backup paths, and then selects the latest snapshot in the group that matches
|
||||
the current backup. You can change the selection criteria using the
|
||||
@@ -597,6 +597,7 @@ environment variables. The following lists these environment variables:
|
||||
AZURE_ACCOUNT_KEY Account key for Azure
|
||||
AZURE_ACCOUNT_SAS Shared access signatures (SAS) for Azure
|
||||
AZURE_ENDPOINT_SUFFIX Endpoint suffix for Azure Storage (default: core.windows.net)
|
||||
AZURE_FORCE_CLI_CREDENTIAL Force the use of Azure CLI credentials for authentication
|
||||
|
||||
B2_ACCOUNT_ID Account ID or applicationKeyId for Backblaze B2
|
||||
B2_ACCOUNT_KEY Account Key or applicationKey for Backblaze B2
|
||||
|
@@ -120,7 +120,7 @@ be skipped by later copy runs.
|
||||
The source repository is specified with ``--from-repo`` or can be read
|
||||
from a file specified via ``--from-repository-file``. Both of these options
|
||||
can also be set as environment variables ``$RESTIC_FROM_REPOSITORY`` or
|
||||
``$RESTIC_FROM_REPOSITORY_FILE``, respectively. For the destination repository
|
||||
``$RESTIC_FROM_REPOSITORY_FILE``, respectively. For the source repository
|
||||
the password can be read from a file ``--from-password-file`` or from a command
|
||||
``--from-password-command``.
|
||||
Alternatively the environment variables ``$RESTIC_FROM_PASSWORD_COMMAND`` and
|
||||
@@ -337,7 +337,7 @@ over 5 separate invocations:
|
||||
$ restic -r /srv/restic-repo check --read-data-subset=4/5
|
||||
$ restic -r /srv/restic-repo check --read-data-subset=5/5
|
||||
|
||||
Use ``--read-data-subset=x%`` to check a randomly choosen subset of the
|
||||
Use ``--read-data-subset=x%`` to check a randomly chosen subset of the
|
||||
repository pack files. It takes one parameter, ``x``, the percentage of
|
||||
pack files to check as an integer or floating point number. This will not
|
||||
guarantee to cover all available pack files after sufficient runs, but it is
|
||||
|
@@ -60,6 +60,20 @@ only applied for the single run of restic. The option can also be set via the en
|
||||
variable ``RESTIC_COMPRESSION``.
|
||||
|
||||
|
||||
Data Verification
|
||||
=================
|
||||
|
||||
To prevent the upload of corrupted data to the repository, which can happen due
|
||||
to hardware issues or software bugs, restic verifies that generated files can
|
||||
be decoded and contain the correct data beforehand. This increases the CPU usage
|
||||
during backups. If necessary, you can disable this verification using the
|
||||
``--no-extra-verify`` option of the ``backup`` command. However, in this case
|
||||
you should verify the repository integrity more actively using
|
||||
``restic check --read-data`` (or the similar ``--read-data-subset`` option).
|
||||
Otherwise, data corruption due to hardware issues or software bugs might go
|
||||
unnoticed.
|
||||
|
||||
|
||||
File Read Concurrency
|
||||
=====================
|
||||
|
||||
|
@@ -106,7 +106,7 @@ Restic supports storage and preservation of hard links. However, since
|
||||
hard links exist in the scope of a filesystem by definition, restoring
|
||||
hard links from a fuse mount should be done by a program that preserves
|
||||
hard links. A program that does so is ``rsync``, used with the option
|
||||
--hard-links.
|
||||
``--hard-links``.
|
||||
|
||||
.. note:: ``restic mount`` is mostly useful if you want to restore just a few
|
||||
files out of a snapshot, or to check which files are contained in a snapshot.
|
||||
|
@@ -207,10 +207,13 @@ The ``forget`` command accepts the following policy options:
|
||||
They also only count hours/days/weeks/etc which have one or more snapshots.
|
||||
A value of ``-1`` will be interpreted as "forever", i.e. "keep all".
|
||||
|
||||
.. note:: All duration related options (``--keep-{within,-*}``) ignore snapshots
|
||||
.. note:: All duration related options (``--keep-{within-,}*``) ignore snapshots
|
||||
with a timestamp in the future (relative to when the ``forget`` command is
|
||||
run) and these snapshots will hence not be removed.
|
||||
|
||||
.. note:: If there are not enough snapshots to keep one for each duration related
|
||||
``--keep-{within-,}*`` option, the oldest snapshot is kept additionally.
|
||||
|
||||
.. note:: Specifying ``--keep-tag ''`` will match untagged snapshots only.
|
||||
|
||||
When ``forget`` is run with a policy, restic first loads the list of all snapshots
|
||||
|
@@ -556,7 +556,7 @@ The snapshots command returns a single JSON object, an array with objects of the
|
||||
stats
|
||||
-----
|
||||
|
||||
The snapshots command returns a single JSON object.
|
||||
The stats command returns a single JSON object.
|
||||
|
||||
+------------------------------+-----------------------------------------------------+
|
||||
| ``total_size`` | Repository size in bytes |
|
||||
|
@@ -488,6 +488,7 @@ _restic_backup()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -560,6 +561,7 @@ _restic_cache()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -624,6 +626,7 @@ _restic_cat()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -696,6 +699,7 @@ _restic_check()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -794,6 +798,7 @@ _restic_copy()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -860,6 +865,7 @@ _restic_diff()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -944,6 +950,7 @@ _restic_dump()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1058,6 +1065,7 @@ _restic_find()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1228,6 +1236,7 @@ _restic_forget()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1312,6 +1321,7 @@ _restic_generate()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1372,6 +1382,7 @@ _restic_help()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1463,6 +1474,7 @@ _restic_init()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1539,6 +1551,7 @@ _restic_key()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1603,6 +1616,7 @@ _restic_list()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1689,6 +1703,7 @@ _restic_ls()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1757,6 +1772,7 @@ _restic_migrate()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1849,6 +1865,7 @@ _restic_mount()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1935,6 +1952,7 @@ _restic_prune()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -1999,6 +2017,7 @@ _restic_recover()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2059,6 +2078,7 @@ _restic_repair_help()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2126,6 +2146,7 @@ _restic_repair_index()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2190,6 +2211,7 @@ _restic_repair_packs()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2274,6 +2296,7 @@ _restic_repair_snapshots()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2342,6 +2365,7 @@ _restic_repair()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2450,6 +2474,7 @@ _restic_restore()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2552,6 +2577,7 @@ _restic_rewrite()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2620,6 +2646,7 @@ _restic_self-update()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2712,6 +2739,7 @@ _restic_snapshots()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2794,6 +2822,7 @@ _restic_stats()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2884,6 +2913,7 @@ _restic_tag()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -2950,6 +2980,7 @@ _restic_unlock()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -3014,6 +3045,7 @@ _restic_version()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
@@ -3106,6 +3138,7 @@ _restic_root_command()
|
||||
flags+=("--limit-upload=")
|
||||
two_word_flags+=("--limit-upload")
|
||||
flags+=("--no-cache")
|
||||
flags+=("--no-extra-verify")
|
||||
flags+=("--no-lock")
|
||||
flags+=("--option=")
|
||||
two_word_flags+=("--option")
|
||||
|
30
doc/conf.py
30
doc/conf.py
@@ -12,14 +12,16 @@
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
import os
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = ['sphinx.ext.extlinks']
|
||||
extensions = [
|
||||
'sphinx.ext.extlinks',
|
||||
'sphinx_rtd_theme',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -35,7 +37,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = 'restic'
|
||||
copyright = '2018, restic authors'
|
||||
copyright = '2023, restic authors'
|
||||
author = 'fd0'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
@@ -54,7 +56,7 @@ release = version
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
language = "en"
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
@@ -72,21 +74,11 @@ todo_include_todos = False
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
if os.environ.get('READTHEDOCS') == 'True':
|
||||
html_context = {
|
||||
'css_files': [
|
||||
'https://media.readthedocs.org/css/sphinx_rtd_theme.css',
|
||||
'https://media.readthedocs.org/css/readthedocs-doc-embed.css',
|
||||
'_static/css/restic.css',
|
||||
]
|
||||
}
|
||||
else:
|
||||
# we're not built by rtd => add rtd-theme
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
html_style = 'css/restic.css'
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
html_css_files = [
|
||||
'css/restic.css',
|
||||
]
|
||||
|
||||
html_logo = 'logo/logo.png'
|
||||
|
||||
|
@@ -171,6 +171,10 @@ Exit status is 3 if some source data could not be read (incomplete snapshot crea
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -80,6 +80,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -68,6 +68,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -85,6 +85,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -109,6 +109,10 @@ new destination repository using the "init" command.
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -93,6 +93,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -96,6 +96,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -117,6 +117,10 @@ It can also be used to search for restic blobs or trees for troubleshooting.
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -179,6 +179,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -89,6 +89,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -96,6 +96,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -80,6 +80,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -68,6 +68,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -107,6 +107,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -74,6 +74,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -144,6 +144,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -97,6 +97,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -70,6 +70,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -73,6 +73,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -72,6 +72,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -107,6 +107,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -63,6 +63,10 @@ Repair the repository
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -117,6 +117,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -121,6 +121,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -75,6 +75,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -92,6 +92,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -114,6 +114,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -99,6 +99,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -72,6 +72,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -69,6 +69,10 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -65,6 +65,10 @@ The full documentation can be found at https://restic.readthedocs.io/ .
|
||||
\fB--no-cache\fP[=false]
|
||||
do not use a local cache
|
||||
|
||||
.PP
|
||||
\fB--no-extra-verify\fP[=false]
|
||||
skip additional verification of data before upload (see documentation)
|
||||
|
||||
.PP
|
||||
\fB--no-lock\fP[=false]
|
||||
do not lock the repository, this allows some operations on read-only repositories
|
||||
|
@@ -148,11 +148,11 @@ command:
|
||||
-v, --verbose be verbose (specify multiple times or a level using --verbose=n, max level/times is 2)
|
||||
|
||||
Subcommands that support showing progress information such as ``backup``,
|
||||
``check`` and ``prune`` will do so unless the quiet flag ``-q`` or
|
||||
``--quiet`` is set. When running from a non-interactive console progress
|
||||
reporting is disabled by default to not fill your logs. For interactive
|
||||
and non-interactive consoles the environment variable ``RESTIC_PROGRESS_FPS``
|
||||
can be used to control the frequency of progress reporting. Use for example
|
||||
``restore``, ``check`` and ``prune`` will do so unless the quiet flag ``-q``
|
||||
or ``--quiet`` is set. When running from a non-interactive console progress
|
||||
reporting is disabled by default to not fill your logs. For interactive and
|
||||
non-interactive consoles the environment variable ``RESTIC_PROGRESS_FPS`` can
|
||||
be used to control the frequency of progress reporting. Use for example
|
||||
``0.016666`` to only update the progress once per minute.
|
||||
|
||||
Additionally, on Unix systems if ``restic`` receives a SIGUSR1 signal the
|
||||
|
78
go.mod
78
go.mod
@@ -1,9 +1,9 @@
|
||||
module github.com/restic/restic
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.33.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0
|
||||
cloud.google.com/go/storage v1.41.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0
|
||||
github.com/Backblaze/blazer v0.6.1
|
||||
github.com/anacrolix/fuse v0.2.0
|
||||
@@ -13,8 +13,8 @@ require (
|
||||
github.com/go-ole/go-ole v1.3.0
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7
|
||||
github.com/klauspost/compress v1.17.2
|
||||
github.com/minio/minio-go/v7 v7.0.63
|
||||
github.com/klauspost/compress v1.17.4
|
||||
github.com/minio/minio-go/v7 v7.0.66
|
||||
github.com/minio/sha256-simd v1.0.1
|
||||
github.com/ncw/swift/v2 v2.0.2
|
||||
github.com/pkg/errors v0.9.1
|
||||
@@ -25,56 +25,64 @@ require (
|
||||
github.com/spf13/cobra v1.7.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
golang.org/x/crypto v0.14.0
|
||||
golang.org/x/net v0.17.0
|
||||
golang.org/x/oauth2 v0.13.0
|
||||
golang.org/x/sync v0.4.0
|
||||
golang.org/x/sys v0.13.0
|
||||
golang.org/x/term v0.13.0
|
||||
golang.org/x/text v0.13.0
|
||||
golang.org/x/time v0.3.0
|
||||
google.golang.org/api v0.148.0
|
||||
golang.org/x/crypto v0.24.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/oauth2 v0.20.0
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/sys v0.21.0
|
||||
golang.org/x/term v0.21.0
|
||||
golang.org/x/text v0.16.0
|
||||
golang.org/x/time v0.5.0
|
||||
google.golang.org/api v0.182.0
|
||||
)
|
||||
|
||||
replace github.com/klauspost/compress => github.com/klauspost/compress v1.17.2
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.9 // indirect
|
||||
cloud.google.com/go/compute v1.23.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.3 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 // indirect
|
||||
cloud.google.com/go v0.114.0 // indirect
|
||||
cloud.google.com/go/auth v0.4.2 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
cloud.google.com/go/iam v1.1.8 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/felixge/fgprof v0.9.3 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.4 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/rs/xid v1.5.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect
|
||||
google.golang.org/grpc v1.64.0 // indirect
|
||||
google.golang.org/protobuf v1.34.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
167
go.sum
167
go.sum
@@ -1,25 +1,27 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.110.9 h1:e7ITSqGFFk4rbz/JFIqZh3G4VEHguhAL4BQcFlWtU68=
|
||||
cloud.google.com/go v0.110.9/go.mod h1:rpxevX/0Lqvlbc88b7Sc1SPNdyK1riNBTUU6JXhYNpM=
|
||||
cloud.google.com/go/compute v1.23.1 h1:V97tBoDaZHb6leicZ1G6DLK2BAaZLJ/7+9BB/En3hR0=
|
||||
cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/iam v1.1.3 h1:18tKG7DzydKWUnLjonWcJO6wjSCAtzh4GcRKlH/Hrzc=
|
||||
cloud.google.com/go/iam v1.1.3/go.mod h1:3khUlaBXfPKKe7huYgEpDn6FtgRyMEqbkvBxrQyY5SE=
|
||||
cloud.google.com/go/storage v1.33.0 h1:PVrDOkIC8qQVa1P3SXGpQvfuJhN2LHOoyZvWs8D2X5M=
|
||||
cloud.google.com/go/storage v1.33.0/go.mod h1:Hhh/dogNRGca7IWv1RC2YqEn0c0G77ctA/OxflYkiD8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0 h1:9kDVnTz3vbfweTqAUmk/a/pH5pWFCHtvRpHYC0G/dcA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.8.0/go.mod h1:3Ug6Qzto9anB6mGlEdgYMDF5zHQ+wwhEaYR4s17PHMw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0 h1:TuEMD+E+1aTjjLICGQOW6vLe8UWES7kopac9mUXL56Y=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI=
|
||||
cloud.google.com/go v0.114.0 h1:OIPFAdfrFDFO2ve2U7r/H5SwSbBzEdrBdE7xkgwc+kY=
|
||||
cloud.google.com/go v0.114.0/go.mod h1:ZV9La5YYxctro1HTPug5lXH/GefROyW8PPD4T8n9J8E=
|
||||
cloud.google.com/go/auth v0.4.2 h1:sb0eyLkhRtpq5jA+a8KWw0W70YcdVca7KJ8TM0AFYDg=
|
||||
cloud.google.com/go/auth v0.4.2/go.mod h1:Kqvlz1cf1sNA0D+sYJnkPQOP+JMHkuHeIgVmCRtZOLc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0=
|
||||
cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE=
|
||||
cloud.google.com/go/storage v1.41.0 h1:RusiwatSu6lHeEXe3kglxakAmAbfV+rhtPqA6i8RBx0=
|
||||
cloud.google.com/go/storage v1.41.0/go.mod h1:J1WCa/Z2FcgdEDuPUY8DxT5I+d9mFKsCepp5vR6Sq80=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0 h1:Ma67P/GGprNwsslzEH6+Kb8nybI8jpDTm4Wmzu2ReK8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 h1:gggzg0SUMs6SQbEw+3LoSsYf9YMjkupeAnHMX8O9mmY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 h1:hVeq+yCyUi+MsoO/CU95yqCIcdzra5ovzk8Q2BBpV2M=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/Backblaze/blazer v0.6.1 h1:xC9HyC7OcxRzzmtfRiikIEvq4HZYWjU6caFwX2EXw1s=
|
||||
github.com/Backblaze/blazer v0.6.1/go.mod h1:7/jrGx4O6OKOto6av+hLwelPR8rwZ+PLxQ5ZOiYAjwY=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@@ -39,11 +41,9 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
@@ -56,10 +56,17 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE=
|
||||
github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
@@ -74,33 +81,30 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||
github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc=
|
||||
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
|
||||
github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ=
|
||||
github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.1/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg=
|
||||
github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
@@ -111,19 +115,18 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
||||
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
|
||||
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.63 h1:GbZ2oCvaUdgT5640WJOpyDhhDxvknAJU2/T3yurwcbQ=
|
||||
github.com/minio/minio-go/v7 v7.0.63/go.mod h1:Q6X7Qjb7WMhvG65qKf4gUgA5XaiSox74kR1uAEjxRS4=
|
||||
github.com/minio/minio-go/v7 v7.0.66 h1:bnTOXOHjOqv/gcMuiVbN9o2ngRItvqE774dG9nq0Dzw=
|
||||
github.com/minio/minio-go/v7 v7.0.66/go.mod h1:DHAgmyQEGdW3Cif0UooKOyrT3Vxs82zNdV6tkKhRtbs=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -133,8 +136,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/ncw/swift/v2 v2.0.2 h1:jx282pcAKFhmoZBSdMcCRFn9VWkoBIRsCpe+yZq7vEk=
|
||||
github.com/ncw/swift/v2 v2.0.2/go.mod h1:z0A9RVdYPjNjXVo2pDOPxZ4eu3oarO1P91fTItcb+Kg=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.7.0 h1:hnbDkaNWPCLMO9wGLdBFTIZvzDrDfBM2072E1S9gJkA=
|
||||
@@ -150,6 +153,7 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
|
||||
github.com/restic/chunker v0.4.0 h1:YUPYCUn70MYP7VO4yllypp2SjmsRhRJaad3xKu1QFRw=
|
||||
github.com/restic/chunker v0.4.0/go.mod h1:z0cH2BejpW636LXw0R/BGyv+Ey8+m9QGiOanDHItzyw=
|
||||
github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
@@ -169,13 +173,24 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ=
|
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
|
||||
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -183,8 +198,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -202,18 +217,18 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
|
||||
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
|
||||
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
|
||||
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -221,7 +236,6 @@ golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -229,22 +243,21 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -257,29 +270,26 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
google.golang.org/api v0.148.0 h1:HBq4TZlN4/1pNcu0geJZ/Q50vIwIXT532UIMYoo0vOs=
|
||||
google.golang.org/api v0.148.0/go.mod h1:8/TBgwaKjfqTdacOJrOv2+2Q6fBDU1uHKK06oGSkxzU=
|
||||
google.golang.org/api v0.182.0 h1:if5fPvudRQ78GeRx3RayIoiuV7modtErPIZC/T2bIvE=
|
||||
google.golang.org/api v0.182.0/go.mod h1:cGhjy4caqA5yXRzEhkHI8Y9mfyC2VLTlER2l08xaqtM=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b h1:+YaDE2r2OG8t/z5qmsh7Y+XXwCbvadxxZ0YY6mTdrVA=
|
||||
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:CgAqfJo+Xmu0GwA0411Ht3OU3OntXwsGmrmjI8ioGXI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b h1:CIC2YMXmIhYw6evmhPxBKJ4fmLbOFtXQN/GV3XOZR8k=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:IBQ646DjkDkvUIsVq/cc03FUFQ9wbZu7yE396YcL870=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc=
|
||||
google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw=
|
||||
google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8 h1:W5Xj/70xIA4x60O/IFyXivR5MGqblAb8R3w26pnD6No=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8/go.mod h1:vPrPUTsDCYxXWjP7clS81mZ6/803D8K4iM9Ma27VKas=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e h1:Elxv5MwEkCI9f5SkoL6afed6NTdxaGoAo39eANBwHL8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY=
|
||||
google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -289,15 +299,12 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@@ -125,6 +125,9 @@ func build(sourceDir, outputDir, goos, goarch string) (filename string) {
|
||||
"GOOS="+goos,
|
||||
"GOARCH="+goarch,
|
||||
)
|
||||
if goarch == "arm" {
|
||||
c.Env = append(c.Env, "GOARM=5")
|
||||
}
|
||||
verbose("run %v %v in %v", "go", c.Args, c.Dir)
|
||||
|
||||
err := c.Run()
|
||||
|
@@ -12,6 +12,10 @@ go_version="$2"
|
||||
|
||||
# invalid if zero
|
||||
is_valid=1
|
||||
set_invalid() {
|
||||
echo $1
|
||||
is_valid=0
|
||||
}
|
||||
|
||||
tmpdir="$(mktemp -d -p .)"
|
||||
cd "${tmpdir}"
|
||||
@@ -41,7 +45,7 @@ for i in $(cat SHA256SUMS | cut -d " " -f 3 ) ; do
|
||||
echo "Downloading $i"
|
||||
curl -OLSs https://github.com/restic/restic/releases/download/v${restic_version}/"$i"
|
||||
done
|
||||
shasum -a256 -c SHA256SUMS || echo "WARNING: RELEASE BINARIES DO NOT MATCH SHA256SUMS!" && is_valid=0
|
||||
shasum -a256 -c SHA256SUMS || set_invalid "WARNING: RELEASE BINARIES DO NOT MATCH SHA256SUMS!"
|
||||
gpg --verify restic-${restic_version}.tar.gz.asc restic-${restic_version}.tar.gz
|
||||
# TODO verify that the release does not contain any unexpected files
|
||||
|
||||
@@ -74,9 +78,9 @@ cp "restic-${restic_version}.tar.gz" output
|
||||
cp SHA256SUMS output
|
||||
|
||||
# check that all release binaries have been reproduced successfully
|
||||
(cd output && shasum -a256 -c SHA256SUMS) || echo "WARNING: REPRODUCED BINARIES DO NOT MATCH RELEASE BINARIES!" && is_valid=0
|
||||
(cd output && shasum -a256 -c SHA256SUMS) || set_invalid "WARNING: REPRODUCED BINARIES DO NOT MATCH RELEASE BINARIES!"
|
||||
# and that the SHA256SUMS files does not miss binaries
|
||||
for i in output/restic* ; do grep "$(basename "$i")" SHA256SUMS > /dev/null || echo "WARNING: $i MISSING FROM RELEASE SHA256SUMS FILE!" && is_valid=0 ; done
|
||||
for i in output/restic* ; do grep "$(basename "$i")" SHA256SUMS > /dev/null || set_invalid "WARNING: $i MISSING FROM RELEASE SHA256SUMS FILE!" ; done
|
||||
|
||||
|
||||
extract_docker() {
|
||||
@@ -85,18 +89,18 @@ extract_docker() {
|
||||
restic_platform=$3
|
||||
out=restic_${restic_version}_linux_${restic_platform}.bz2
|
||||
|
||||
# requires at least docker 25.0
|
||||
docker image pull --platform "linux/${docker_platform}" ${image}:${restic_version} > /dev/null
|
||||
docker image save ${image}:${restic_version} -o docker.tar
|
||||
|
||||
mkdir img
|
||||
tar xvf docker.tar -C img --wildcards \*/layer.tar > /dev/null
|
||||
tar xvf docker.tar -C img --wildcards blobs/sha256/\* > /dev/null
|
||||
rm docker.tar
|
||||
for i in img/*/layer.tar; do
|
||||
for i in img/blobs/sha256/*; do
|
||||
tar -xvf "$i" -C img usr/bin/restic 2> /dev/null 1>&2 || true
|
||||
if [[ -f img/usr/bin/restic ]]; then
|
||||
if [[ -f restic-docker ]]; then
|
||||
echo "WARNING: CONTAINER CONTAINS MULTIPLE RESTIC BINARIES"
|
||||
is_valid=0
|
||||
set_invalid "WARNING: CONTAINER CONTAINS MULTIPLE RESTIC BINARIES"
|
||||
fi
|
||||
mv img/usr/bin/restic restic-docker
|
||||
fi
|
||||
@@ -118,7 +122,7 @@ for img in restic/restic ghcr.io/restic/restic; do
|
||||
extract_docker "$img" 386 386
|
||||
extract_docker "$img" amd64 amd64
|
||||
|
||||
(cd docker && shasum -a256 -c SHA256SUMS) || echo "WARNING: DOCKER CONTAINER DOES NOT CONTAIN RELEASE BINARIES!" && is_valid=0
|
||||
(cd docker && shasum -a256 -c SHA256SUMS) || set_invalid "WARNING: DOCKER CONTAINER DOES NOT CONTAIN RELEASE BINARIES!"
|
||||
|
||||
mv docker docker-$(( ctr++ ))
|
||||
done
|
||||
|
@@ -2,10 +2,12 @@ package archiver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/restic/restic/internal/debug"
|
||||
@@ -168,6 +170,11 @@ func (arch *Archiver) error(item string, err error) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// not all errors include the filepath, thus add it if it is missing
|
||||
if !strings.Contains(err.Error(), item) {
|
||||
err = fmt.Errorf("%v: %w", item, err)
|
||||
}
|
||||
|
||||
errf := arch.Error(item, err)
|
||||
if err != errf {
|
||||
debug.Log("item %v: error was filtered by handler, before: %q, after: %v", item, err, errf)
|
||||
@@ -183,7 +190,10 @@ func (arch *Archiver) nodeFromFileInfo(snPath, filename string, fi os.FileInfo)
|
||||
}
|
||||
// overwrite name to match that within the snapshot
|
||||
node.Name = path.Base(snPath)
|
||||
return node, errors.WithStack(err)
|
||||
if err != nil {
|
||||
return node, fmt.Errorf("nodeFromFileInfo %v: %w", filename, err)
|
||||
}
|
||||
return node, err
|
||||
}
|
||||
|
||||
// loadSubtree tries to load the subtree referenced by node. In case of an error, nil is returned.
|
||||
|
@@ -1879,7 +1879,7 @@ func TestArchiverContextCanceled(t *testing.T) {
|
||||
})
|
||||
|
||||
// Ensure that the archiver itself reports the canceled context and not just the backend
|
||||
repo := repository.TestRepositoryWithBackend(t, &noCancelBackend{mem.New()}, 0)
|
||||
repo := repository.TestRepositoryWithBackend(t, &noCancelBackend{mem.New()}, 0, repository.Options{})
|
||||
|
||||
back := restictest.Chdir(t, tempdir)
|
||||
defer back()
|
||||
|
@@ -101,12 +101,22 @@ func open(cfg Config, rt http.RoundTripper) (*Backend, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewAccountSASClientFromEndpointToken")
|
||||
}
|
||||
} else {
|
||||
var cred azcore.TokenCredential
|
||||
|
||||
if cfg.ForceCliCredential {
|
||||
debug.Log(" - using AzureCLICredential")
|
||||
cred, err = azidentity.NewAzureCLICredential(nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewAzureCLICredential")
|
||||
}
|
||||
} else {
|
||||
debug.Log(" - using DefaultAzureCredential")
|
||||
cred, err := azidentity.NewDefaultAzureCredential(nil)
|
||||
cred, err = azidentity.NewDefaultAzureCredential(nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewDefaultAzureCredential")
|
||||
}
|
||||
}
|
||||
|
||||
client, err = azContainer.NewClient(url, cred, opts)
|
||||
if err != nil {
|
||||
|
@@ -3,6 +3,7 @@ package azure
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/restic/restic/internal/errors"
|
||||
@@ -16,6 +17,7 @@ type Config struct {
|
||||
AccountName string
|
||||
AccountSAS options.SecretString
|
||||
AccountKey options.SecretString
|
||||
ForceCliCredential bool
|
||||
EndpointSuffix string
|
||||
Container string
|
||||
Prefix string
|
||||
@@ -73,6 +75,11 @@ func (cfg *Config) ApplyEnvironment(prefix string) {
|
||||
cfg.AccountSAS = options.NewSecretString(os.Getenv(prefix + "AZURE_ACCOUNT_SAS"))
|
||||
}
|
||||
|
||||
var forceCliCred, err = strconv.ParseBool(os.Getenv(prefix + "AZURE_FORCE_CLI_CREDENTIAL"))
|
||||
if err == nil {
|
||||
cfg.ForceCliCredential = forceCliCred
|
||||
}
|
||||
|
||||
if cfg.EndpointSuffix == "" {
|
||||
cfg.EndpointSuffix = os.Getenv(prefix + "AZURE_ENDPOINT_SUFFIX")
|
||||
}
|
||||
|
@@ -328,9 +328,14 @@ func (b *Backend) List(ctx context.Context, t restic.FileType, fn func(restic.Fi
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusNotFound {
|
||||
// ignore missing directories
|
||||
if !strings.HasPrefix(resp.Header.Get("Server"), "rclone/") {
|
||||
// ignore missing directories, unless the server is rclone. rclone
|
||||
// already ignores missing directories, but misuses "not found" to
|
||||
// report certain internal errors, see
|
||||
// https://github.com/rclone/rclone/pull/7550 for details.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return errors.Errorf("List failed, server response: %v (%v)", resp.Status, resp.StatusCode)
|
||||
|
@@ -143,7 +143,7 @@ func (f *openFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.R
|
||||
// the methods being called are responsible for appropriate synchronization.
|
||||
//
|
||||
// However, no lock needed here as getBlobAt can be called conurrently
|
||||
// (blobCache has it's own locking)
|
||||
// (blobCache has its own locking)
|
||||
for i := startContent; remainingBytes > 0 && i < len(f.cumsize)-1; i++ {
|
||||
blob, err := f.getBlobAt(ctx, i)
|
||||
if err != nil {
|
||||
|
@@ -110,9 +110,8 @@ func (d *SnapshotsDir) Lookup(ctx context.Context, name string) (fs.Node, error)
|
||||
return newSnapshotLink(d.root, inode, entry.linkTarget, entry.snapshot)
|
||||
} else if entry.snapshot != nil {
|
||||
return newDirFromSnapshot(d.root, inode, entry.snapshot)
|
||||
} else {
|
||||
return NewSnapshotsDir(d.root, inode, d.inode, d.dirStruct, d.prefix+"/"+name), nil
|
||||
}
|
||||
return NewSnapshotsDir(d.root, inode, d.inode, d.dirStruct, d.prefix+"/"+name), nil
|
||||
}
|
||||
|
||||
return nil, syscall.ENOENT
|
||||
|
@@ -69,7 +69,7 @@ func TestUpgradeRepoV2Failure(t *testing.T) {
|
||||
Backend: be,
|
||||
}
|
||||
|
||||
repo := repository.TestRepositoryWithBackend(t, be, 1)
|
||||
repo := repository.TestRepositoryWithBackend(t, be, 1, repository.Options{})
|
||||
if repo.Config().Version != 1 {
|
||||
t.Fatal("test repo has wrong version")
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package pack
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
@@ -74,7 +75,7 @@ func (p *Packer) Finalize() error {
|
||||
p.m.Lock()
|
||||
defer p.m.Unlock()
|
||||
|
||||
header, err := p.makeHeader()
|
||||
header, err := makeHeader(p.blobs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -83,6 +84,12 @@ func (p *Packer) Finalize() error {
|
||||
nonce := crypto.NewRandomNonce()
|
||||
encryptedHeader = append(encryptedHeader, nonce...)
|
||||
encryptedHeader = p.k.Seal(encryptedHeader, nonce, header, nil)
|
||||
encryptedHeader = binary.LittleEndian.AppendUint32(encryptedHeader, uint32(len(encryptedHeader)))
|
||||
|
||||
if err := verifyHeader(p.k, encryptedHeader, p.blobs); err != nil {
|
||||
//nolint:revive // ignore linter warnings about error message spelling
|
||||
return fmt.Errorf("Detected data corruption while writing pack-file header: %w\nCorrupted data is either caused by hardware issues or software bugs. Please open an issue at https://github.com/restic/restic/issues/new/choose for further troubleshooting.", err)
|
||||
}
|
||||
|
||||
// append the header
|
||||
n, err := p.wr.Write(encryptedHeader)
|
||||
@@ -90,18 +97,33 @@ func (p *Packer) Finalize() error {
|
||||
return errors.Wrap(err, "Write")
|
||||
}
|
||||
|
||||
hdrBytes := len(encryptedHeader)
|
||||
if n != hdrBytes {
|
||||
if n != len(encryptedHeader) {
|
||||
return errors.New("wrong number of bytes written")
|
||||
}
|
||||
p.bytes += uint(len(encryptedHeader))
|
||||
|
||||
// write length
|
||||
err = binary.Write(p.wr, binary.LittleEndian, uint32(hdrBytes))
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifyHeader(k *crypto.Key, header []byte, expected []restic.Blob) error {
|
||||
// do not offer a way to skip the pack header verification, as pack headers are usually small enough
|
||||
// to not result in a significant performance impact
|
||||
|
||||
decoded, hdrSize, err := List(k, bytes.NewReader(header), int64(len(header)))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "binary.Write")
|
||||
return fmt.Errorf("header decoding failed: %w", err)
|
||||
}
|
||||
if hdrSize != uint32(len(header)) {
|
||||
return fmt.Errorf("unexpected header size %v instead of %v", hdrSize, len(header))
|
||||
}
|
||||
if len(decoded) != len(expected) {
|
||||
return fmt.Errorf("pack header size mismatch")
|
||||
}
|
||||
for i := 0; i < len(decoded); i++ {
|
||||
if decoded[i] != expected[i] {
|
||||
return fmt.Errorf("pack header entry mismatch got %v instead of %v", decoded[i], expected[i])
|
||||
}
|
||||
}
|
||||
p.bytes += uint(hdrBytes + binary.Size(uint32(0)))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -111,10 +133,10 @@ func (p *Packer) HeaderOverhead() int {
|
||||
}
|
||||
|
||||
// makeHeader constructs the header for p.
|
||||
func (p *Packer) makeHeader() ([]byte, error) {
|
||||
buf := make([]byte, 0, len(p.blobs)*int(entrySize))
|
||||
func makeHeader(blobs []restic.Blob) ([]byte, error) {
|
||||
buf := make([]byte, 0, len(blobs)*int(entrySize))
|
||||
|
||||
for _, b := range p.blobs {
|
||||
for _, b := range blobs {
|
||||
switch {
|
||||
case b.Type == restic.DataBlob && b.UncompressedLength == 0:
|
||||
buf = append(buf, 0)
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/crypto"
|
||||
@@ -177,3 +178,60 @@ func TestReadRecords(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnpackedVerification(t *testing.T) {
|
||||
// create random keys
|
||||
k := crypto.NewRandomKey()
|
||||
blobs := []restic.Blob{
|
||||
{
|
||||
BlobHandle: restic.NewRandomBlobHandle(),
|
||||
Length: 42,
|
||||
Offset: 0,
|
||||
UncompressedLength: 2 * 42,
|
||||
},
|
||||
}
|
||||
|
||||
type DamageType string
|
||||
const (
|
||||
damageData DamageType = "data"
|
||||
damageCiphertext DamageType = "ciphertext"
|
||||
damageLength DamageType = "length"
|
||||
)
|
||||
|
||||
for _, test := range []struct {
|
||||
damage DamageType
|
||||
msg string
|
||||
}{
|
||||
{"", ""},
|
||||
{damageData, "pack header entry mismatch"},
|
||||
{damageCiphertext, "ciphertext verification failed"},
|
||||
{damageLength, "header decoding failed"},
|
||||
} {
|
||||
header, err := makeHeader(blobs)
|
||||
rtest.OK(t, err)
|
||||
|
||||
if test.damage == damageData {
|
||||
header[8] ^= 0x42
|
||||
}
|
||||
|
||||
encryptedHeader := make([]byte, 0, crypto.CiphertextLength(len(header)))
|
||||
nonce := crypto.NewRandomNonce()
|
||||
encryptedHeader = append(encryptedHeader, nonce...)
|
||||
encryptedHeader = k.Seal(encryptedHeader, nonce, header, nil)
|
||||
encryptedHeader = binary.LittleEndian.AppendUint32(encryptedHeader, uint32(len(encryptedHeader)))
|
||||
|
||||
if test.damage == damageCiphertext {
|
||||
encryptedHeader[8] ^= 0x42
|
||||
}
|
||||
if test.damage == damageLength {
|
||||
encryptedHeader[len(encryptedHeader)-1] ^= 0x42
|
||||
}
|
||||
|
||||
err = verifyHeader(k, encryptedHeader, blobs)
|
||||
if test.msg == "" {
|
||||
rtest.Assert(t, err == nil, "expected no error, got %v", err)
|
||||
} else {
|
||||
rtest.Assert(t, strings.Contains(err.Error(), test.msg), "expected error to contain %q, got %q", test.msg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/backend/mem"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
@@ -19,7 +18,7 @@ func FuzzSaveLoadBlob(f *testing.F) {
|
||||
}
|
||||
|
||||
id := restic.Hash(blob)
|
||||
repo := TestRepositoryWithBackend(t, mem.New(), 2)
|
||||
repo := TestRepositoryWithVersion(t, 2)
|
||||
|
||||
var wg errgroup.Group
|
||||
repo.StartPackUploader(context.TODO(), &wg)
|
||||
|
@@ -346,7 +346,8 @@ func TestRepackWrongBlob(t *testing.T) {
|
||||
}
|
||||
|
||||
func testRepackWrongBlob(t *testing.T, version uint) {
|
||||
repo := repository.TestRepositoryWithVersion(t, version)
|
||||
// disable verification to allow adding corrupted blobs to the repository
|
||||
repo := repository.TestRepositoryWithBackend(t, nil, version, repository.Options{NoExtraVerify: true})
|
||||
|
||||
seed := time.Now().UnixNano()
|
||||
rand.Seed(seed)
|
||||
@@ -371,7 +372,8 @@ func TestRepackBlobFallback(t *testing.T) {
|
||||
}
|
||||
|
||||
func testRepackBlobFallback(t *testing.T, version uint) {
|
||||
repo := repository.TestRepositoryWithVersion(t, version)
|
||||
// disable verification to allow adding corrupted blobs to the repository
|
||||
repo := repository.TestRepositoryWithBackend(t, nil, version, repository.Options{NoExtraVerify: true})
|
||||
|
||||
seed := time.Now().UnixNano()
|
||||
rand.Seed(seed)
|
||||
|
@@ -61,6 +61,7 @@ type Repository struct {
|
||||
type Options struct {
|
||||
Compression CompressionMode
|
||||
PackSize uint
|
||||
NoExtraVerify bool
|
||||
}
|
||||
|
||||
// CompressionMode configures if data should be compressed.
|
||||
@@ -423,6 +424,11 @@ func (r *Repository) saveAndEncrypt(ctx context.Context, t restic.BlobType, data
|
||||
// encrypt blob
|
||||
ciphertext = r.key.Seal(ciphertext, nonce, data, nil)
|
||||
|
||||
if err := r.verifyCiphertext(ciphertext, uncompressedLength, id); err != nil {
|
||||
//nolint:revive // ignore linter warnings about error message spelling
|
||||
return 0, fmt.Errorf("Detected data corruption while saving blob %v: %w\nCorrupted blobs are either caused by hardware issues or software bugs. Please open an issue at https://github.com/restic/restic/issues/new/choose for further troubleshooting.", id, err)
|
||||
}
|
||||
|
||||
// find suitable packer and add blob
|
||||
var pm *packerManager
|
||||
|
||||
@@ -438,6 +444,31 @@ func (r *Repository) saveAndEncrypt(ctx context.Context, t restic.BlobType, data
|
||||
return pm.SaveBlob(ctx, t, id, ciphertext, uncompressedLength)
|
||||
}
|
||||
|
||||
func (r *Repository) verifyCiphertext(buf []byte, uncompressedLength int, id restic.ID) error {
|
||||
if r.opts.NoExtraVerify {
|
||||
return nil
|
||||
}
|
||||
|
||||
nonce, ciphertext := buf[:r.key.NonceSize()], buf[r.key.NonceSize():]
|
||||
plaintext, err := r.key.Open(nil, nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decryption failed: %w", err)
|
||||
}
|
||||
if uncompressedLength != 0 {
|
||||
// DecodeAll will allocate a slice if it is not large enough since it
|
||||
// knows the decompressed size (because we're using EncodeAll)
|
||||
plaintext, err = r.getZstdDecoder().DecodeAll(plaintext, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decompression failed: %w", err)
|
||||
}
|
||||
}
|
||||
if !restic.Hash(plaintext).Equal(id) {
|
||||
return errors.New("hash mismatch")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) compressUnpacked(p []byte) ([]byte, error) {
|
||||
// compression is only available starting from version 2
|
||||
if r.cfg.Version < 2 {
|
||||
@@ -474,7 +505,8 @@ func (r *Repository) decompressUnpacked(p []byte) ([]byte, error) {
|
||||
|
||||
// SaveUnpacked encrypts data and stores it in the backend. Returned is the
|
||||
// storage hash.
|
||||
func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []byte) (id restic.ID, err error) {
|
||||
func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, buf []byte) (id restic.ID, err error) {
|
||||
p := buf
|
||||
if t != restic.ConfigFile {
|
||||
p, err = r.compressUnpacked(p)
|
||||
if err != nil {
|
||||
@@ -489,6 +521,11 @@ func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []by
|
||||
|
||||
ciphertext = r.key.Seal(ciphertext, nonce, p, nil)
|
||||
|
||||
if err := r.verifyUnpacked(ciphertext, t, buf); err != nil {
|
||||
//nolint:revive // ignore linter warnings about error message spelling
|
||||
return restic.ID{}, fmt.Errorf("Detected data corruption while saving file of type %v: %w\nCorrupted data is either caused by hardware issues or software bugs. Please open an issue at https://github.com/restic/restic/issues/new/choose for further troubleshooting.", t, err)
|
||||
}
|
||||
|
||||
if t == restic.ConfigFile {
|
||||
id = restic.ID{}
|
||||
} else {
|
||||
@@ -506,6 +543,29 @@ func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []by
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (r *Repository) verifyUnpacked(buf []byte, t restic.FileType, expected []byte) error {
|
||||
if r.opts.NoExtraVerify {
|
||||
return nil
|
||||
}
|
||||
|
||||
nonce, ciphertext := buf[:r.key.NonceSize()], buf[r.key.NonceSize():]
|
||||
plaintext, err := r.key.Open(nil, nonce, ciphertext, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decryption failed: %w", err)
|
||||
}
|
||||
if t != restic.ConfigFile {
|
||||
plaintext, err = r.decompressUnpacked(plaintext)
|
||||
if err != nil {
|
||||
return fmt.Errorf("decompression failed: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if !bytes.Equal(plaintext, expected) {
|
||||
return errors.New("data mismatch")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Flush saves all remaining packs and the index
|
||||
func (r *Repository) Flush(ctx context.Context) error {
|
||||
if err := r.flushPacks(ctx); err != nil {
|
||||
@@ -829,7 +889,7 @@ func (r *Repository) List(ctx context.Context, t restic.FileType, fn func(restic
|
||||
}
|
||||
|
||||
// ListPack returns the list of blobs saved in the pack id and the length of
|
||||
// the the pack header.
|
||||
// the pack header.
|
||||
func (r *Repository) ListPack(ctx context.Context, id restic.ID, size int64) ([]restic.Blob, uint32, error) {
|
||||
h := restic.Handle{Type: restic.PackFile, Name: id.String()}
|
||||
|
||||
@@ -887,9 +947,9 @@ type BackendLoadFn func(ctx context.Context, h restic.Handle, length int, offset
|
||||
const maxUnusedRange = 4 * 1024 * 1024
|
||||
|
||||
// StreamPack loads the listed blobs from the specified pack file. The plaintext blob is passed to
|
||||
// the handleBlobFn callback or an error if decryption failed or the blob hash does not match. In
|
||||
// case of download errors handleBlobFn might be called multiple times for the same blob. If the
|
||||
// callback returns an error, then StreamPack will abort and not retry it.
|
||||
// the handleBlobFn callback or an error if decryption failed or the blob hash does not match.
|
||||
// handleBlobFn is never called multiple times for the same blob. If the callback returns an error,
|
||||
// then StreamPack will abort and not retry it.
|
||||
func StreamPack(ctx context.Context, beLoad BackendLoadFn, key *crypto.Key, packID restic.ID, blobs []restic.Blob, handleBlobFn func(blob restic.BlobHandle, buf []byte, err error) error) error {
|
||||
if len(blobs) == 0 {
|
||||
// nothing to do
|
||||
@@ -951,7 +1011,9 @@ func streamPackPart(ctx context.Context, beLoad BackendLoadFn, key *crypto.Key,
|
||||
currentBlobEnd := dataStart
|
||||
var buf []byte
|
||||
var decode []byte
|
||||
for _, entry := range blobs {
|
||||
for len(blobs) > 0 {
|
||||
entry := blobs[0]
|
||||
|
||||
skipBytes := int(entry.Offset - currentBlobEnd)
|
||||
if skipBytes < 0 {
|
||||
return errors.Errorf("overlapping blobs in pack %v", packID)
|
||||
@@ -1014,6 +1076,8 @@ func streamPackPart(ctx context.Context, beLoad BackendLoadFn, key *crypto.Key,
|
||||
cancel()
|
||||
return backoff.Permanent(err)
|
||||
}
|
||||
// ensure that each blob is only passed once to handleBlobFn
|
||||
blobs = blobs[1:]
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
@@ -3,8 +3,10 @@ package repository
|
||||
import (
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/restic/restic/internal/crypto"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
rtest "github.com/restic/restic/internal/test"
|
||||
)
|
||||
@@ -72,3 +74,101 @@ func BenchmarkSortCachedPacksFirst(b *testing.B) {
|
||||
sortCachedPacksFirst(cache, cpy[:])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlobVerification(t *testing.T) {
|
||||
repo := TestRepository(t).(*Repository)
|
||||
|
||||
type DamageType string
|
||||
const (
|
||||
damageData DamageType = "data"
|
||||
damageCompressed DamageType = "compressed"
|
||||
damageCiphertext DamageType = "ciphertext"
|
||||
)
|
||||
|
||||
for _, test := range []struct {
|
||||
damage DamageType
|
||||
msg string
|
||||
}{
|
||||
{"", ""},
|
||||
{damageData, "hash mismatch"},
|
||||
{damageCompressed, "decompression failed"},
|
||||
{damageCiphertext, "ciphertext verification failed"},
|
||||
} {
|
||||
plaintext := rtest.Random(800, 1234)
|
||||
id := restic.Hash(plaintext)
|
||||
if test.damage == damageData {
|
||||
plaintext[42] ^= 0x42
|
||||
}
|
||||
|
||||
uncompressedLength := uint(len(plaintext))
|
||||
plaintext = repo.getZstdEncoder().EncodeAll(plaintext, nil)
|
||||
|
||||
if test.damage == damageCompressed {
|
||||
plaintext = plaintext[:len(plaintext)-8]
|
||||
}
|
||||
|
||||
nonce := crypto.NewRandomNonce()
|
||||
ciphertext := append([]byte{}, nonce...)
|
||||
ciphertext = repo.Key().Seal(ciphertext, nonce, plaintext, nil)
|
||||
|
||||
if test.damage == damageCiphertext {
|
||||
ciphertext[42] ^= 0x42
|
||||
}
|
||||
|
||||
err := repo.verifyCiphertext(ciphertext, int(uncompressedLength), id)
|
||||
if test.msg == "" {
|
||||
rtest.Assert(t, err == nil, "expected no error, got %v", err)
|
||||
} else {
|
||||
rtest.Assert(t, strings.Contains(err.Error(), test.msg), "expected error to contain %q, got %q", test.msg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnpackedVerification(t *testing.T) {
|
||||
repo := TestRepository(t).(*Repository)
|
||||
|
||||
type DamageType string
|
||||
const (
|
||||
damageData DamageType = "data"
|
||||
damageCompressed DamageType = "compressed"
|
||||
damageCiphertext DamageType = "ciphertext"
|
||||
)
|
||||
|
||||
for _, test := range []struct {
|
||||
damage DamageType
|
||||
msg string
|
||||
}{
|
||||
{"", ""},
|
||||
{damageData, "data mismatch"},
|
||||
{damageCompressed, "decompression failed"},
|
||||
{damageCiphertext, "ciphertext verification failed"},
|
||||
} {
|
||||
plaintext := rtest.Random(800, 1234)
|
||||
orig := append([]byte{}, plaintext...)
|
||||
if test.damage == damageData {
|
||||
plaintext[42] ^= 0x42
|
||||
}
|
||||
|
||||
compressed := []byte{2}
|
||||
compressed = repo.getZstdEncoder().EncodeAll(plaintext, compressed)
|
||||
|
||||
if test.damage == damageCompressed {
|
||||
compressed = compressed[:len(compressed)-8]
|
||||
}
|
||||
|
||||
nonce := crypto.NewRandomNonce()
|
||||
ciphertext := append([]byte{}, nonce...)
|
||||
ciphertext = repo.Key().Seal(ciphertext, nonce, compressed, nil)
|
||||
|
||||
if test.damage == damageCiphertext {
|
||||
ciphertext[42] ^= 0x42
|
||||
}
|
||||
|
||||
err := repo.verifyUnpacked(ciphertext, restic.IndexFile, orig)
|
||||
if test.msg == "" {
|
||||
rtest.Assert(t, err == nil, "expected no error, got %v", err)
|
||||
} else {
|
||||
rtest.Assert(t, strings.Contains(err.Error(), test.msg), "expected error to contain %q, got %q", test.msg, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
@@ -14,6 +15,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff/v4"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/klauspost/compress/zstd"
|
||||
"github.com/restic/restic/internal/backend/local"
|
||||
@@ -528,7 +530,9 @@ func testStreamPack(t *testing.T, version uint) {
|
||||
packfileBlobs, packfile := buildPackfileWithoutHeader(blobSizes, &key, compress)
|
||||
|
||||
loadCalls := 0
|
||||
load := func(ctx context.Context, h restic.Handle, length int, offset int64, fn func(rd io.Reader) error) error {
|
||||
shortFirstLoad := false
|
||||
|
||||
loadBytes := func(length int, offset int64) []byte {
|
||||
data := packfile
|
||||
|
||||
if offset > int64(len(data)) {
|
||||
@@ -540,12 +544,34 @@ func testStreamPack(t *testing.T, version uint) {
|
||||
if length > len(data) {
|
||||
length = len(data)
|
||||
}
|
||||
if shortFirstLoad {
|
||||
length /= 2
|
||||
shortFirstLoad = false
|
||||
}
|
||||
|
||||
return data[:length]
|
||||
}
|
||||
|
||||
load := func(ctx context.Context, h restic.Handle, length int, offset int64, fn func(rd io.Reader) error) error {
|
||||
data := loadBytes(length, offset)
|
||||
if shortFirstLoad {
|
||||
data = data[:len(data)/2]
|
||||
shortFirstLoad = false
|
||||
}
|
||||
|
||||
data = data[:length]
|
||||
loadCalls++
|
||||
|
||||
return fn(bytes.NewReader(data))
|
||||
err := fn(bytes.NewReader(data))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
var permanent *backoff.PermanentError
|
||||
if errors.As(err, &permanent) {
|
||||
return err
|
||||
}
|
||||
|
||||
// retry loading once
|
||||
return fn(bytes.NewReader(loadBytes(length, offset)))
|
||||
}
|
||||
|
||||
// first, test regular usage
|
||||
@@ -553,19 +579,21 @@ func testStreamPack(t *testing.T, version uint) {
|
||||
tests := []struct {
|
||||
blobs []restic.Blob
|
||||
calls int
|
||||
shortFirstLoad bool
|
||||
}{
|
||||
{packfileBlobs[1:2], 1},
|
||||
{packfileBlobs[2:5], 1},
|
||||
{packfileBlobs[2:8], 1},
|
||||
{packfileBlobs[1:2], 1, false},
|
||||
{packfileBlobs[2:5], 1, false},
|
||||
{packfileBlobs[2:8], 1, false},
|
||||
{[]restic.Blob{
|
||||
packfileBlobs[0],
|
||||
packfileBlobs[4],
|
||||
packfileBlobs[2],
|
||||
}, 1},
|
||||
}, 1, false},
|
||||
{[]restic.Blob{
|
||||
packfileBlobs[0],
|
||||
packfileBlobs[len(packfileBlobs)-1],
|
||||
}, 2},
|
||||
}, 2, false},
|
||||
{packfileBlobs[:], 1, true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@@ -592,6 +620,7 @@ func testStreamPack(t *testing.T, version uint) {
|
||||
}
|
||||
|
||||
loadCalls = 0
|
||||
shortFirstLoad = test.shortFirstLoad
|
||||
err = repository.StreamPack(ctx, load, &key, restic.ID{}, test.blobs, handleBlob)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -604,6 +633,7 @@ func testStreamPack(t *testing.T, version uint) {
|
||||
})
|
||||
}
|
||||
})
|
||||
shortFirstLoad = false
|
||||
|
||||
// next, test invalid uses, which should return an error
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
|
@@ -43,7 +43,7 @@ const TestChunkerPol = chunker.Pol(0x3DA3358B4DC173)
|
||||
// TestRepositoryWithBackend returns a repository initialized with a test
|
||||
// password. If be is nil, an in-memory backend is used. A constant polynomial
|
||||
// is used for the chunker and low-security test parameters.
|
||||
func TestRepositoryWithBackend(t testing.TB, be restic.Backend, version uint) restic.Repository {
|
||||
func TestRepositoryWithBackend(t testing.TB, be restic.Backend, version uint, opts Options) restic.Repository {
|
||||
t.Helper()
|
||||
TestUseLowSecurityKDFParameters(t)
|
||||
restic.TestDisableCheckPolynomial(t)
|
||||
@@ -52,7 +52,7 @@ func TestRepositoryWithBackend(t testing.TB, be restic.Backend, version uint) re
|
||||
be = TestBackend(t)
|
||||
}
|
||||
|
||||
repo, err := New(be, Options{})
|
||||
repo, err := New(be, opts)
|
||||
if err != nil {
|
||||
t.Fatalf("TestRepository(): new repo failed: %v", err)
|
||||
}
|
||||
@@ -78,6 +78,7 @@ func TestRepository(t testing.TB) restic.Repository {
|
||||
func TestRepositoryWithVersion(t testing.TB, version uint) restic.Repository {
|
||||
t.Helper()
|
||||
dir := os.Getenv("RESTIC_TEST_REPO")
|
||||
opts := Options{}
|
||||
if dir != "" {
|
||||
_, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
@@ -85,7 +86,7 @@ func TestRepositoryWithVersion(t testing.TB, version uint) restic.Repository {
|
||||
if err != nil {
|
||||
t.Fatalf("error creating local backend at %v: %v", dir, err)
|
||||
}
|
||||
return TestRepositoryWithBackend(t, be, version)
|
||||
return TestRepositoryWithBackend(t, be, version, opts)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
@@ -93,7 +94,7 @@ func TestRepositoryWithVersion(t testing.TB, version uint) restic.Repository {
|
||||
}
|
||||
}
|
||||
|
||||
return TestRepositoryWithBackend(t, nil, version)
|
||||
return TestRepositoryWithBackend(t, nil, version, opts)
|
||||
}
|
||||
|
||||
// TestOpenLocal opens a local repository.
|
||||
|
@@ -65,7 +65,7 @@ func (be *failLockLoadingBackend) Load(ctx context.Context, h restic.Handle, len
|
||||
|
||||
func TestMultipleLockFailure(t *testing.T) {
|
||||
be := &failLockLoadingBackend{Backend: mem.New()}
|
||||
repo := repository.TestRepositoryWithBackend(t, be, 0)
|
||||
repo := repository.TestRepositoryWithBackend(t, be, 0, repository.Options{})
|
||||
restic.TestSetLockTimeout(t, 5*time.Millisecond)
|
||||
|
||||
lock1, err := restic.NewLock(context.TODO(), repo)
|
||||
|
@@ -109,7 +109,7 @@ func NodeFromFileInfo(path string, fi os.FileInfo) (*Node, error) {
|
||||
}
|
||||
|
||||
func nodeTypeFromFileInfo(fi os.FileInfo) string {
|
||||
switch fi.Mode() & (os.ModeType | os.ModeCharDevice) {
|
||||
switch fi.Mode() & os.ModeType {
|
||||
case 0:
|
||||
return "file"
|
||||
case os.ModeDir:
|
||||
@@ -124,6 +124,8 @@ func nodeTypeFromFileInfo(fi os.FileInfo) string {
|
||||
return "fifo"
|
||||
case os.ModeSocket:
|
||||
return "socket"
|
||||
case os.ModeIrregular:
|
||||
return "irregular"
|
||||
}
|
||||
|
||||
return ""
|
||||
@@ -622,7 +624,7 @@ func (node *Node) fillExtra(path string, fi os.FileInfo) error {
|
||||
case "fifo":
|
||||
case "socket":
|
||||
default:
|
||||
return errors.Errorf("invalid node type %q", node.Type)
|
||||
return errors.Errorf("unsupported file type %q", node.Type)
|
||||
}
|
||||
|
||||
return node.fillExtendedAttributes(path)
|
||||
|
@@ -39,7 +39,7 @@ type Repository interface {
|
||||
List(ctx context.Context, t FileType, fn func(ID, int64) error) error
|
||||
|
||||
// ListPack returns the list of blobs saved in the pack id and the length of
|
||||
// the the pack header.
|
||||
// the pack header.
|
||||
ListPack(context.Context, ID, int64) ([]Blob, uint32, error)
|
||||
|
||||
LoadBlob(context.Context, BlobType, ID, []byte) ([]byte, error)
|
||||
|
@@ -197,19 +197,20 @@ func (r *fileRestorer) restoreFiles(ctx context.Context) error {
|
||||
return wg.Wait()
|
||||
}
|
||||
|
||||
func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
|
||||
|
||||
// calculate blob->[]files->[]offsets mappings
|
||||
blobs := make(map[restic.ID]struct {
|
||||
type blobToFileOffsetsMapping map[restic.ID]struct {
|
||||
files map[*fileInfo][]int64 // file -> offsets (plural!) of the blob in the file
|
||||
})
|
||||
var blobList []restic.Blob
|
||||
blob restic.Blob
|
||||
}
|
||||
|
||||
func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
|
||||
// calculate blob->[]files->[]offsets mappings
|
||||
blobs := make(blobToFileOffsetsMapping)
|
||||
for file := range pack.files {
|
||||
addBlob := func(blob restic.Blob, fileOffset int64) {
|
||||
blobInfo, ok := blobs[blob.ID]
|
||||
if !ok {
|
||||
blobInfo.files = make(map[*fileInfo][]int64)
|
||||
blobList = append(blobList, blob)
|
||||
blobInfo.blob = blob
|
||||
blobs[blob.ID] = blobInfo
|
||||
}
|
||||
blobInfo.files[file] = append(blobInfo.files[file], fileOffset)
|
||||
@@ -239,18 +240,83 @@ func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
|
||||
}
|
||||
}
|
||||
|
||||
sanitizeError := func(file *fileInfo, err error) error {
|
||||
// track already processed blobs for precise error reporting
|
||||
processedBlobs := restic.NewBlobSet()
|
||||
for _, entry := range blobs {
|
||||
occurrences := 0
|
||||
for _, offsets := range entry.files {
|
||||
occurrences += len(offsets)
|
||||
}
|
||||
// With a maximum blob size of 8MB, the normal blob streaming has to write
|
||||
// at most 800MB for a single blob. This should be short enough to avoid
|
||||
// network connection timeouts. Based on a quick test, a limit of 100 only
|
||||
// selects a very small number of blobs (the number of references per blob
|
||||
// - aka. `count` - seem to follow a expontential distribution)
|
||||
if occurrences > 100 {
|
||||
// process frequently referenced blobs first as these can take a long time to write
|
||||
// which can cause backend connections to time out
|
||||
delete(blobs, entry.blob.ID)
|
||||
partialBlobs := blobToFileOffsetsMapping{entry.blob.ID: entry}
|
||||
err := r.downloadBlobs(ctx, pack.id, partialBlobs, processedBlobs)
|
||||
if err := r.reportError(blobs, processedBlobs, err); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(blobs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := r.downloadBlobs(ctx, pack.id, blobs, processedBlobs)
|
||||
return r.reportError(blobs, processedBlobs, err)
|
||||
}
|
||||
|
||||
func (r *fileRestorer) sanitizeError(file *fileInfo, err error) error {
|
||||
if err != nil {
|
||||
err = r.Error(file.location, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *fileRestorer) reportError(blobs blobToFileOffsetsMapping, processedBlobs restic.BlobSet, err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := repository.StreamPack(ctx, r.packLoader, r.key, pack.id, blobList, func(h restic.BlobHandle, blobData []byte, err error) error {
|
||||
// only report error for not yet processed blobs
|
||||
affectedFiles := make(map[*fileInfo]struct{})
|
||||
for _, entry := range blobs {
|
||||
if processedBlobs.Has(entry.blob.BlobHandle) {
|
||||
continue
|
||||
}
|
||||
for file := range entry.files {
|
||||
affectedFiles[file] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
for file := range affectedFiles {
|
||||
if errFile := r.sanitizeError(file, err); errFile != nil {
|
||||
return errFile
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *fileRestorer) downloadBlobs(ctx context.Context, packID restic.ID,
|
||||
blobs blobToFileOffsetsMapping, processedBlobs restic.BlobSet) error {
|
||||
|
||||
blobList := make([]restic.Blob, 0, len(blobs))
|
||||
for _, entry := range blobs {
|
||||
blobList = append(blobList, entry.blob)
|
||||
}
|
||||
return repository.StreamPack(ctx, r.packLoader, r.key, packID, blobList,
|
||||
func(h restic.BlobHandle, blobData []byte, err error) error {
|
||||
processedBlobs.Insert(h)
|
||||
blob := blobs[h.ID]
|
||||
if err != nil {
|
||||
for file := range blob.files {
|
||||
if errFile := sanitizeError(file, err); errFile != nil {
|
||||
if errFile := r.sanitizeError(file, err); errFile != nil {
|
||||
return errFile
|
||||
}
|
||||
}
|
||||
@@ -282,7 +348,7 @@ func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
|
||||
|
||||
return writeErr
|
||||
}
|
||||
err := sanitizeError(file, writeToFile())
|
||||
err := r.sanitizeError(file, writeToFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -290,14 +356,4 @@ func (r *fileRestorer) downloadPack(ctx context.Context, pack *packInfo) error {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
for file := range pack.files {
|
||||
if errFile := sanitizeError(file, err); errFile != nil {
|
||||
return errFile
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -247,6 +247,27 @@ func TestFileRestorerPackSkip(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileRestorerFrequentBlob(t *testing.T) {
|
||||
tempdir := rtest.TempDir(t)
|
||||
|
||||
for _, sparse := range []bool{false, true} {
|
||||
blobs := []TestBlob{
|
||||
{"data1-1", "pack1-1"},
|
||||
}
|
||||
for i := 0; i < 10000; i++ {
|
||||
blobs = append(blobs, TestBlob{"a", "pack1-1"})
|
||||
}
|
||||
blobs = append(blobs, TestBlob{"end", "pack1-1"})
|
||||
|
||||
restoreAndVerify(t, tempdir, []TestFile{
|
||||
{
|
||||
name: "file1",
|
||||
blobs: blobs,
|
||||
},
|
||||
}, nil, sparse)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorRestoreFiles(t *testing.T) {
|
||||
tempdir := rtest.TempDir(t)
|
||||
content := []TestFile{
|
||||
@@ -316,3 +337,47 @@ func testPartialDownloadError(t *testing.T, part int) {
|
||||
rtest.OK(t, err)
|
||||
verifyRestore(t, r, repo)
|
||||
}
|
||||
|
||||
func TestFatalDownloadError(t *testing.T) {
|
||||
tempdir := rtest.TempDir(t)
|
||||
content := []TestFile{
|
||||
{
|
||||
name: "file1",
|
||||
blobs: []TestBlob{
|
||||
{"data1-1", "pack1"},
|
||||
{"data1-2", "pack1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "file2",
|
||||
blobs: []TestBlob{
|
||||
{"data2-1", "pack1"},
|
||||
{"data2-2", "pack1"},
|
||||
{"data2-3", "pack1"},
|
||||
},
|
||||
}}
|
||||
|
||||
repo := newTestRepo(content)
|
||||
|
||||
loader := repo.loader
|
||||
repo.loader = func(ctx context.Context, h restic.Handle, length int, offset int64, fn func(rd io.Reader) error) error {
|
||||
// only return half the data to break file2
|
||||
return loader(ctx, h, length/2, offset, fn)
|
||||
}
|
||||
|
||||
r := newFileRestorer(tempdir, repo.loader, repo.key, repo.Lookup, 2, false, nil)
|
||||
r.files = repo.files
|
||||
|
||||
var errors []string
|
||||
r.Error = func(s string, e error) error {
|
||||
// ignore errors as in the `restore` command
|
||||
errors = append(errors, s)
|
||||
return nil
|
||||
}
|
||||
|
||||
err := r.restoreFiles(context.TODO())
|
||||
rtest.OK(t, err)
|
||||
|
||||
rtest.Assert(t, len(errors) == 1, "unexpected number of restore errors, expected: 1, got: %v", len(errors))
|
||||
rtest.Assert(t, errors[0] == "file2", "expected error for file2, got: %v", errors[0])
|
||||
}
|
||||
|
Reference in New Issue
Block a user