mirror of
https://github.com/octoleo/restic.git
synced 2024-12-25 20:11:06 +00:00
Merge pull request #4694 from restic/update-go-versions
Update go versions
This commit is contained in:
commit
667a2f5369
17
.github/workflows/tests.yml
vendored
17
.github/workflows/tests.yml
vendored
@ -13,7 +13,7 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
latest_go: "1.21.x"
|
latest_go: "1.22.x"
|
||||||
GO111MODULE: on
|
GO111MODULE: on
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@ -23,27 +23,32 @@ jobs:
|
|||||||
# list of jobs to run:
|
# list of jobs to run:
|
||||||
include:
|
include:
|
||||||
- job_name: Windows
|
- job_name: Windows
|
||||||
go: 1.21.x
|
go: 1.22.x
|
||||||
os: windows-latest
|
os: windows-latest
|
||||||
|
|
||||||
- job_name: macOS
|
- job_name: macOS
|
||||||
go: 1.21.x
|
go: 1.22.x
|
||||||
os: macOS-latest
|
os: macOS-latest
|
||||||
test_fuse: false
|
test_fuse: false
|
||||||
|
|
||||||
- job_name: Linux
|
- job_name: Linux
|
||||||
go: 1.21.x
|
go: 1.22.x
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
test_cloud_backends: true
|
test_cloud_backends: true
|
||||||
test_fuse: true
|
test_fuse: true
|
||||||
check_changelog: true
|
check_changelog: true
|
||||||
|
|
||||||
- job_name: Linux (race)
|
- job_name: Linux (race)
|
||||||
go: 1.21.x
|
go: 1.22.x
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
test_fuse: true
|
test_fuse: true
|
||||||
test_opts: "-race"
|
test_opts: "-race"
|
||||||
|
|
||||||
|
- job_name: Linux
|
||||||
|
go: 1.21.x
|
||||||
|
os: ubuntu-latest
|
||||||
|
test_fuse: true
|
||||||
|
|
||||||
- job_name: Linux
|
- job_name: Linux
|
||||||
go: 1.20.x
|
go: 1.20.x
|
||||||
os: ubuntu-latest
|
os: ubuntu-latest
|
||||||
@ -255,7 +260,7 @@ jobs:
|
|||||||
uses: golangci/golangci-lint-action@v3
|
uses: golangci/golangci-lint-action@v3
|
||||||
with:
|
with:
|
||||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||||
version: v1.55.2
|
version: v1.56.1
|
||||||
args: --verbose --timeout 5m
|
args: --verbose --timeout 5m
|
||||||
|
|
||||||
# only run golangci-lint for pull requests, otherwise ALL hints get
|
# only run golangci-lint for pull requests, otherwise ALL hints get
|
||||||
|
@ -54,3 +54,8 @@ issues:
|
|||||||
# staticcheck: there's no easy way to replace these packages
|
# staticcheck: there's no easy way to replace these packages
|
||||||
- "SA1019: \"golang.org/x/crypto/poly1305\" is deprecated"
|
- "SA1019: \"golang.org/x/crypto/poly1305\" is deprecated"
|
||||||
- "SA1019: \"golang.org/x/crypto/openpgp\" is deprecated"
|
- "SA1019: \"golang.org/x/crypto/openpgp\" is deprecated"
|
||||||
|
|
||||||
|
exclude-rules:
|
||||||
|
# revive: ignore unused parameters in tests
|
||||||
|
- path: (_test\.go|testing\.go|backend/.*/tests\.go)
|
||||||
|
text: "unused-parameter:"
|
@ -42,7 +42,7 @@ Exit status is 0 if the command was successful.
|
|||||||
Exit status is 1 if there was a fatal error (no snapshot created).
|
Exit status is 1 if there was a fatal error (no snapshot created).
|
||||||
Exit status is 3 if some source data could not be read (incomplete snapshot created).
|
Exit status is 3 if some source data could not be read (incomplete snapshot created).
|
||||||
`,
|
`,
|
||||||
PreRun: func(cmd *cobra.Command, args []string) {
|
PreRun: func(_ *cobra.Command, _ []string) {
|
||||||
if backupOptions.Host == "" {
|
if backupOptions.Host == "" {
|
||||||
hostname, err := os.Hostname()
|
hostname, err := os.Hostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -28,7 +28,7 @@ EXIT STATUS
|
|||||||
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(_ *cobra.Command, args []string) error {
|
||||||
return runCache(cacheOptions, globalOptions, args)
|
return runCache(cacheOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
|||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runCheck(cmd.Context(), checkOptions, globalOptions, args)
|
return runCheck(cmd.Context(), checkOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
PreRunE: func(_ *cobra.Command, _ []string) error {
|
||||||
return checkFlags(checkOptions)
|
return checkFlags(checkOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -345,11 +345,11 @@ func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args
|
|||||||
|
|
||||||
if len(salvagePacks) > 0 {
|
if len(salvagePacks) > 0 {
|
||||||
Warnf("\nThe repository contains pack files with damaged blobs. These blobs must be removed to repair the repository. This can be done using the following commands:\n\n")
|
Warnf("\nThe repository contains pack files with damaged blobs. These blobs must be removed to repair the repository. This can be done using the following commands:\n\n")
|
||||||
var strIds []string
|
var strIDs []string
|
||||||
for _, id := range salvagePacks {
|
for _, id := range salvagePacks {
|
||||||
strIds = append(strIds, id.String())
|
strIDs = append(strIDs, id.String())
|
||||||
}
|
}
|
||||||
Warnf("RESTIC_FEATURES=repair-packs-v1 restic repair packs %v\nrestic repair snapshots --forget\n\n", strings.Join(strIds, " "))
|
Warnf("RESTIC_FEATURES=repair-packs-v1 restic repair packs %v\nrestic repair snapshots --forget\n\n", strings.Join(strIDs, " "))
|
||||||
Warnf("Corrupted blobs are either caused by hardware problems or bugs in restic. Please open an issue at https://github.com/restic/restic/issues/new/choose for further troubleshooting!\n")
|
Warnf("Corrupted blobs are either caused by hardware problems or bugs in restic. Please open an issue at https://github.com/restic/restic/issues/new/choose for further troubleshooting!\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ func runDiff(ctx context.Context, opts DiffOptions, gopts GlobalOptions, args []
|
|||||||
}
|
}
|
||||||
|
|
||||||
if gopts.Quiet {
|
if gopts.Quiet {
|
||||||
c.printChange = func(change *Change) {}
|
c.printChange = func(_ *Change) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
stats := &DiffStatsContainer{
|
stats := &DiffStatsContainer{
|
||||||
|
@ -21,7 +21,7 @@ EXIT STATUS
|
|||||||
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(_ *cobra.Command, args []string) error {
|
||||||
return runGenerate(genOpts, args)
|
return runGenerate(genOpts, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ func listKeys(ctx context.Context, s *repository.Repository, gopts GlobalOptions
|
|||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var keys []keyInfo
|
var keys []keyInfo
|
||||||
|
|
||||||
err := restic.ParallelList(ctx, s, restic.KeyFile, s.Connections(), func(ctx context.Context, id restic.ID, size int64) error {
|
err := restic.ParallelList(ctx, s, restic.KeyFile, s.Connections(), func(ctx context.Context, id restic.ID, _ int64) error {
|
||||||
k, err := repository.LoadKey(ctx, s, id)
|
k, err := repository.LoadKey(ctx, s, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("LoadKey() failed: %v\n", err)
|
Warnf("LoadKey() failed: %v\n", err)
|
||||||
|
@ -63,7 +63,7 @@ func runList(ctx context.Context, gopts GlobalOptions, args []string) error {
|
|||||||
case "locks":
|
case "locks":
|
||||||
t = restic.LockFile
|
t = restic.LockFile
|
||||||
case "blobs":
|
case "blobs":
|
||||||
return index.ForAllIndexes(ctx, repo, repo, func(id restic.ID, idx *index.Index, oldFormat bool, err error) error {
|
return index.ForAllIndexes(ctx, repo, repo, func(_ restic.ID, idx *index.Index, _ bool, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ func runList(ctx context.Context, gopts GlobalOptions, args []string) error {
|
|||||||
return errors.Fatal("invalid type")
|
return errors.Fatal("invalid type")
|
||||||
}
|
}
|
||||||
|
|
||||||
return repo.List(ctx, t, func(id restic.ID, size int64) error {
|
return repo.List(ctx, t, func(id restic.ID, _ int64) error {
|
||||||
Printf("%s\n", id)
|
Printf("%s\n", id)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -21,7 +21,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
|||||||
`,
|
`,
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(_ *cobra.Command, _ []string) {
|
||||||
fmt.Printf("All Extended Options:\n")
|
fmt.Printf("All Extended Options:\n")
|
||||||
var maxLen int
|
var maxLen int
|
||||||
for _, opt := range options.List() {
|
for _, opt := range options.List() {
|
||||||
|
@ -37,7 +37,7 @@ EXIT STATUS
|
|||||||
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return runPrune(cmd.Context(), pruneOptions, globalOptions)
|
return runPrune(cmd.Context(), pruneOptions, globalOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -101,7 +101,7 @@ func verifyPruneOptions(opts *PruneOptions) error {
|
|||||||
// parse MaxUnused either as unlimited, a percentage, or an absolute number of bytes
|
// parse MaxUnused either as unlimited, a percentage, or an absolute number of bytes
|
||||||
switch {
|
switch {
|
||||||
case maxUnused == "unlimited":
|
case maxUnused == "unlimited":
|
||||||
opts.maxUnusedBytes = func(used uint64) uint64 {
|
opts.maxUnusedBytes = func(_ uint64) uint64 {
|
||||||
return math.MaxUint64
|
return math.MaxUint64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ func verifyPruneOptions(opts *PruneOptions) error {
|
|||||||
return errors.Fatalf("invalid number of bytes %q for --max-unused: %v", opts.MaxUnused, err)
|
return errors.Fatalf("invalid number of bytes %q for --max-unused: %v", opts.MaxUnused, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
opts.maxUnusedBytes = func(used uint64) uint64 {
|
opts.maxUnusedBytes = func(_ uint64) uint64 {
|
||||||
return uint64(size)
|
return uint64(size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -798,7 +798,7 @@ func rebuildIndexFiles(ctx context.Context, gopts GlobalOptions, repo restic.Rep
|
|||||||
DeleteProgress: func() *progress.Counter {
|
DeleteProgress: func() *progress.Counter {
|
||||||
return newProgressMax(!gopts.Quiet, 0, "old indexes deleted")
|
return newProgressMax(!gopts.Quiet, 0, "old indexes deleted")
|
||||||
},
|
},
|
||||||
DeleteReport: func(id restic.ID, err error) {
|
DeleteReport: func(id restic.ID, _ error) {
|
||||||
if gopts.verbosity > 2 {
|
if gopts.verbosity > 2 {
|
||||||
Verbosef("removed index %v\n", id.String())
|
Verbosef("removed index %v\n", id.String())
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ EXIT STATUS
|
|||||||
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return runRecover(cmd.Context(), globalOptions)
|
return runRecover(cmd.Context(), globalOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ func runRecover(ctx context.Context, gopts GlobalOptions) error {
|
|||||||
bar.Done()
|
bar.Done()
|
||||||
|
|
||||||
Verbosef("load snapshots\n")
|
Verbosef("load snapshots\n")
|
||||||
err = restic.ForAllSnapshots(ctx, snapshotLister, repo, nil, func(id restic.ID, sn *restic.Snapshot, err error) error {
|
err = restic.ForAllSnapshots(ctx, snapshotLister, repo, nil, func(_ restic.ID, sn *restic.Snapshot, _ error) error {
|
||||||
trees[*sn.Tree] = true
|
trees[*sn.Tree] = true
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -24,7 +24,7 @@ EXIT STATUS
|
|||||||
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return runRebuildIndex(cmd.Context(), repairIndexOptions, globalOptions)
|
return runRebuildIndex(cmd.Context(), repairIndexOptions, globalOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ func rebuildIndex(ctx context.Context, opts RepairIndexOptions, gopts GlobalOpti
|
|||||||
|
|
||||||
if opts.ReadAllPacks {
|
if opts.ReadAllPacks {
|
||||||
// get list of old index files but start with empty index
|
// get list of old index files but start with empty index
|
||||||
err := repo.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
|
err := repo.List(ctx, restic.IndexFile, func(id restic.ID, _ int64) error {
|
||||||
obsoleteIndexes = append(obsoleteIndexes, id)
|
obsoleteIndexes = append(obsoleteIndexes, id)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -88,7 +88,7 @@ func rebuildIndex(ctx context.Context, opts RepairIndexOptions, gopts GlobalOpti
|
|||||||
} else {
|
} else {
|
||||||
Verbosef("loading indexes...\n")
|
Verbosef("loading indexes...\n")
|
||||||
mi := index.NewMasterIndex()
|
mi := index.NewMasterIndex()
|
||||||
err := index.ForAllIndexes(ctx, repo, repo, func(id restic.ID, idx *index.Index, oldFormat bool, err error) error {
|
err := index.ForAllIndexes(ctx, repo, repo, func(id restic.ID, idx *index.Index, _ bool, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("removing invalid index %v: %v\n", id, err)
|
Warnf("removing invalid index %v: %v\n", id, err)
|
||||||
obsoleteIndexes = append(obsoleteIndexes, id)
|
obsoleteIndexes = append(obsoleteIndexes, id)
|
||||||
|
@ -125,7 +125,7 @@ func runRepairSnapshots(ctx context.Context, gopts GlobalOptions, opts RepairOpt
|
|||||||
node.Size = newSize
|
node.Size = newSize
|
||||||
return node
|
return node
|
||||||
},
|
},
|
||||||
RewriteFailedTree: func(nodeID restic.ID, path string, _ error) (restic.ID, error) {
|
RewriteFailedTree: func(_ restic.ID, path string, _ error) (restic.ID, error) {
|
||||||
if path == "/" {
|
if path == "/" {
|
||||||
Verbosef(" dir %q: not readable\n", path)
|
Verbosef(" dir %q: not readable\n", path)
|
||||||
// remove snapshots with invalid root node
|
// remove snapshots with invalid root node
|
||||||
|
@ -181,7 +181,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
|
|||||||
|
|
||||||
excludePatterns := filter.ParsePatterns(opts.Exclude)
|
excludePatterns := filter.ParsePatterns(opts.Exclude)
|
||||||
insensitiveExcludePatterns := filter.ParsePatterns(opts.InsensitiveExclude)
|
insensitiveExcludePatterns := filter.ParsePatterns(opts.InsensitiveExclude)
|
||||||
selectExcludeFilter := func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
|
selectExcludeFilter := func(item string, _ string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
|
||||||
matched, err := filter.List(excludePatterns, item)
|
matched, err := filter.List(excludePatterns, item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg.E("error for exclude pattern: %v", err)
|
msg.E("error for exclude pattern: %v", err)
|
||||||
@ -204,7 +204,7 @@ func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions,
|
|||||||
|
|
||||||
includePatterns := filter.ParsePatterns(opts.Include)
|
includePatterns := filter.ParsePatterns(opts.Include)
|
||||||
insensitiveIncludePatterns := filter.ParsePatterns(opts.InsensitiveInclude)
|
insensitiveIncludePatterns := filter.ParsePatterns(opts.InsensitiveInclude)
|
||||||
selectIncludeFilter := func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
|
selectIncludeFilter := func(item string, _ string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool) {
|
||||||
matched, childMayMatch, err := filter.ListWithChild(includePatterns, item)
|
matched, childMayMatch, err := filter.ListWithChild(includePatterns, item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg.E("error for include pattern: %v", err)
|
msg.E("error for include pattern: %v", err)
|
||||||
|
@ -147,7 +147,7 @@ func rewriteSnapshot(ctx context.Context, repo *repository.Repository, sn *resti
|
|||||||
return rewriter.RewriteTree(ctx, repo, "/", *sn.Tree)
|
return rewriter.RewriteTree(ctx, repo, "/", *sn.Tree)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filter = func(ctx context.Context, sn *restic.Snapshot) (restic.ID, error) {
|
filter = func(_ context.Context, sn *restic.Snapshot) (restic.ID, error) {
|
||||||
return *sn.Tree, nil
|
return *sn.Tree, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ func statsDebug(ctx context.Context, repo restic.Repository) error {
|
|||||||
|
|
||||||
func statsDebugFileType(ctx context.Context, repo restic.Lister, tpe restic.FileType) (*sizeHistogram, error) {
|
func statsDebugFileType(ctx context.Context, repo restic.Lister, tpe restic.FileType) (*sizeHistogram, error) {
|
||||||
hist := newSizeHistogram(2 * repository.MaxPackSize)
|
hist := newSizeHistogram(2 * repository.MaxPackSize)
|
||||||
err := repo.List(ctx, tpe, func(id restic.ID, size int64) error {
|
err := repo.List(ctx, tpe, func(_ restic.ID, size int64) error {
|
||||||
hist.Add(uint64(size))
|
hist.Add(uint64(size))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -19,7 +19,7 @@ EXIT STATUS
|
|||||||
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
return runUnlock(cmd.Context(), unlockOptions, globalOptions)
|
return runUnlock(cmd.Context(), unlockOptions, globalOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ EXIT STATUS
|
|||||||
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
Exit status is 0 if the command was successful, and non-zero if there was any error.
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(_ *cobra.Command, _ []string) {
|
||||||
if globalOptions.JSON {
|
if globalOptions.JSON {
|
||||||
type jsonVersion struct {
|
type jsonVersion struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
|
@ -37,7 +37,7 @@ The full documentation can be found at https://restic.readthedocs.io/ .
|
|||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
|
|
||||||
PersistentPreRunE: func(c *cobra.Command, args []string) error {
|
PersistentPreRunE: func(c *cobra.Command, _ []string) error {
|
||||||
// set verbosity, default is one
|
// set verbosity, default is one
|
||||||
globalOptions.verbosity = 1
|
globalOptions.verbosity = 1
|
||||||
if globalOptions.Quiet && globalOptions.Verbose > 0 {
|
if globalOptions.Quiet && globalOptions.Verbose > 0 {
|
||||||
|
@ -147,8 +147,8 @@ func (o Options) ApplyDefaults() Options {
|
|||||||
func New(repo restic.Repository, fs fs.FS, opts Options) *Archiver {
|
func New(repo restic.Repository, fs fs.FS, opts Options) *Archiver {
|
||||||
arch := &Archiver{
|
arch := &Archiver{
|
||||||
Repo: repo,
|
Repo: repo,
|
||||||
SelectByName: func(item string) bool { return true },
|
SelectByName: func(_ string) bool { return true },
|
||||||
Select: func(item string, fi os.FileInfo) bool { return true },
|
Select: func(_ string, _ os.FileInfo) bool { return true },
|
||||||
FS: fs,
|
FS: fs,
|
||||||
Options: opts.ApplyDefaults(),
|
Options: opts.ApplyDefaults(),
|
||||||
|
|
||||||
@ -762,7 +762,7 @@ func (arch *Archiver) Snapshot(ctx context.Context, targets []string, opts Snaps
|
|||||||
arch.runWorkers(wgCtx, wg)
|
arch.runWorkers(wgCtx, wg)
|
||||||
|
|
||||||
debug.Log("starting snapshot")
|
debug.Log("starting snapshot")
|
||||||
fn, nodeCount, err := arch.SaveTree(wgCtx, "/", atree, arch.loadParentTree(wgCtx, opts.ParentSnapshot), func(n *restic.Node, is ItemStats) {
|
fn, nodeCount, err := arch.SaveTree(wgCtx, "/", atree, arch.loadParentTree(wgCtx, opts.ParentSnapshot), func(_ *restic.Node, is ItemStats) {
|
||||||
arch.CompleteItem("/", nil, nil, is, time.Since(start))
|
arch.CompleteItem("/", nil, nil, is, time.Since(start))
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -25,10 +25,10 @@ type Scanner struct {
|
|||||||
func NewScanner(fs fs.FS) *Scanner {
|
func NewScanner(fs fs.FS) *Scanner {
|
||||||
return &Scanner{
|
return &Scanner{
|
||||||
FS: fs,
|
FS: fs,
|
||||||
SelectByName: func(item string) bool { return true },
|
SelectByName: func(_ string) bool { return true },
|
||||||
Select: func(item string, fi os.FileInfo) bool { return true },
|
Select: func(_ string, _ os.FileInfo) bool { return true },
|
||||||
Error: func(item string, err error) error { return err },
|
Error: func(_ string, err error) error { return err },
|
||||||
Result: func(item string, s ScanStats) {},
|
Result: func(_ string, _ ScanStats) {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ func NewFactory() location.Factory {
|
|||||||
|
|
||||||
return location.NewHTTPBackendFactory[struct{}, *MemoryBackend](
|
return location.NewHTTPBackendFactory[struct{}, *MemoryBackend](
|
||||||
"mem",
|
"mem",
|
||||||
func(s string) (*struct{}, error) {
|
func(_ string) (*struct{}, error) {
|
||||||
return &struct{}{}, nil
|
return &struct{}{}, nil
|
||||||
},
|
},
|
||||||
location.NoPassword,
|
location.NoPassword,
|
||||||
|
@ -183,7 +183,7 @@ func newBackend(ctx context.Context, cfg Config, lim limiter.Limiter) (*Backend,
|
|||||||
dialCount := 0
|
dialCount := 0
|
||||||
tr := &http2.Transport{
|
tr := &http2.Transport{
|
||||||
AllowHTTP: true, // this is not really HTTP, just stdin/stdout
|
AllowHTTP: true, // this is not really HTTP, just stdin/stdout
|
||||||
DialTLS: func(network, address string, cfg *tls.Config) (net.Conn, error) {
|
DialTLS: func(network, address string, _ *tls.Config) (net.Conn, error) {
|
||||||
debug.Log("new connection requested, %v %v", network, address)
|
debug.Log("new connection requested, %v %v", network, address)
|
||||||
if dialCount > 0 {
|
if dialCount > 0 {
|
||||||
// the connection to the child process is already closed
|
// the connection to the child process is already closed
|
||||||
|
@ -134,7 +134,7 @@ func (c *Checker) LoadIndex(ctx context.Context, p *progress.Counter) (hints []e
|
|||||||
|
|
||||||
if p != nil {
|
if p != nil {
|
||||||
var numIndexFiles uint64
|
var numIndexFiles uint64
|
||||||
err := indexList.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
|
err := indexList.List(ctx, restic.IndexFile, func(_ restic.ID, _ int64) error {
|
||||||
numIndexFiles++
|
numIndexFiles++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -41,7 +41,7 @@ type trackFile struct {
|
|||||||
|
|
||||||
func newTrackFile(stack []byte, filename string, file File) *trackFile {
|
func newTrackFile(stack []byte, filename string, file File) *trackFile {
|
||||||
f := &trackFile{file}
|
f := &trackFile{file}
|
||||||
runtime.SetFinalizer(f, func(f *trackFile) {
|
runtime.SetFinalizer(f, func(_ *trackFile) {
|
||||||
fmt.Fprintf(os.Stderr, "file %s not closed\n\nStacktrack:\n%s\n", filename, stack)
|
fmt.Fprintf(os.Stderr, "file %s not closed\n\nStacktrack:\n%s\n", filename, stack)
|
||||||
panic("file " + filename + " not closed")
|
panic("file " + filename + " not closed")
|
||||||
})
|
})
|
||||||
|
@ -295,7 +295,7 @@ func (d *SnapshotsDirStructure) updateSnapshots(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var snapshots restic.Snapshots
|
var snapshots restic.Snapshots
|
||||||
err := d.root.cfg.Filter.FindAll(ctx, d.root.repo, d.root.repo, nil, func(id string, sn *restic.Snapshot, err error) error {
|
err := d.root.cfg.Filter.FindAll(ctx, d.root.repo, d.root.repo, nil, func(_ string, sn *restic.Snapshot, _ error) error {
|
||||||
if sn != nil {
|
if sn != nil {
|
||||||
snapshots = append(snapshots, sn)
|
snapshots = append(snapshots, sn)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ func ForAllIndexes(ctx context.Context, lister restic.Lister, repo restic.Lister
|
|||||||
workerCount := repo.Connections() + uint(runtime.GOMAXPROCS(0))
|
workerCount := repo.Connections() + uint(runtime.GOMAXPROCS(0))
|
||||||
|
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
return restic.ParallelList(ctx, lister, restic.IndexFile, workerCount, func(ctx context.Context, id restic.ID, size int64) error {
|
return restic.ParallelList(ctx, lister, restic.IndexFile, workerCount, func(ctx context.Context, id restic.ID, _ int64) error {
|
||||||
var err error
|
var err error
|
||||||
var idx *Index
|
var idx *Index
|
||||||
oldFormat := false
|
oldFormat := false
|
||||||
|
@ -136,7 +136,7 @@ func SearchKey(ctx context.Context, s *Repository, password string, maxKeys int,
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// try at most maxKeys keys in repo
|
// try at most maxKeys keys in repo
|
||||||
err = s.List(listCtx, restic.KeyFile, func(id restic.ID, size int64) error {
|
err = s.List(listCtx, restic.KeyFile, func(id restic.ID, _ int64) error {
|
||||||
checked++
|
checked++
|
||||||
if maxKeys > 0 && checked > maxKeys {
|
if maxKeys > 0 && checked > maxKeys {
|
||||||
return ErrMaxKeysReached
|
return ErrMaxKeysReached
|
||||||
|
@ -68,7 +68,7 @@ func RepairPacks(ctx context.Context, repo restic.Repository, ids restic.IDSet,
|
|||||||
DeleteProgress: func() *progress.Counter {
|
DeleteProgress: func() *progress.Counter {
|
||||||
return printer.NewCounter("old indexes deleted")
|
return printer.NewCounter("old indexes deleted")
|
||||||
},
|
},
|
||||||
DeleteReport: func(id restic.ID, err error) {
|
DeleteReport: func(id restic.ID, _ error) {
|
||||||
printer.VV("removed index %v", id.String())
|
printer.VV("removed index %v", id.String())
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -651,7 +651,7 @@ func (r *Repository) LoadIndex(ctx context.Context, p *progress.Counter) error {
|
|||||||
|
|
||||||
if p != nil {
|
if p != nil {
|
||||||
var numIndexFiles uint64
|
var numIndexFiles uint64
|
||||||
err := indexList.List(ctx, restic.IndexFile, func(id restic.ID, size int64) error {
|
err := indexList.List(ctx, restic.IndexFile, func(_ restic.ID, _ int64) error {
|
||||||
numIndexFiles++
|
numIndexFiles++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -662,7 +662,7 @@ func (r *Repository) LoadIndex(ctx context.Context, p *progress.Counter) error {
|
|||||||
defer p.Done()
|
defer p.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
err = index.ForAllIndexes(ctx, indexList, r, func(id restic.ID, idx *index.Index, oldFormat bool, err error) error {
|
err = index.ForAllIndexes(ctx, indexList, r, func(_ restic.ID, idx *index.Index, _ bool, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ func Find(ctx context.Context, be Lister, t FileType, prefix string) (ID, error)
|
|||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
err := be.List(ctx, t, func(id ID, size int64) error {
|
err := be.List(ctx, t, func(id ID, _ int64) error {
|
||||||
name := id.String()
|
name := id.String()
|
||||||
if len(name) >= len(prefix) && prefix == name[:len(prefix)] {
|
if len(name) >= len(prefix) && prefix == name[:len(prefix)] {
|
||||||
if match.IsNull() {
|
if match.IsNull() {
|
||||||
|
@ -341,7 +341,7 @@ func (l *Lock) checkExistence(ctx context.Context) (bool, error) {
|
|||||||
|
|
||||||
exists := false
|
exists := false
|
||||||
|
|
||||||
err := l.repo.List(ctx, LockFile, func(id ID, size int64) error {
|
err := l.repo.List(ctx, LockFile, func(id ID, _ int64) error {
|
||||||
if id.Equal(*l.lockID) {
|
if id.Equal(*l.lockID) {
|
||||||
exists = true
|
exists = true
|
||||||
}
|
}
|
||||||
@ -415,7 +415,7 @@ func RemoveStaleLocks(ctx context.Context, repo Repository) (uint, error) {
|
|||||||
// RemoveAllLocks removes all locks forcefully.
|
// RemoveAllLocks removes all locks forcefully.
|
||||||
func RemoveAllLocks(ctx context.Context, repo Repository) (uint, error) {
|
func RemoveAllLocks(ctx context.Context, repo Repository) (uint, error) {
|
||||||
var processed uint32
|
var processed uint32
|
||||||
err := ParallelList(ctx, repo, LockFile, repo.Connections(), func(ctx context.Context, id ID, size int64) error {
|
err := ParallelList(ctx, repo, LockFile, repo.Connections(), func(ctx context.Context, id ID, _ int64) error {
|
||||||
err := repo.Backend().Remove(ctx, backend.Handle{Type: LockFile, Name: id.String()})
|
err := repo.Backend().Remove(ctx, backend.Handle{Type: LockFile, Name: id.String()})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
atomic.AddUint32(&processed, 1)
|
atomic.AddUint32(&processed, 1)
|
||||||
|
@ -83,7 +83,7 @@ func ForAllSnapshots(ctx context.Context, be Lister, loader LoaderUnpacked, excl
|
|||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
|
|
||||||
// For most snapshots decoding is nearly for free, thus just assume were only limited by IO
|
// For most snapshots decoding is nearly for free, thus just assume were only limited by IO
|
||||||
return ParallelList(ctx, be, SnapshotFile, loader.Connections(), func(ctx context.Context, id ID, size int64) error {
|
return ParallelList(ctx, be, SnapshotFile, loader.Connections(), func(ctx context.Context, id ID, _ int64) error {
|
||||||
if excludeIDs.Has(id) {
|
if excludeIDs.Has(id) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ type Restorer struct {
|
|||||||
SelectFilter func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool)
|
SelectFilter func(item string, dstpath string, node *restic.Node) (selectedForRestore bool, childMayBeSelected bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
var restorerAbortOnAllErrors = func(location string, err error) error { return err }
|
var restorerAbortOnAllErrors = func(_ string, err error) error { return err }
|
||||||
|
|
||||||
// NewRestorer creates a restorer preloaded with the content from the snapshot id.
|
// NewRestorer creates a restorer preloaded with the content from the snapshot id.
|
||||||
func NewRestorer(repo restic.Repository, sn *restic.Snapshot, sparse bool,
|
func NewRestorer(repo restic.Repository, sn *restic.Snapshot, sparse bool,
|
||||||
@ -239,7 +239,7 @@ func (res *Restorer) RestoreTo(ctx context.Context, dst string) error {
|
|||||||
|
|
||||||
// first tree pass: create directories and collect all files to restore
|
// first tree pass: create directories and collect all files to restore
|
||||||
_, err = res.traverseTree(ctx, dst, string(filepath.Separator), *res.sn.Tree, treeVisitor{
|
_, err = res.traverseTree(ctx, dst, string(filepath.Separator), *res.sn.Tree, treeVisitor{
|
||||||
enterDir: func(node *restic.Node, target, location string) error {
|
enterDir: func(_ *restic.Node, target, location string) error {
|
||||||
debug.Log("first pass, enterDir: mkdir %q, leaveDir should restore metadata", location)
|
debug.Log("first pass, enterDir: mkdir %q, leaveDir should restore metadata", location)
|
||||||
if res.progress != nil {
|
if res.progress != nil {
|
||||||
res.progress.AddFile(0)
|
res.progress.AddFile(0)
|
||||||
@ -366,7 +366,7 @@ func (res *Restorer) VerifyFiles(ctx context.Context, dst string) (int, error) {
|
|||||||
defer close(work)
|
defer close(work)
|
||||||
|
|
||||||
_, err := res.traverseTree(ctx, dst, string(filepath.Separator), *res.sn.Tree, treeVisitor{
|
_, err := res.traverseTree(ctx, dst, string(filepath.Separator), *res.sn.Tree, treeVisitor{
|
||||||
visitNode: func(node *restic.Node, target, location string) error {
|
visitNode: func(node *restic.Node, target, _ string) error {
|
||||||
if node.Type != "file" {
|
if node.Type != "file" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ func NewProgress(printer ProgressPrinter, interval time.Duration) *Progress {
|
|||||||
printer: printer,
|
printer: printer,
|
||||||
estimator: *newRateEstimator(time.Now()),
|
estimator: *newRateEstimator(time.Now()),
|
||||||
}
|
}
|
||||||
p.Updater = *progress.NewUpdater(interval, func(runtime time.Duration, final bool) {
|
p.Updater = *progress.NewUpdater(interval, func(_ time.Duration, final bool) {
|
||||||
if final {
|
if final {
|
||||||
p.printer.Reset()
|
p.printer.Reset()
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,13 +39,13 @@ func NewTreeRewriter(opts RewriteOpts) *TreeRewriter {
|
|||||||
}
|
}
|
||||||
// setup default implementations
|
// setup default implementations
|
||||||
if rw.opts.RewriteNode == nil {
|
if rw.opts.RewriteNode == nil {
|
||||||
rw.opts.RewriteNode = func(node *restic.Node, path string) *restic.Node {
|
rw.opts.RewriteNode = func(node *restic.Node, _ string) *restic.Node {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if rw.opts.RewriteFailedTree == nil {
|
if rw.opts.RewriteFailedTree == nil {
|
||||||
// fail with error by default
|
// fail with error by default
|
||||||
rw.opts.RewriteFailedTree = func(nodeID restic.ID, path string, err error) (restic.ID, error) {
|
rw.opts.RewriteFailedTree = func(_ restic.ID, _ string, err error) (restic.ID, error) {
|
||||||
return restic.ID{}, err
|
return restic.ID{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user