Compare commits

..

74 Commits

Author SHA1 Message Date
Alexander Neumann
fe9f142b52 Add version for 0.16.5 2024-07-01 21:25:34 +02:00
Alexander Neumann
6ae760751a Generate CHANGELOG.md for 0.16.5 2024-07-01 21:25:33 +02:00
Alexander Neumann
2fa1b42706 Prepare changelog for 0.16.5 2024-07-01 21:25:33 +02:00
Michael Eischer
ca04a88e65 Merge pull request #4879 from restic/backport-azure-cli-option
Backport azure cli option
2024-06-26 21:07:16 +02:00
Michael Eischer
12e858b7af azure: deduplicate cli and default credentials case 2024-06-26 20:59:51 +02:00
Maik Riechert
834f08fe2d Azure: add option to force use of CLI credential 2024-06-26 20:59:51 +02:00
Michael Eischer
814ef4901f Merge pull request #4878 from restic/patch-deps-bump
Bump dependencies
2024-06-26 20:58:29 +02:00
Michael Eischer
84bc9432de update release verification script for latest docker 2024-06-26 20:49:23 +02:00
Michael Eischer
e9d711422a bump azure, golang and gcs dependencies 2024-06-26 20:49:23 +02:00
Alexander Neumann
0f9fa44de5 Set development version for 0.16.4 2024-02-04 19:50:56 +01:00
Alexander Neumann
3786536dc1 Add version for 0.16.4 2024-02-04 19:50:52 +01:00
Alexander Neumann
811be5984d Update manpages and auto-completion 2024-02-04 19:50:51 +01:00
Alexander Neumann
b0ead75de5 Generate CHANGELOG.md for 0.16.4 2024-02-04 19:50:34 +01:00
Alexander Neumann
6cd2804bff Prepare changelog for 0.16.4 2024-02-04 19:50:34 +01:00
Michael Eischer
a72c2b74f3 Apply changelog entry / documentation improvements from review 2024-02-04 19:10:06 +01:00
Michael Eischer
261b1455c7 add documentation for --no-extra-verify option 2024-02-04 19:10:06 +01:00
Michael Eischer
2a0bd2b637 rename --no-verify-pack to --no-extra-verify 2024-02-04 19:10:05 +01:00
Michael Eischer
4589da7eb9 add data verification changelog entry 2024-02-04 19:09:49 +01:00
Michael Eischer
75e72d826c pack: verify integrity of pack file header 2024-02-04 19:09:49 +01:00
Michael Eischer
d8916bc3d9 repository: ask users to report corrupted data while saving blobs 2024-02-04 19:09:49 +01:00
Michael Eischer
dc11d012bb Make --no-verify-pack globally available
Verifying all blobs before upload comes with a notable performance
impact. Allow users to skip it if necessary.
2024-02-04 19:09:49 +01:00
Michael Eischer
8ef5425351 repository: test verification of blobs/unpacked data 2024-02-04 19:09:46 +01:00
Michael Eischer
885431ec2b repository: Allow skipping verification for tests
Some tests have to explicitly create pack files with blobs that don't
match their ID. For those blobs the builtin verification of the
repository must be disabled.
2024-02-04 19:08:30 +01:00
Michael Eischer
cb85fb46dd backup: verify unpacked files before upload 2024-02-04 19:07:48 +01:00
Michael Eischer
2f30c940b2 backup: verify blobs before upload
This only covers the blobs themselves, the pack header is not verified
so far. Unpacked files are also not covered by the integrity check.
2024-02-04 19:07:48 +01:00
Michael Eischer
0ea62b5ac6 repository: make repo.Options configurable for test repos 2024-02-04 19:07:46 +01:00
Michael Eischer
29e1caf825 add changelog draft for data corruption on max compression 2024-02-04 19:05:51 +01:00
Michael Eischer
0164f5310d Downgrade klauspost/compress to fix data corruption at max. compression 2024-02-04 19:05:50 +01:00
Alexander Neumann
0ec9383ba2 Set development version for 0.16.3 2024-01-14 20:21:45 +01:00
Alexander Neumann
abca112404 Add version for 0.16.3 2024-01-14 20:21:45 +01:00
Alexander Neumann
b70b94507a Generate CHANGELOG.md for 0.16.3 2024-01-14 20:21:19 +01:00
Alexander Neumann
d987582594 Prepare changelog for 0.16.3 2024-01-14 20:21:19 +01:00
Leo R. Lundgren
ef2e473b99 doc: Polish changelogs 2024-01-10 00:19:07 +01:00
Michael Eischer
e4bbde7036 rclone: Workaround for incorrect "not found" errors while listing files
rclone returns a "not found" error if an internal error occurs while
listing a folder. Ignoring this error lets restic erroneously think that
there are no files, which can cause `prune` to wipe the whole
repository.
2024-01-09 18:28:17 +01:00
Michael Eischer
ec0fb46f6c add changelog for reliable restores 2024-01-09 18:27:48 +01:00
Michael Eischer
103beb96bc restore: separately restore blobs that are frequently referenced
Writing these blobs to their files can take a long time and consequently
cause the backend connection to time out. Avoid that by retrieving these
blobs separately.
2024-01-09 18:27:48 +01:00
Michael Eischer
f0f89d7f27 restore: split error reporting from downloadPack 2024-01-09 18:27:48 +01:00
Michael Eischer
cf352ccafb restore: cleanup downloadPack 2024-01-09 18:27:48 +01:00
Michael Eischer
b856e9489a restore: split downloadPack into smaller methods 2024-01-09 18:27:48 +01:00
Michael Eischer
ce7db90e08 sync CI and go dependencies with master branch 2024-01-08 21:33:05 +01:00
Michael Eischer
620518aec6 add changelog for better restore error reporting 2024-01-08 21:33:05 +01:00
Michael Eischer
f2fafbffaa restore: only report errors for blobs that actually failed to load
Previously, errors would be reported for all blobs of a packfile that
failed to stream. Now, only the not yet processed blobs are reported.
2024-01-08 21:33:05 +01:00
Michael Eischer
7a3a884874 repository: test that StreamPack only delivers blobs once 2024-01-08 21:33:05 +01:00
Michael Eischer
772a907533 repository: StreamPack delivers blobs at most once
If an error occurred while streaming a pack file, this could result in
passing some of the blobs multiple times to the callback function. This
significantly complicates using StreamPack correctly and is unnecessary.
Retries do not change the content of a blob and thus only deliver the
same result over and over again.
2024-01-08 21:33:05 +01:00
Michael Eischer
a9446c1184 add changelog for irregular files on windows 2024-01-08 21:33:05 +01:00
Michael Eischer
1bab29c336 archiver: Add filepath to error message if it is not included yet 2024-01-08 21:33:05 +01:00
Michael Eischer
e886c3f6b2 archiver: improve error message for irregular files
Since Go 1.21, most reparse points are considered as irregular files.
Depending on the underlying driver these can exhibit nearly arbitrary
behavior. When encountering such a file, restic returned an
indecipherable error message: `error: invalid node type ""`.

Add the filepath to the error message and state that the file type is
not supported.
2024-01-08 21:33:05 +01:00
Michael Eischer
c95de54726 restic: cleanup node type determination
os.ModeCharDevice is already included in os.ModeType
2024-01-08 21:33:05 +01:00
Michael Eischer
d4b8abd3e2 fix deduplicated files on windows 2024-01-08 21:33:05 +01:00
Joram Berger
948ab3ccaf Add a note that the oldest snapshot may be kept additionally
Documentation enhancement.
2024-01-08 21:33:05 +01:00
Markus Zoppelt
bb0c923298 docs: add pkgx install option
PR in pkgx pantry: https://github.com/pkgxdev/pantry/pull/4098

restic pkg:
https://pkgx.dev/pkgs/restic.net/restic/
2024-01-08 21:33:05 +01:00
Michael Eischer
ff0c975443 regenerate changelog 2024-01-08 21:33:05 +01:00
Michael Eischer
7e61e117d6 cleanup changelog whitespace 2024-01-08 21:33:05 +01:00
mmattel
220a28582e Add a table of contents (TOC) to the changelog template 2024-01-08 21:33:05 +01:00
Giuseppe D'Andrea
f44fd73230 docs: fix typo in working with repos
When using the `copy` command, `--from-password-file` and `--from-password-command` flags are used to specify the password of the source repository, not of the destination repository.
2024-01-08 21:33:05 +01:00
Joda Stößer
76bd975e03 docs(scripting): correct stats output comment to be about the correct command
not about the snapshots command
2024-01-08 21:33:05 +01:00
Quang-Linh LE
64b7aed362 docs: Mention progress for restore command. This is available after https://github.com/restic/restic/pull/3991 2024-01-08 21:33:05 +01:00
Michael Kuhn
3fa6b2de4a Fix repository not being printed when using repository file
When using `RESTIC_REPOSITORY_FILE` in combination with `restic init`,
the repository is missing in the output:
```
$ restic init
created restic repository 3c872be20f at
[...]
```
This is due to the code using `gopts.Repo`, which is empty in this case.
2024-01-08 21:33:05 +01:00
Michael Eischer
5cd000f4b0 CI: update golangci-lint
Necessary to properly support Go 1.21.
2024-01-08 21:33:05 +01:00
Alexander Neumann
59fe24cb2b Set development version for 0.16.2 2023-10-29 19:50:12 +01:00
Alexander Neumann
1a5efcf680 Add version for 0.16.2 2023-10-29 19:50:07 +01:00
Alexander Neumann
d33fe6dd3c Generate CHANGELOG.md for 0.16.2 2023-10-29 19:50:04 +01:00
Alexander Neumann
c8dd95f104 Prepare changelog for 0.16.2 2023-10-29 19:50:04 +01:00
Leo R. Lundgren
7d980b469d doc: Polish changelogs 2023-10-29 00:44:53 +02:00
Michael Eischer
d863234e3e add changelog for missing documentation 2023-10-28 20:25:24 +02:00
Michael Eischer
4be45de1c2 Restore support for ARMv5 platforms 2023-10-27 19:52:14 +02:00
Leo R. Lundgren
8c1125fe13 doc: Correct two typos 2023-10-27 19:48:00 +02:00
Martin Michlmayr
0b6ccea461 Fix typos 2023-10-27 19:48:00 +02:00
Martin Michlmayr
de6135351e Format option correctly 2023-10-27 19:48:00 +02:00
Michael Eischer
d47581b25e verify-release-binaries.sh: don't show warning if binaries are correct 2023-10-27 19:48:00 +02:00
Michael Eischer
69dec02a14 Remove readthedocs special case from docs configuration
Apparently it's now required to bring your own theme.
2023-10-27 19:47:19 +02:00
Michael Eischer
826d880614 Fix doc path typo in readthedocs configuration 2023-10-27 19:47:15 +02:00
Michael Eischer
dbf7ef72b9 Add read the docs config file version 2
The config file is by now necessary to build documentation:
https://blog.readthedocs.com/migrate-configuration-v2/
2023-10-27 19:47:11 +02:00
Alexander Neumann
27ec320eae Set development version for 0.16.1 2023-10-24 20:02:58 +02:00
88 changed files with 1380 additions and 498 deletions

View File

@@ -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 }}

View File

@@ -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
View 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

View File

@@ -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

View File

@@ -1 +1 @@
0.16.1
0.16.5

View File

@@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@@ -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 -}}

View File

@@ -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)
}

View File

@@ -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())

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
=====================

View File

@@ -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.

View File

@@ -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

View File

@@ -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 |

View File

@@ -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")

View File

@@ -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'

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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=

View File

@@ -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()

View File

@@ -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

View File

@@ -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.

View File

@@ -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()

View File

@@ -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 {

View File

@@ -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")
}

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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

View File

@@ -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")
}

View File

@@ -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)

View File

@@ -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)
}
}
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
})

View File

@@ -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)
}
}
}

View File

@@ -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) {

View File

@@ -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.

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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])
}