forked from TrueCloudLab/restic
Remove ctx from globalOptions
Previously the global context was either accessed via gopts.ctx, stored in a local variable and then used within that function or sometimes both. This makes it very hard to follow which ctx or a wrapped version of it reaches which method. Thus just drop the context from the globalOptions struct and pass it explicitly to every command line handler method.
This commit is contained in:
parent
ab819b2344
commit
985722b102
29 changed files with 280 additions and 278 deletions
|
@ -57,8 +57,9 @@ Exit status is 3 if some source data could not be read (incomplete snapshot crea
|
||||||
},
|
},
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
ctx := globalCtx()
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
cancelCtx, cancel := context.WithCancel(globalOptions.ctx)
|
cancelCtx, cancel := context.WithCancel(ctx)
|
||||||
defer func() {
|
defer func() {
|
||||||
// shutdown termstatus
|
// shutdown termstatus
|
||||||
cancel()
|
cancel()
|
||||||
|
@ -72,7 +73,7 @@ Exit status is 3 if some source data could not be read (incomplete snapshot crea
|
||||||
term.Run(cancelCtx)
|
term.Run(cancelCtx)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
return runBackup(backupOptions, globalOptions, term, args)
|
return runBackup(ctx, backupOptions, globalOptions, term, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,7 +528,7 @@ func findParentSnapshot(ctx context.Context, repo restic.Repository, opts Backup
|
||||||
return parentID, nil
|
return parentID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Terminal, args []string) error {
|
func runBackup(ctx context.Context, opts BackupOptions, gopts GlobalOptions, term *termstatus.Terminal, args []string) error {
|
||||||
err := opts.Check(gopts, args)
|
err := opts.Check(gopts, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -550,7 +551,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
||||||
Verbosef("open repository\n")
|
Verbosef("open repository\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -577,7 +578,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
||||||
|
|
||||||
progressReporter.SetMinUpdatePause(calculateProgressInterval(!gopts.Quiet, gopts.JSON))
|
progressReporter.SetMinUpdatePause(calculateProgressInterval(!gopts.Quiet, gopts.JSON))
|
||||||
|
|
||||||
wg, wgCtx := errgroup.WithContext(gopts.ctx)
|
wg, wgCtx := errgroup.WithContext(ctx)
|
||||||
cancelCtx, cancel := context.WithCancel(wgCtx)
|
cancelCtx, cancel := context.WithCancel(wgCtx)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
wg.Go(func() error { return progressReporter.Run(cancelCtx) })
|
wg.Go(func() error { return progressReporter.Run(cancelCtx) })
|
||||||
|
@ -585,7 +586,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
||||||
if !gopts.JSON {
|
if !gopts.JSON {
|
||||||
progressPrinter.V("lock repository")
|
progressPrinter.V("lock repository")
|
||||||
}
|
}
|
||||||
lock, err := lockRepo(gopts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -605,7 +606,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
||||||
|
|
||||||
var parentSnapshotID *restic.ID
|
var parentSnapshotID *restic.ID
|
||||||
if !opts.Stdin {
|
if !opts.Stdin {
|
||||||
parentSnapshotID, err = findParentSnapshot(gopts.ctx, repo, opts, targets, timeStamp)
|
parentSnapshotID, err = findParentSnapshot(ctx, repo, opts, targets, timeStamp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -622,7 +623,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
||||||
if !gopts.JSON {
|
if !gopts.JSON {
|
||||||
progressPrinter.V("load index files")
|
progressPrinter.V("load index files")
|
||||||
}
|
}
|
||||||
err = repo.LoadIndex(gopts.ctx)
|
err = repo.LoadIndex(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -727,7 +728,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
||||||
if !gopts.JSON {
|
if !gopts.JSON {
|
||||||
progressPrinter.V("start backup on %v", targets)
|
progressPrinter.V("start backup on %v", targets)
|
||||||
}
|
}
|
||||||
_, id, err := arch.Snapshot(gopts.ctx, targets, snapshotOpts)
|
_, id, err := arch.Snapshot(ctx, targets, snapshotOpts)
|
||||||
|
|
||||||
// cleanly shutdown all running goroutines
|
// cleanly shutdown all running goroutines
|
||||||
cancel()
|
cancel()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
@ -24,7 +25,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runCat(globalOptions, args)
|
return runCat(globalCtx(), globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,18 +33,18 @@ func init() {
|
||||||
cmdRoot.AddCommand(cmdCat)
|
cmdRoot.AddCommand(cmdCat)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCat(gopts GlobalOptions, args []string) error {
|
func runCat(ctx context.Context, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) < 1 || (args[0] != "masterkey" && args[0] != "config" && len(args) != 2) {
|
if len(args) < 1 || (args[0] != "masterkey" && args[0] != "config" && len(args) != 2) {
|
||||||
return errors.Fatal("type or ID not specified")
|
return errors.Fatal("type or ID not specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
lock, err := lockRepo(gopts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -62,7 +63,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find snapshot id with prefix
|
// find snapshot id with prefix
|
||||||
id, err = restic.FindSnapshot(gopts.ctx, repo.Backend(), args[1])
|
id, err = restic.FindSnapshot(ctx, repo.Backend(), args[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("could not find snapshot: %v\n", err)
|
return errors.Fatalf("could not find snapshot: %v\n", err)
|
||||||
}
|
}
|
||||||
|
@ -79,7 +80,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||||
Println(string(buf))
|
Println(string(buf))
|
||||||
return nil
|
return nil
|
||||||
case "index":
|
case "index":
|
||||||
buf, err := repo.LoadUnpacked(gopts.ctx, restic.IndexFile, id, nil)
|
buf, err := repo.LoadUnpacked(ctx, restic.IndexFile, id, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -87,7 +88,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||||
Println(string(buf))
|
Println(string(buf))
|
||||||
return nil
|
return nil
|
||||||
case "snapshot":
|
case "snapshot":
|
||||||
sn, err := restic.LoadSnapshot(gopts.ctx, repo, id)
|
sn, err := restic.LoadSnapshot(ctx, repo, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -100,7 +101,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||||
Println(string(buf))
|
Println(string(buf))
|
||||||
return nil
|
return nil
|
||||||
case "key":
|
case "key":
|
||||||
key, err := repository.LoadKey(gopts.ctx, repo, id.String())
|
key, err := repository.LoadKey(ctx, repo, id.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -121,7 +122,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||||
Println(string(buf))
|
Println(string(buf))
|
||||||
return nil
|
return nil
|
||||||
case "lock":
|
case "lock":
|
||||||
lock, err := restic.LoadLock(gopts.ctx, repo, id)
|
lock, err := restic.LoadLock(ctx, repo, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -136,7 +137,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||||
|
|
||||||
case "pack":
|
case "pack":
|
||||||
h := restic.Handle{Type: restic.PackFile, Name: id.String()}
|
h := restic.Handle{Type: restic.PackFile, Name: id.String()}
|
||||||
buf, err := backend.LoadAll(gopts.ctx, nil, repo.Backend(), h)
|
buf, err := backend.LoadAll(ctx, nil, repo.Backend(), h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -150,7 +151,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||||
return err
|
return err
|
||||||
|
|
||||||
case "blob":
|
case "blob":
|
||||||
err = repo.LoadIndex(gopts.ctx)
|
err = repo.LoadIndex(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -161,7 +162,7 @@ func runCat(gopts GlobalOptions, args []string) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
buf, err := repo.LoadBlob(gopts.ctx, t, id, nil)
|
buf, err := repo.LoadBlob(ctx, t, id, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -34,7 +35,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runCheck(checkOptions, globalOptions, args)
|
return runCheck(globalCtx(), checkOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return checkFlags(checkOptions)
|
return checkFlags(checkOptions)
|
||||||
|
@ -191,7 +192,7 @@ func prepareCheckCache(opts CheckOptions, gopts *GlobalOptions) (cleanup func())
|
||||||
return cleanup
|
return cleanup
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
func runCheck(ctx context.Context, opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
return errors.Fatal("the check command expects no arguments, only options - please see `restic help check` for usage and flags")
|
return errors.Fatal("the check command expects no arguments, only options - please see `restic help check` for usage and flags")
|
||||||
}
|
}
|
||||||
|
@ -202,14 +203,14 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||||
return code, nil
|
return code, nil
|
||||||
})
|
})
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
Verbosef("create exclusive lock for repository\n")
|
Verbosef("create exclusive lock for repository\n")
|
||||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
lock, err := lockRepoExclusive(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -217,13 +218,13 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
chkr := checker.New(repo, opts.CheckUnused)
|
chkr := checker.New(repo, opts.CheckUnused)
|
||||||
err = chkr.LoadSnapshots(gopts.ctx)
|
err = chkr.LoadSnapshots(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
Verbosef("load indexes\n")
|
Verbosef("load indexes\n")
|
||||||
hints, errs := chkr.LoadIndex(gopts.ctx)
|
hints, errs := chkr.LoadIndex(ctx)
|
||||||
|
|
||||||
errorsFound := false
|
errorsFound := false
|
||||||
suggestIndexRebuild := false
|
suggestIndexRebuild := false
|
||||||
|
@ -260,7 +261,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
|
|
||||||
Verbosef("check all packs\n")
|
Verbosef("check all packs\n")
|
||||||
go chkr.Packs(gopts.ctx, errChan)
|
go chkr.Packs(ctx, errChan)
|
||||||
|
|
||||||
for err := range errChan {
|
for err := range errChan {
|
||||||
if checker.IsOrphanedPack(err) {
|
if checker.IsOrphanedPack(err) {
|
||||||
|
@ -287,7 +288,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
bar := newProgressMax(!gopts.Quiet, 0, "snapshots")
|
bar := newProgressMax(!gopts.Quiet, 0, "snapshots")
|
||||||
defer bar.Done()
|
defer bar.Done()
|
||||||
chkr.Structure(gopts.ctx, bar, errChan)
|
chkr.Structure(ctx, bar, errChan)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for err := range errChan {
|
for err := range errChan {
|
||||||
|
@ -308,7 +309,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if opts.CheckUnused {
|
if opts.CheckUnused {
|
||||||
for _, id := range chkr.UnusedBlobs(gopts.ctx) {
|
for _, id := range chkr.UnusedBlobs(ctx) {
|
||||||
Verbosef("unused blob %v\n", id)
|
Verbosef("unused blob %v\n", id)
|
||||||
errorsFound = true
|
errorsFound = true
|
||||||
}
|
}
|
||||||
|
@ -320,7 +321,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error {
|
||||||
p := newProgressMax(!gopts.Quiet, packCount, "packs")
|
p := newProgressMax(!gopts.Quiet, packCount, "packs")
|
||||||
errChan := make(chan error)
|
errChan := make(chan error)
|
||||||
|
|
||||||
go chkr.ReadPacks(gopts.ctx, packs, p, errChan)
|
go chkr.ReadPacks(ctx, packs, p, errChan)
|
||||||
|
|
||||||
for err := range errChan {
|
for err := range errChan {
|
||||||
errorsFound = true
|
errorsFound = true
|
||||||
|
|
|
@ -32,7 +32,7 @@ This can be mitigated by the "--copy-chunker-params" option when initializing a
|
||||||
new destination repository using the "init" command.
|
new destination repository using the "init" command.
|
||||||
`,
|
`,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runCopy(copyOptions, globalOptions, args)
|
return runCopy(globalCtx(), copyOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func init() {
|
||||||
initMultiSnapshotFilterOptions(f, ©Options.snapshotFilterOptions, true)
|
initMultiSnapshotFilterOptions(f, ©Options.snapshotFilterOptions, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCopy(opts CopyOptions, gopts GlobalOptions, args []string) error {
|
func runCopy(ctx context.Context, opts CopyOptions, gopts GlobalOptions, args []string) error {
|
||||||
secondaryGopts, isFromRepo, err := fillSecondaryGlobalOpts(opts.secondaryRepoOptions, gopts, "destination")
|
secondaryGopts, isFromRepo, err := fillSecondaryGlobalOpts(opts.secondaryRepoOptions, gopts, "destination")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -62,13 +62,12 @@ func runCopy(opts CopyOptions, gopts GlobalOptions, args []string) error {
|
||||||
gopts, secondaryGopts = secondaryGopts, gopts
|
gopts, secondaryGopts = secondaryGopts, gopts
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := gopts.ctx
|
srcRepo, err := OpenRepository(ctx, gopts)
|
||||||
srcRepo, err := OpenRepository(gopts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dstRepo, err := OpenRepository(secondaryGopts)
|
dstRepo, err := OpenRepository(ctx, secondaryGopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runDebugDump(globalOptions, args)
|
return runDebugDump(globalCtx(), globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,18 +141,18 @@ func dumpIndexes(ctx context.Context, repo restic.Repository, wr io.Writer) erro
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDebugDump(gopts GlobalOptions, args []string) error {
|
func runDebugDump(ctx context.Context, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return errors.Fatal("type not specified")
|
return errors.Fatal("type not specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
lock, err := lockRepo(gopts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -163,20 +163,20 @@ func runDebugDump(gopts GlobalOptions, args []string) error {
|
||||||
|
|
||||||
switch tpe {
|
switch tpe {
|
||||||
case "indexes":
|
case "indexes":
|
||||||
return dumpIndexes(gopts.ctx, repo, gopts.stdout)
|
return dumpIndexes(ctx, repo, gopts.stdout)
|
||||||
case "snapshots":
|
case "snapshots":
|
||||||
return debugPrintSnapshots(gopts.ctx, repo, gopts.stdout)
|
return debugPrintSnapshots(ctx, repo, gopts.stdout)
|
||||||
case "packs":
|
case "packs":
|
||||||
return printPacks(gopts.ctx, repo, gopts.stdout)
|
return printPacks(ctx, repo, gopts.stdout)
|
||||||
case "all":
|
case "all":
|
||||||
Printf("snapshots:\n")
|
Printf("snapshots:\n")
|
||||||
err := debugPrintSnapshots(gopts.ctx, repo, gopts.stdout)
|
err := debugPrintSnapshots(ctx, repo, gopts.stdout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf("\nindexes:\n")
|
Printf("\nindexes:\n")
|
||||||
err = dumpIndexes(gopts.ctx, repo, gopts.stdout)
|
err = dumpIndexes(ctx, repo, gopts.stdout)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ var cmdDebugExamine = &cobra.Command{
|
||||||
Short: "Examine a pack file",
|
Short: "Examine a pack file",
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runDebugExamine(globalOptions, args)
|
return runDebugExamine(globalCtx(), globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,8 +426,8 @@ func storePlainBlob(id restic.ID, prefix string, plain []byte) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDebugExamine(gopts GlobalOptions, args []string) error {
|
func runDebugExamine(ctx context.Context, gopts GlobalOptions, args []string) error {
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -436,7 +436,7 @@ func runDebugExamine(gopts GlobalOptions, args []string) error {
|
||||||
for _, name := range args {
|
for _, name := range args {
|
||||||
id, err := restic.ParseID(name)
|
id, err := restic.ParseID(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
name, err = restic.Find(gopts.ctx, repo.Backend(), restic.PackFile, name)
|
name, err = restic.Find(ctx, repo.Backend(), restic.PackFile, name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
id, err = restic.ParseID(name)
|
id, err = restic.ParseID(name)
|
||||||
}
|
}
|
||||||
|
@ -453,20 +453,20 @@ func runDebugExamine(gopts GlobalOptions, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
lock, err := lockRepo(gopts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = repo.LoadIndex(gopts.ctx)
|
err = repo.LoadIndex(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
err := examinePack(gopts.ctx, repo, id)
|
err := examinePack(ctx, repo, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("error: %v\n", err)
|
Warnf("error: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runDiff(diffOptions, globalOptions, args)
|
return runDiff(globalCtx(), diffOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,13 +321,12 @@ func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, pref
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDiff(opts DiffOptions, gopts GlobalOptions, args []string) error {
|
func runDiff(ctx context.Context, opts DiffOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) != 2 {
|
if len(args) != 2 {
|
||||||
return errors.Fatalf("specify two snapshot IDs")
|
return errors.Fatalf("specify two snapshot IDs")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := gopts.ctx
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
repo, err := OpenRepository(gopts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runDump(dumpOptions, globalOptions, args)
|
return runDump(globalCtx(), dumpOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,9 +107,7 @@ func printFromTree(ctx context.Context, tree *restic.Tree, repo restic.Repositor
|
||||||
return fmt.Errorf("path %q not found in snapshot", item)
|
return fmt.Errorf("path %q not found in snapshot", item)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDump(opts DumpOptions, gopts GlobalOptions, args []string) error {
|
func runDump(ctx context.Context, opts DumpOptions, gopts GlobalOptions, args []string) error {
|
||||||
ctx := gopts.ctx
|
|
||||||
|
|
||||||
if len(args) != 2 {
|
if len(args) != 2 {
|
||||||
return errors.Fatal("no file and no snapshot ID specified")
|
return errors.Fatal("no file and no snapshot ID specified")
|
||||||
}
|
}
|
||||||
|
@ -127,7 +125,7 @@ func runDump(opts DumpOptions, gopts GlobalOptions, args []string) error {
|
||||||
|
|
||||||
splittedPath := splitPath(path.Clean(pathToPrint))
|
splittedPath := splitPath(path.Clean(pathToPrint))
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -154,7 +152,7 @@ func runDump(opts DumpOptions, gopts GlobalOptions, args []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sn, err := restic.LoadSnapshot(gopts.ctx, repo, id)
|
sn, err := restic.LoadSnapshot(ctx, repo, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Exitf(2, "loading snapshot %q failed: %v", snapshotIDString, err)
|
Exitf(2, "loading snapshot %q failed: %v", snapshotIDString, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runFind(findOptions, globalOptions, args)
|
return runFind(globalCtx(), findOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,7 +534,7 @@ func (f *Finder) findObjectsPacks(ctx context.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
func runFind(ctx context.Context, opts FindOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return errors.Fatal("wrong number of arguments")
|
return errors.Fatal("wrong number of arguments")
|
||||||
}
|
}
|
||||||
|
@ -568,29 +568,28 @@ func runFind(opts FindOptions, gopts GlobalOptions, args []string) error {
|
||||||
return errors.Fatal("cannot have several ID types")
|
return errors.Fatal("cannot have several ID types")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
lock, err := lockRepo(gopts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotLister, err := backend.MemorizeList(gopts.ctx, repo.Backend(), restic.SnapshotFile)
|
snapshotLister, err := backend.MemorizeList(ctx, repo.Backend(), restic.SnapshotFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = repo.LoadIndex(gopts.ctx); err != nil {
|
if err = repo.LoadIndex(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := gopts.ctx
|
|
||||||
f := &Finder{
|
f := &Finder{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
pat: pat,
|
pat: pat,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runForget(forgetOptions, globalOptions, args)
|
return runForget(globalCtx(), forgetOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,13 +99,13 @@ func init() {
|
||||||
addPruneOptions(cmdForget)
|
addPruneOptions(cmdForget)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
func runForget(ctx context.Context, opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
||||||
err := verifyPruneOptions(&pruneOptions)
|
err := verifyPruneOptions(&pruneOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -114,14 +115,13 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.DryRun || !gopts.NoLock {
|
if !opts.DryRun || !gopts.NoLock {
|
||||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
lock, err := lockRepoExclusive(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := gopts.ctx
|
|
||||||
var snapshots restic.Snapshots
|
var snapshots restic.Snapshots
|
||||||
removeSnIDs := restic.NewIDSet()
|
removeSnIDs := restic.NewIDSet()
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
||||||
|
|
||||||
if len(removeSnIDs) > 0 {
|
if len(removeSnIDs) > 0 {
|
||||||
if !opts.DryRun {
|
if !opts.DryRun {
|
||||||
err := DeleteFilesChecked(gopts, repo, removeSnIDs, restic.SnapshotFile)
|
err := DeleteFilesChecked(ctx, gopts, repo, removeSnIDs, restic.SnapshotFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error {
|
||||||
Verbosef("%d snapshots have been removed, running prune\n", len(removeSnIDs))
|
Verbosef("%d snapshots have been removed, running prune\n", len(removeSnIDs))
|
||||||
}
|
}
|
||||||
pruneOptions.DryRun = opts.DryRun
|
pruneOptions.DryRun = opts.DryRun
|
||||||
return runPruneWithRepo(pruneOptions, gopts, repo, removeSnIDs)
|
return runPruneWithRepo(ctx, pruneOptions, gopts, repo, removeSnIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/restic/chunker"
|
"github.com/restic/chunker"
|
||||||
|
@ -25,7 +26,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runInit(initOptions, globalOptions, args)
|
return runInit(globalCtx(), initOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ func init() {
|
||||||
f.StringVar(&initOptions.RepositoryVersion, "repository-version", "stable", "repository format version to use, allowed values are a format version, 'latest' and 'stable'")
|
f.StringVar(&initOptions.RepositoryVersion, "repository-version", "stable", "repository format version to use, allowed values are a format version, 'latest' and 'stable'")
|
||||||
}
|
}
|
||||||
|
|
||||||
func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
|
func runInit(ctx context.Context, opts InitOptions, gopts GlobalOptions, args []string) error {
|
||||||
var version uint
|
var version uint
|
||||||
if opts.RepositoryVersion == "latest" || opts.RepositoryVersion == "" {
|
if opts.RepositoryVersion == "latest" || opts.RepositoryVersion == "" {
|
||||||
version = restic.MaxRepoVersion
|
version = restic.MaxRepoVersion
|
||||||
|
@ -64,7 +65,7 @@ func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
|
||||||
return errors.Fatalf("only repository versions between %v and %v are allowed", restic.MinRepoVersion, restic.MaxRepoVersion)
|
return errors.Fatalf("only repository versions between %v and %v are allowed", restic.MinRepoVersion, restic.MaxRepoVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkerPolynomial, err := maybeReadChunkerPolynomial(opts, gopts)
|
chunkerPolynomial, err := maybeReadChunkerPolynomial(ctx, opts, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -81,7 +82,7 @@ func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
be, err := create(repo, gopts.extended)
|
be, err := create(ctx, repo, gopts.extended)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("create repository at %s failed: %v\n", location.StripPassword(gopts.Repo), err)
|
return errors.Fatalf("create repository at %s failed: %v\n", location.StripPassword(gopts.Repo), err)
|
||||||
}
|
}
|
||||||
|
@ -94,7 +95,7 @@ func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Init(gopts.ctx, version, gopts.password, chunkerPolynomial)
|
err = s.Init(ctx, version, gopts.password, chunkerPolynomial)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("create key in repository at %s failed: %v\n", location.StripPassword(gopts.Repo), err)
|
return errors.Fatalf("create key in repository at %s failed: %v\n", location.StripPassword(gopts.Repo), err)
|
||||||
}
|
}
|
||||||
|
@ -108,14 +109,14 @@ func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func maybeReadChunkerPolynomial(opts InitOptions, gopts GlobalOptions) (*chunker.Pol, error) {
|
func maybeReadChunkerPolynomial(ctx context.Context, opts InitOptions, gopts GlobalOptions) (*chunker.Pol, error) {
|
||||||
if opts.CopyChunkerParameters {
|
if opts.CopyChunkerParameters {
|
||||||
otherGopts, _, err := fillSecondaryGlobalOpts(opts.secondaryRepoOptions, gopts, "secondary")
|
otherGopts, _, err := fillSecondaryGlobalOpts(opts.secondaryRepoOptions, gopts, "secondary")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
otherRepo, err := OpenRepository(otherGopts)
|
otherRepo, err := OpenRepository(ctx, otherGopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runKey(globalOptions, args)
|
return runKey(globalCtx(), globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,13 +197,12 @@ func switchToNewKeyAndRemoveIfBroken(ctx context.Context, repo *repository.Repos
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runKey(gopts GlobalOptions, args []string) error {
|
func runKey(ctx context.Context, gopts GlobalOptions, args []string) error {
|
||||||
ctx := gopts.ctx
|
|
||||||
if len(args) < 1 || (args[0] == "remove" && len(args) != 2) || (args[0] != "remove" && len(args) != 1) {
|
if len(args) < 1 || (args[0] == "remove" && len(args) != 2) || (args[0] != "remove" && len(args) != 1) {
|
||||||
return errors.Fatal("wrong number of arguments")
|
return errors.Fatal("wrong number of arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/restic/restic/internal/errors"
|
"github.com/restic/restic/internal/errors"
|
||||||
"github.com/restic/restic/internal/repository"
|
"github.com/restic/restic/internal/repository"
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
|
@ -21,7 +23,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runList(cmd, globalOptions, args)
|
return runList(globalCtx(), cmd, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,18 +31,18 @@ func init() {
|
||||||
cmdRoot.AddCommand(cmdList)
|
cmdRoot.AddCommand(cmdList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runList(cmd *cobra.Command, opts GlobalOptions, args []string) error {
|
func runList(ctx context.Context, cmd *cobra.Command, opts GlobalOptions, args []string) error {
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
return errors.Fatal("type not specified, usage: " + cmd.Use)
|
return errors.Fatal("type not specified, usage: " + cmd.Use)
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(opts)
|
repo, err := OpenRepository(ctx, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !opts.NoLock && args[0] != "locks" {
|
if !opts.NoLock && args[0] != "locks" {
|
||||||
lock, err := lockRepo(opts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -60,11 +62,11 @@ func runList(cmd *cobra.Command, opts GlobalOptions, args []string) error {
|
||||||
case "locks":
|
case "locks":
|
||||||
t = restic.LockFile
|
t = restic.LockFile
|
||||||
case "blobs":
|
case "blobs":
|
||||||
return repository.ForAllIndexes(opts.ctx, repo, func(id restic.ID, idx *repository.Index, oldFormat bool, err error) error {
|
return repository.ForAllIndexes(ctx, repo, func(id restic.ID, idx *repository.Index, oldFormat bool, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
idx.Each(opts.ctx, func(blobs restic.PackedBlob) {
|
idx.Each(ctx, func(blobs restic.PackedBlob) {
|
||||||
Printf("%v %v\n", blobs.Type, blobs.ID)
|
Printf("%v %v\n", blobs.Type, blobs.ID)
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
|
@ -73,7 +75,7 @@ func runList(cmd *cobra.Command, opts GlobalOptions, args []string) error {
|
||||||
return errors.Fatal("invalid type")
|
return errors.Fatal("invalid type")
|
||||||
}
|
}
|
||||||
|
|
||||||
return repo.List(opts.ctx, t, func(id restic.ID, size int64) error {
|
return repo.List(ctx, t, func(id restic.ID, size int64) error {
|
||||||
Printf("%s\n", id)
|
Printf("%s\n", id)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -41,7 +42,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runLs(lsOptions, globalOptions, args)
|
return runLs(globalCtx(), lsOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +111,7 @@ func lsNodeJSON(enc *json.Encoder, path string, node *restic.Node) error {
|
||||||
return enc.Encode(n)
|
return enc.Encode(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runLs(opts LsOptions, gopts GlobalOptions, args []string) error {
|
func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return errors.Fatal("no snapshot ID specified, specify snapshot ID or use special ID 'latest'")
|
return errors.Fatal("no snapshot ID specified, specify snapshot ID or use special ID 'latest'")
|
||||||
}
|
}
|
||||||
|
@ -160,21 +161,20 @@ func runLs(opts LsOptions, gopts GlobalOptions, args []string) error {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotLister, err := backend.MemorizeList(gopts.ctx, repo.Backend(), restic.SnapshotFile)
|
snapshotLister, err := backend.MemorizeList(ctx, repo.Backend(), restic.SnapshotFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = repo.LoadIndex(gopts.ctx); err != nil {
|
if err = repo.LoadIndex(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := gopts.ctx
|
|
||||||
var (
|
var (
|
||||||
printSnapshot func(sn *restic.Snapshot)
|
printSnapshot func(sn *restic.Snapshot)
|
||||||
printNode func(path string, node *restic.Node)
|
printNode func(path string, node *restic.Node)
|
||||||
|
|
|
@ -24,7 +24,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runMigrate(migrateOptions, globalOptions, args)
|
return runMigrate(globalCtx(), migrateOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ func applyMigrations(ctx context.Context, opts MigrateOptions, gopts GlobalOptio
|
||||||
checkGopts := gopts
|
checkGopts := gopts
|
||||||
// the repository is already locked
|
// the repository is already locked
|
||||||
checkGopts.NoLock = true
|
checkGopts.NoLock = true
|
||||||
err = runCheck(checkOptions, checkGopts, []string{})
|
err = runCheck(ctx, checkOptions, checkGopts, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -116,21 +116,21 @@ func applyMigrations(ctx context.Context, opts MigrateOptions, gopts GlobalOptio
|
||||||
return firsterr
|
return firsterr
|
||||||
}
|
}
|
||||||
|
|
||||||
func runMigrate(opts MigrateOptions, gopts GlobalOptions, args []string) error {
|
func runMigrate(ctx context.Context, opts MigrateOptions, gopts GlobalOptions, args []string) error {
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
lock, err := lockRepoExclusive(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
return checkMigrations(gopts.ctx, repo)
|
return checkMigrations(ctx, repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
return applyMigrations(gopts.ctx, opts, gopts, repo, args)
|
return applyMigrations(ctx, opts, gopts, repo, args)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -66,7 +67,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runMount(mountOptions, globalOptions, args)
|
return runMount(globalCtx(), mountOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ func init() {
|
||||||
_ = mountFlags.MarkDeprecated("snapshot-template", "use --time-template")
|
_ = mountFlags.MarkDeprecated("snapshot-template", "use --time-template")
|
||||||
}
|
}
|
||||||
|
|
||||||
func runMount(opts MountOptions, gopts GlobalOptions, args []string) error {
|
func runMount(ctx context.Context, opts MountOptions, gopts GlobalOptions, args []string) error {
|
||||||
if opts.TimeTemplate == "" {
|
if opts.TimeTemplate == "" {
|
||||||
return errors.Fatal("time template string cannot be empty")
|
return errors.Fatal("time template string cannot be empty")
|
||||||
}
|
}
|
||||||
|
@ -114,20 +115,20 @@ func runMount(opts MountOptions, gopts GlobalOptions, args []string) error {
|
||||||
debug.Log("start mount")
|
debug.Log("start mount")
|
||||||
defer debug.Log("finish mount")
|
defer debug.Log("finish mount")
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
lock, err := lockRepo(gopts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = repo.LoadIndex(gopts.ctx)
|
err = repo.LoadIndex(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runPrune(pruneOptions, globalOptions)
|
return runPrune(globalCtx(), pruneOptions, globalOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ func verifyPruneOptions(opts *PruneOptions) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPrune(opts PruneOptions, gopts GlobalOptions) error {
|
func runPrune(ctx context.Context, opts PruneOptions, gopts GlobalOptions) error {
|
||||||
err := verifyPruneOptions(&opts)
|
err := verifyPruneOptions(&opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -144,7 +144,7 @@ func runPrune(opts PruneOptions, gopts GlobalOptions) error {
|
||||||
return errors.Fatal("disabled compression and `--repack-uncompressed` are mutually exclusive")
|
return errors.Fatal("disabled compression and `--repack-uncompressed` are mutually exclusive")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -165,16 +165,16 @@ func runPrune(opts PruneOptions, gopts GlobalOptions) error {
|
||||||
opts.unsafeRecovery = true
|
opts.unsafeRecovery = true
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
lock, err := lockRepoExclusive(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return runPruneWithRepo(opts, gopts, repo, restic.NewIDSet())
|
return runPruneWithRepo(ctx, opts, gopts, repo, restic.NewIDSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
func runPruneWithRepo(opts PruneOptions, gopts GlobalOptions, repo *repository.Repository, ignoreSnapshots restic.IDSet) error {
|
func runPruneWithRepo(ctx context.Context, opts PruneOptions, gopts GlobalOptions, repo *repository.Repository, ignoreSnapshots restic.IDSet) error {
|
||||||
// we do not need index updates while pruning!
|
// we do not need index updates while pruning!
|
||||||
repo.DisableAutoIndexUpdate()
|
repo.DisableAutoIndexUpdate()
|
||||||
|
|
||||||
|
@ -184,12 +184,12 @@ func runPruneWithRepo(opts PruneOptions, gopts GlobalOptions, repo *repository.R
|
||||||
|
|
||||||
Verbosef("loading indexes...\n")
|
Verbosef("loading indexes...\n")
|
||||||
// loading the index before the snapshots is ok, as we use an exclusive lock here
|
// loading the index before the snapshots is ok, as we use an exclusive lock here
|
||||||
err := repo.LoadIndex(gopts.ctx)
|
err := repo.LoadIndex(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
plan, stats, err := planPrune(opts, gopts, repo, ignoreSnapshots)
|
plan, stats, err := planPrune(ctx, opts, gopts, repo, ignoreSnapshots)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ func runPruneWithRepo(opts PruneOptions, gopts GlobalOptions, repo *repository.R
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return doPrune(opts, gopts, repo, plan)
|
return doPrune(ctx, opts, gopts, repo, plan)
|
||||||
}
|
}
|
||||||
|
|
||||||
type pruneStats struct {
|
type pruneStats struct {
|
||||||
|
@ -255,11 +255,10 @@ type packInfoWithID struct {
|
||||||
|
|
||||||
// planPrune selects which files to rewrite and which to delete and which blobs to keep.
|
// planPrune selects which files to rewrite and which to delete and which blobs to keep.
|
||||||
// Also some summary statistics are returned.
|
// Also some summary statistics are returned.
|
||||||
func planPrune(opts PruneOptions, gopts GlobalOptions, repo restic.Repository, ignoreSnapshots restic.IDSet) (prunePlan, pruneStats, error) {
|
func planPrune(ctx context.Context, opts PruneOptions, gopts GlobalOptions, repo restic.Repository, ignoreSnapshots restic.IDSet) (prunePlan, pruneStats, error) {
|
||||||
ctx := gopts.ctx
|
|
||||||
var stats pruneStats
|
var stats pruneStats
|
||||||
|
|
||||||
usedBlobs, err := getUsedBlobs(gopts, repo, ignoreSnapshots)
|
usedBlobs, err := getUsedBlobs(ctx, gopts, repo, ignoreSnapshots)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return prunePlan{}, stats, err
|
return prunePlan{}, stats, err
|
||||||
}
|
}
|
||||||
|
@ -652,9 +651,7 @@ func printPruneStats(gopts GlobalOptions, stats pruneStats) error {
|
||||||
// - rebuild the index while ignoring all files that will be deleted
|
// - rebuild the index while ignoring all files that will be deleted
|
||||||
// - delete the files
|
// - delete the files
|
||||||
// plan.removePacks and plan.ignorePacks are modified in this function.
|
// plan.removePacks and plan.ignorePacks are modified in this function.
|
||||||
func doPrune(opts PruneOptions, gopts GlobalOptions, repo restic.Repository, plan prunePlan) (err error) {
|
func doPrune(ctx context.Context, opts PruneOptions, gopts GlobalOptions, repo restic.Repository, plan prunePlan) (err error) {
|
||||||
ctx := gopts.ctx
|
|
||||||
|
|
||||||
if opts.DryRun {
|
if opts.DryRun {
|
||||||
if !gopts.JSON && gopts.verbosity >= 2 {
|
if !gopts.JSON && gopts.verbosity >= 2 {
|
||||||
if len(plan.removePacksFirst) > 0 {
|
if len(plan.removePacksFirst) > 0 {
|
||||||
|
@ -670,7 +667,7 @@ func doPrune(opts PruneOptions, gopts GlobalOptions, repo restic.Repository, pla
|
||||||
// unreferenced packs can be safely deleted first
|
// unreferenced packs can be safely deleted first
|
||||||
if len(plan.removePacksFirst) != 0 {
|
if len(plan.removePacksFirst) != 0 {
|
||||||
Verbosef("deleting unreferenced packs\n")
|
Verbosef("deleting unreferenced packs\n")
|
||||||
DeleteFiles(gopts, repo, plan.removePacksFirst, restic.PackFile)
|
DeleteFiles(ctx, gopts, repo, plan.removePacksFirst, restic.PackFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(plan.repackPacks) != 0 {
|
if len(plan.repackPacks) != 0 {
|
||||||
|
@ -703,12 +700,12 @@ func doPrune(opts PruneOptions, gopts GlobalOptions, repo restic.Repository, pla
|
||||||
if opts.unsafeRecovery {
|
if opts.unsafeRecovery {
|
||||||
Verbosef("deleting index files\n")
|
Verbosef("deleting index files\n")
|
||||||
indexFiles := repo.Index().(*repository.MasterIndex).IDs()
|
indexFiles := repo.Index().(*repository.MasterIndex).IDs()
|
||||||
err = DeleteFilesChecked(gopts, repo, indexFiles, restic.IndexFile)
|
err = DeleteFilesChecked(ctx, gopts, repo, indexFiles, restic.IndexFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("%s", err)
|
return errors.Fatalf("%s", err)
|
||||||
}
|
}
|
||||||
} else if len(plan.ignorePacks) != 0 {
|
} else if len(plan.ignorePacks) != 0 {
|
||||||
err = rebuildIndexFiles(gopts, repo, plan.ignorePacks, nil)
|
err = rebuildIndexFiles(ctx, gopts, repo, plan.ignorePacks, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("%s", err)
|
return errors.Fatalf("%s", err)
|
||||||
}
|
}
|
||||||
|
@ -716,11 +713,11 @@ func doPrune(opts PruneOptions, gopts GlobalOptions, repo restic.Repository, pla
|
||||||
|
|
||||||
if len(plan.removePacks) != 0 {
|
if len(plan.removePacks) != 0 {
|
||||||
Verbosef("removing %d old packs\n", len(plan.removePacks))
|
Verbosef("removing %d old packs\n", len(plan.removePacks))
|
||||||
DeleteFiles(gopts, repo, plan.removePacks, restic.PackFile)
|
DeleteFiles(ctx, gopts, repo, plan.removePacks, restic.PackFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.unsafeRecovery {
|
if opts.unsafeRecovery {
|
||||||
_, err = writeIndexFiles(gopts, repo, plan.ignorePacks, nil)
|
_, err = writeIndexFiles(ctx, gopts, repo, plan.ignorePacks, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("%s", err)
|
return errors.Fatalf("%s", err)
|
||||||
}
|
}
|
||||||
|
@ -730,31 +727,29 @@ func doPrune(opts PruneOptions, gopts GlobalOptions, repo restic.Repository, pla
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeIndexFiles(gopts GlobalOptions, repo restic.Repository, removePacks restic.IDSet, extraObsolete restic.IDs) (restic.IDSet, error) {
|
func writeIndexFiles(ctx context.Context, gopts GlobalOptions, repo restic.Repository, removePacks restic.IDSet, extraObsolete restic.IDs) (restic.IDSet, error) {
|
||||||
Verbosef("rebuilding index\n")
|
Verbosef("rebuilding index\n")
|
||||||
|
|
||||||
bar := newProgressMax(!gopts.Quiet, 0, "packs processed")
|
bar := newProgressMax(!gopts.Quiet, 0, "packs processed")
|
||||||
obsoleteIndexes, err := repo.Index().Save(gopts.ctx, repo, removePacks, extraObsolete, bar)
|
obsoleteIndexes, err := repo.Index().Save(ctx, repo, removePacks, extraObsolete, bar)
|
||||||
bar.Done()
|
bar.Done()
|
||||||
return obsoleteIndexes, err
|
return obsoleteIndexes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func rebuildIndexFiles(gopts GlobalOptions, repo restic.Repository, removePacks restic.IDSet, extraObsolete restic.IDs) error {
|
func rebuildIndexFiles(ctx context.Context, gopts GlobalOptions, repo restic.Repository, removePacks restic.IDSet, extraObsolete restic.IDs) error {
|
||||||
obsoleteIndexes, err := writeIndexFiles(gopts, repo, removePacks, extraObsolete)
|
obsoleteIndexes, err := writeIndexFiles(ctx, gopts, repo, removePacks, extraObsolete)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
Verbosef("deleting obsolete index files\n")
|
Verbosef("deleting obsolete index files\n")
|
||||||
return DeleteFilesChecked(gopts, repo, obsoleteIndexes, restic.IndexFile)
|
return DeleteFilesChecked(ctx, gopts, repo, obsoleteIndexes, restic.IndexFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUsedBlobs(gopts GlobalOptions, repo restic.Repository, ignoreSnapshots restic.IDSet) (usedBlobs restic.BlobSet, err error) {
|
func getUsedBlobs(ctx context.Context, gopts GlobalOptions, repo restic.Repository, ignoreSnapshots restic.IDSet) (usedBlobs restic.BlobSet, err error) {
|
||||||
ctx := gopts.ctx
|
|
||||||
|
|
||||||
var snapshotTrees restic.IDs
|
var snapshotTrees restic.IDs
|
||||||
Verbosef("loading all snapshots...\n")
|
Verbosef("loading all snapshots...\n")
|
||||||
err = restic.ForAllSnapshots(gopts.ctx, repo.Backend(), repo, ignoreSnapshots,
|
err = restic.ForAllSnapshots(ctx, repo.Backend(), repo, ignoreSnapshots,
|
||||||
func(id restic.ID, sn *restic.Snapshot, err error) error {
|
func(id restic.ID, sn *restic.Snapshot, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
debug.Log("failed to load snapshot %v (error %v)", id, err)
|
debug.Log("failed to load snapshot %v (error %v)", id, err)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/restic/restic/internal/pack"
|
"github.com/restic/restic/internal/pack"
|
||||||
"github.com/restic/restic/internal/repository"
|
"github.com/restic/restic/internal/repository"
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
|
@ -22,7 +24,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runRebuildIndex(rebuildIndexOptions, globalOptions)
|
return runRebuildIndex(globalCtx(), rebuildIndexOptions, globalOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,24 +42,22 @@ func init() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRebuildIndex(opts RebuildIndexOptions, gopts GlobalOptions) error {
|
func runRebuildIndex(ctx context.Context, opts RebuildIndexOptions, gopts GlobalOptions) error {
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
lock, err := lockRepoExclusive(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return rebuildIndex(opts, gopts, repo, restic.NewIDSet())
|
return rebuildIndex(ctx, opts, gopts, repo, restic.NewIDSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
func rebuildIndex(opts RebuildIndexOptions, gopts GlobalOptions, repo *repository.Repository, ignorePacks restic.IDSet) error {
|
func rebuildIndex(ctx context.Context, opts RebuildIndexOptions, gopts GlobalOptions, repo *repository.Repository, ignorePacks restic.IDSet) error {
|
||||||
ctx := gopts.ctx
|
|
||||||
|
|
||||||
var obsoleteIndexes restic.IDs
|
var obsoleteIndexes restic.IDs
|
||||||
packSizeFromList := make(map[restic.ID]int64)
|
packSizeFromList := make(map[restic.ID]int64)
|
||||||
packSizeFromIndex := make(map[restic.ID]int64)
|
packSizeFromIndex := make(map[restic.ID]int64)
|
||||||
|
@ -141,7 +141,7 @@ func rebuildIndex(opts RebuildIndexOptions, gopts GlobalOptions, repo *repositor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rebuildIndexFiles(gopts, repo, removePacks, obsoleteIndexes)
|
err = rebuildIndexFiles(ctx, gopts, repo, removePacks, obsoleteIndexes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runRecover(globalOptions)
|
return runRecover(globalCtx(), globalOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,30 +35,30 @@ func init() {
|
||||||
cmdRoot.AddCommand(cmdRecover)
|
cmdRoot.AddCommand(cmdRecover)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRecover(gopts GlobalOptions) error {
|
func runRecover(ctx context.Context, gopts GlobalOptions) error {
|
||||||
hostname, err := os.Hostname()
|
hostname, err := os.Hostname()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := lockRepo(gopts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotLister, err := backend.MemorizeList(gopts.ctx, repo.Backend(), restic.SnapshotFile)
|
snapshotLister, err := backend.MemorizeList(ctx, repo.Backend(), restic.SnapshotFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
Verbosef("load index files\n")
|
Verbosef("load index files\n")
|
||||||
if err = repo.LoadIndex(gopts.ctx); err != nil {
|
if err = repo.LoadIndex(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ func runRecover(gopts GlobalOptions) error {
|
||||||
// tree. If it is not referenced, we have a root tree.
|
// tree. If it is not referenced, we have a root tree.
|
||||||
trees := make(map[restic.ID]bool)
|
trees := make(map[restic.ID]bool)
|
||||||
|
|
||||||
repo.Index().Each(gopts.ctx, func(blob restic.PackedBlob) {
|
repo.Index().Each(ctx, func(blob restic.PackedBlob) {
|
||||||
if blob.Type == restic.TreeBlob {
|
if blob.Type == restic.TreeBlob {
|
||||||
trees[blob.Blob.ID] = false
|
trees[blob.Blob.ID] = false
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ func runRecover(gopts GlobalOptions) error {
|
||||||
Verbosef("load %d trees\n", len(trees))
|
Verbosef("load %d trees\n", len(trees))
|
||||||
bar := newProgressMax(!gopts.Quiet, uint64(len(trees)), "trees loaded")
|
bar := newProgressMax(!gopts.Quiet, uint64(len(trees)), "trees loaded")
|
||||||
for id := range trees {
|
for id := range trees {
|
||||||
tree, err := restic.LoadTree(gopts.ctx, repo, id)
|
tree, err := restic.LoadTree(ctx, repo, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Warnf("unable to load tree %v: %v\n", id.Str(), err)
|
Warnf("unable to load tree %v: %v\n", id.Str(), err)
|
||||||
continue
|
continue
|
||||||
|
@ -91,7 +91,7 @@ func runRecover(gopts GlobalOptions) error {
|
||||||
bar.Done()
|
bar.Done()
|
||||||
|
|
||||||
Verbosef("load snapshots\n")
|
Verbosef("load snapshots\n")
|
||||||
err = restic.ForAllSnapshots(gopts.ctx, snapshotLister, repo, nil, func(id restic.ID, sn *restic.Snapshot, err error) error {
|
err = restic.ForAllSnapshots(ctx, snapshotLister, repo, nil, func(id restic.ID, sn *restic.Snapshot, err error) error {
|
||||||
trees[*sn.Tree] = true
|
trees[*sn.Tree] = true
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -132,18 +132,18 @@ func runRecover(gopts GlobalOptions) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wg, ctx := errgroup.WithContext(gopts.ctx)
|
wg, wgCtx := errgroup.WithContext(ctx)
|
||||||
repo.StartPackUploader(ctx, wg)
|
repo.StartPackUploader(wgCtx, wg)
|
||||||
|
|
||||||
var treeID restic.ID
|
var treeID restic.ID
|
||||||
wg.Go(func() error {
|
wg.Go(func() error {
|
||||||
var err error
|
var err error
|
||||||
treeID, err = restic.SaveTree(ctx, repo, tree)
|
treeID, err = restic.SaveTree(wgCtx, repo, tree)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("unable to save new tree to the repository: %v", err)
|
return errors.Fatalf("unable to save new tree to the repository: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = repo.Flush(ctx)
|
err = repo.Flush(wgCtx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("unable to save blobs to the repository: %v", err)
|
return errors.Fatalf("unable to save blobs to the repository: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ func runRecover(gopts GlobalOptions) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return createSnapshot(gopts.ctx, "/recover", hostname, []string{"recovered"}, repo, &treeID)
|
return createSnapshot(ctx, "/recover", hostname, []string{"recovered"}, repo, &treeID)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runRestore(restoreOptions, globalOptions, args)
|
return runRestore(globalCtx(), restoreOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +64,7 @@ func init() {
|
||||||
flags.BoolVar(&restoreOptions.Verify, "verify", false, "verify restored files content")
|
flags.BoolVar(&restoreOptions.Verify, "verify", false, "verify restored files content")
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
func runRestore(ctx context.Context, opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||||
ctx := gopts.ctx
|
|
||||||
hasExcludes := len(opts.Exclude) > 0 || len(opts.InsensitiveExclude) > 0
|
hasExcludes := len(opts.Exclude) > 0 || len(opts.InsensitiveExclude) > 0
|
||||||
hasIncludes := len(opts.Include) > 0 || len(opts.InsensitiveInclude) > 0
|
hasIncludes := len(opts.Include) > 0 || len(opts.InsensitiveInclude) > 0
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
||||||
|
|
||||||
debug.Log("restore %v to %v", snapshotIDString, opts.Target)
|
debug.Log("restore %v to %v", snapshotIDString, opts.Target)
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runSelfUpdate(selfUpdateOptions, globalOptions, args)
|
return runSelfUpdate(globalCtx(), selfUpdateOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ func init() {
|
||||||
flags.StringVar(&selfUpdateOptions.Output, "output", "", "Save the downloaded file as `filename` (default: running binary itself)")
|
flags.StringVar(&selfUpdateOptions.Output, "output", "", "Save the downloaded file as `filename` (default: running binary itself)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func runSelfUpdate(opts SelfUpdateOptions, gopts GlobalOptions, args []string) error {
|
func runSelfUpdate(ctx context.Context, opts SelfUpdateOptions, gopts GlobalOptions, args []string) error {
|
||||||
if opts.Output == "" {
|
if opts.Output == "" {
|
||||||
file, err := os.Executable()
|
file, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -73,7 +74,7 @@ func runSelfUpdate(opts SelfUpdateOptions, gopts GlobalOptions, args []string) e
|
||||||
|
|
||||||
Verbosef("writing restic to %v\n", opts.Output)
|
Verbosef("writing restic to %v\n", opts.Output)
|
||||||
|
|
||||||
v, err := selfupdate.DownloadLatestStableRelease(gopts.ctx, opts.Output, version, Verbosef)
|
v, err := selfupdate.DownloadLatestStableRelease(ctx, opts.Output, version, Verbosef)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("unable to update restic: %v", err)
|
return errors.Fatalf("unable to update restic: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -25,7 +26,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runSnapshots(snapshotOptions, globalOptions, args)
|
return runSnapshots(globalCtx(), snapshotOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,21 +57,20 @@ func init() {
|
||||||
f.StringVarP(&snapshotOptions.GroupBy, "group-by", "g", "", "`group` snapshots by host, paths and/or tags, separated by comma")
|
f.StringVarP(&snapshotOptions.GroupBy, "group-by", "g", "", "`group` snapshots by host, paths and/or tags, separated by comma")
|
||||||
}
|
}
|
||||||
|
|
||||||
func runSnapshots(opts SnapshotOptions, gopts GlobalOptions, args []string) error {
|
func runSnapshots(ctx context.Context, opts SnapshotOptions, gopts GlobalOptions, args []string) error {
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
lock, err := lockRepo(gopts.ctx, repo)
|
lock, err := lockRepo(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := gopts.ctx
|
|
||||||
var snapshots restic.Snapshots
|
var snapshots restic.Snapshots
|
||||||
for sn := range FindFilteredSnapshots(ctx, repo.Backend(), repo, opts.Hosts, opts.Tags, opts.Paths, args) {
|
for sn := range FindFilteredSnapshots(ctx, repo.Backend(), repo, opts.Hosts, opts.Tags, opts.Paths, args) {
|
||||||
snapshots = append(snapshots, sn)
|
snapshots = append(snapshots, sn)
|
||||||
|
|
|
@ -47,7 +47,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runStats(globalOptions, args)
|
return runStats(globalCtx(), globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,14 +68,13 @@ func init() {
|
||||||
initMultiSnapshotFilterOptions(f, &statsOptions.snapshotFilterOptions, true)
|
initMultiSnapshotFilterOptions(f, &statsOptions.snapshotFilterOptions, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runStats(gopts GlobalOptions, args []string) error {
|
func runStats(ctx context.Context, gopts GlobalOptions, args []string) error {
|
||||||
err := verifyStatsInput(gopts, args)
|
err := verifyStatsInput(gopts, args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := gopts.ctx
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
repo, err := OpenRepository(gopts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -88,7 +87,7 @@ func runStats(gopts GlobalOptions, args []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snapshotLister, err := backend.MemorizeList(gopts.ctx, repo.Backend(), restic.SnapshotFile)
|
snapshotLister, err := backend.MemorizeList(ctx, repo.Backend(), restic.SnapshotFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runTag(tagOptions, globalOptions, args)
|
return runTag(globalCtx(), tagOptions, globalOptions, args)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ func changeTags(ctx context.Context, repo *repository.Repository, sn *restic.Sna
|
||||||
return changed, nil
|
return changed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTag(opts TagOptions, gopts GlobalOptions, args []string) error {
|
func runTag(ctx context.Context, opts TagOptions, gopts GlobalOptions, args []string) error {
|
||||||
if len(opts.SetTags) == 0 && len(opts.AddTags) == 0 && len(opts.RemoveTags) == 0 {
|
if len(opts.SetTags) == 0 && len(opts.AddTags) == 0 && len(opts.RemoveTags) == 0 {
|
||||||
return errors.Fatal("nothing to do!")
|
return errors.Fatal("nothing to do!")
|
||||||
}
|
}
|
||||||
|
@ -103,14 +103,14 @@ func runTag(opts TagOptions, gopts GlobalOptions, args []string) error {
|
||||||
return errors.Fatal("--set and --add/--remove cannot be given at the same time")
|
return errors.Fatal("--set and --add/--remove cannot be given at the same time")
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !gopts.NoLock {
|
if !gopts.NoLock {
|
||||||
Verbosef("create exclusive lock for repository\n")
|
Verbosef("create exclusive lock for repository\n")
|
||||||
lock, err := lockRepoExclusive(gopts.ctx, repo)
|
lock, err := lockRepoExclusive(ctx, repo)
|
||||||
defer unlockRepo(lock)
|
defer unlockRepo(lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -118,7 +118,6 @@ func runTag(opts TagOptions, gopts GlobalOptions, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
changeCnt := 0
|
changeCnt := 0
|
||||||
ctx := gopts.ctx
|
|
||||||
for sn := range FindFilteredSnapshots(ctx, repo.Backend(), repo, opts.Hosts, opts.Tags, opts.Paths, args) {
|
for sn := range FindFilteredSnapshots(ctx, repo.Backend(), repo, opts.Hosts, opts.Tags, opts.Paths, args) {
|
||||||
changed, err := changeTags(ctx, repo, sn, opts.SetTags.Flatten(), opts.AddTags.Flatten(), opts.RemoveTags.Flatten())
|
changed, err := changeTags(ctx, repo, sn, opts.SetTags.Flatten(), opts.AddTags.Flatten(), opts.RemoveTags.Flatten())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -18,7 +20,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
|
||||||
`,
|
`,
|
||||||
DisableAutoGenTag: true,
|
DisableAutoGenTag: true,
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return runUnlock(unlockOptions, globalOptions)
|
return runUnlock(globalCtx(), unlockOptions, globalOptions)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,8 +37,8 @@ func init() {
|
||||||
unlockCmd.Flags().BoolVar(&unlockOptions.RemoveAll, "remove-all", false, "remove all locks, even non-stale ones")
|
unlockCmd.Flags().BoolVar(&unlockOptions.RemoveAll, "remove-all", false, "remove all locks, even non-stale ones")
|
||||||
}
|
}
|
||||||
|
|
||||||
func runUnlock(opts UnlockOptions, gopts GlobalOptions) error {
|
func runUnlock(ctx context.Context, opts UnlockOptions, gopts GlobalOptions) error {
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(ctx, gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -46,7 +48,7 @@ func runUnlock(opts UnlockOptions, gopts GlobalOptions) error {
|
||||||
fn = restic.RemoveAllLocks
|
fn = restic.RemoveAllLocks
|
||||||
}
|
}
|
||||||
|
|
||||||
processed, err := fn(gopts.ctx, repo)
|
processed, err := fn(ctx, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
|
@ -8,22 +10,22 @@ import (
|
||||||
|
|
||||||
// DeleteFiles deletes the given fileList of fileType in parallel
|
// DeleteFiles deletes the given fileList of fileType in parallel
|
||||||
// it will print a warning if there is an error, but continue deleting the remaining files
|
// it will print a warning if there is an error, but continue deleting the remaining files
|
||||||
func DeleteFiles(gopts GlobalOptions, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) {
|
func DeleteFiles(ctx context.Context, gopts GlobalOptions, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) {
|
||||||
_ = deleteFiles(gopts, true, repo, fileList, fileType)
|
_ = deleteFiles(ctx, gopts, true, repo, fileList, fileType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteFilesChecked deletes the given fileList of fileType in parallel
|
// DeleteFilesChecked deletes the given fileList of fileType in parallel
|
||||||
// if an error occurs, it will cancel and return this error
|
// if an error occurs, it will cancel and return this error
|
||||||
func DeleteFilesChecked(gopts GlobalOptions, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) error {
|
func DeleteFilesChecked(ctx context.Context, gopts GlobalOptions, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) error {
|
||||||
return deleteFiles(gopts, false, repo, fileList, fileType)
|
return deleteFiles(ctx, gopts, false, repo, fileList, fileType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteFiles deletes the given fileList of fileType in parallel
|
// deleteFiles deletes the given fileList of fileType in parallel
|
||||||
// if ignoreError=true, it will print a warning if there was an error, else it will abort.
|
// if ignoreError=true, it will print a warning if there was an error, else it will abort.
|
||||||
func deleteFiles(gopts GlobalOptions, ignoreError bool, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) error {
|
func deleteFiles(ctx context.Context, gopts GlobalOptions, ignoreError bool, repo restic.Repository, fileList restic.IDSet, fileType restic.FileType) error {
|
||||||
totalCount := len(fileList)
|
totalCount := len(fileList)
|
||||||
fileChan := make(chan restic.ID)
|
fileChan := make(chan restic.ID)
|
||||||
wg, ctx := errgroup.WithContext(gopts.ctx)
|
wg, ctx := errgroup.WithContext(ctx)
|
||||||
wg.Go(func() error {
|
wg.Go(func() error {
|
||||||
defer close(fileChan)
|
defer close(fileChan)
|
||||||
for id := range fileList {
|
for id := range fileList {
|
||||||
|
|
|
@ -68,7 +68,6 @@ type GlobalOptions struct {
|
||||||
backend.TransportOptions
|
backend.TransportOptions
|
||||||
limiter.Limits
|
limiter.Limits
|
||||||
|
|
||||||
ctx context.Context
|
|
||||||
password string
|
password string
|
||||||
stdout io.Writer
|
stdout io.Writer
|
||||||
stderr io.Writer
|
stderr io.Writer
|
||||||
|
@ -93,10 +92,11 @@ var globalOptions = GlobalOptions{
|
||||||
}
|
}
|
||||||
|
|
||||||
var isReadingPassword bool
|
var isReadingPassword bool
|
||||||
|
var internalGlobalCtx context.Context
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
var cancel context.CancelFunc
|
var cancel context.CancelFunc
|
||||||
globalOptions.ctx, cancel = context.WithCancel(context.Background())
|
internalGlobalCtx, cancel = context.WithCancel(context.Background())
|
||||||
AddCleanupHandler(func(code int) (int, error) {
|
AddCleanupHandler(func(code int) (int, error) {
|
||||||
// Must be called before the unlock cleanup handler to ensure that the latter is
|
// Must be called before the unlock cleanup handler to ensure that the latter is
|
||||||
// not blocked due to limited number of backend connections, see #1434
|
// not blocked due to limited number of backend connections, see #1434
|
||||||
|
@ -145,6 +145,10 @@ func init() {
|
||||||
restoreTerminal()
|
restoreTerminal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func globalCtx() context.Context {
|
||||||
|
return internalGlobalCtx
|
||||||
|
}
|
||||||
|
|
||||||
// checkErrno returns nil when err is set to syscall.Errno(0), since this is no
|
// checkErrno returns nil when err is set to syscall.Errno(0), since this is no
|
||||||
// error condition.
|
// error condition.
|
||||||
func checkErrno(err error) error {
|
func checkErrno(err error) error {
|
||||||
|
@ -428,13 +432,13 @@ func ReadRepo(opts GlobalOptions) (string, error) {
|
||||||
const maxKeys = 20
|
const maxKeys = 20
|
||||||
|
|
||||||
// OpenRepository reads the password and opens the repository.
|
// OpenRepository reads the password and opens the repository.
|
||||||
func OpenRepository(opts GlobalOptions) (*repository.Repository, error) {
|
func OpenRepository(ctx context.Context, opts GlobalOptions) (*repository.Repository, error) {
|
||||||
repo, err := ReadRepo(opts)
|
repo, err := ReadRepo(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
be, err := open(repo, opts, opts.extended)
|
be, err := open(ctx, repo, opts, opts.extended)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -478,7 +482,7 @@ func OpenRepository(opts GlobalOptions) (*repository.Repository, error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.SearchKey(opts.ctx, opts.password, maxKeys, opts.KeyHint)
|
err = s.SearchKey(ctx, opts.password, maxKeys, opts.KeyHint)
|
||||||
if err != nil && passwordTriesLeft > 1 {
|
if err != nil && passwordTriesLeft > 1 {
|
||||||
opts.password = ""
|
opts.password = ""
|
||||||
fmt.Fprintf(os.Stderr, "%s. Try again\n", err)
|
fmt.Fprintf(os.Stderr, "%s. Try again\n", err)
|
||||||
|
@ -695,7 +699,7 @@ func parseConfig(loc location.Location, opts options.Options) (interface{}, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the backend specified by a location config.
|
// Open the backend specified by a location config.
|
||||||
func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend, error) {
|
func open(ctx context.Context, s string, gopts GlobalOptions, opts options.Options) (restic.Backend, error) {
|
||||||
debug.Log("parsing location %v", location.StripPassword(s))
|
debug.Log("parsing location %v", location.StripPassword(s))
|
||||||
loc, err := location.Parse(s)
|
loc, err := location.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -720,19 +724,19 @@ func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend,
|
||||||
|
|
||||||
switch loc.Scheme {
|
switch loc.Scheme {
|
||||||
case "local":
|
case "local":
|
||||||
be, err = local.Open(globalOptions.ctx, cfg.(local.Config))
|
be, err = local.Open(ctx, cfg.(local.Config))
|
||||||
case "sftp":
|
case "sftp":
|
||||||
be, err = sftp.Open(globalOptions.ctx, cfg.(sftp.Config))
|
be, err = sftp.Open(ctx, cfg.(sftp.Config))
|
||||||
case "s3":
|
case "s3":
|
||||||
be, err = s3.Open(globalOptions.ctx, cfg.(s3.Config), rt)
|
be, err = s3.Open(ctx, cfg.(s3.Config), rt)
|
||||||
case "gs":
|
case "gs":
|
||||||
be, err = gs.Open(cfg.(gs.Config), rt)
|
be, err = gs.Open(cfg.(gs.Config), rt)
|
||||||
case "azure":
|
case "azure":
|
||||||
be, err = azure.Open(cfg.(azure.Config), rt)
|
be, err = azure.Open(cfg.(azure.Config), rt)
|
||||||
case "swift":
|
case "swift":
|
||||||
be, err = swift.Open(globalOptions.ctx, cfg.(swift.Config), rt)
|
be, err = swift.Open(ctx, cfg.(swift.Config), rt)
|
||||||
case "b2":
|
case "b2":
|
||||||
be, err = b2.Open(globalOptions.ctx, cfg.(b2.Config), rt)
|
be, err = b2.Open(ctx, cfg.(b2.Config), rt)
|
||||||
case "rest":
|
case "rest":
|
||||||
be, err = rest.Open(cfg.(rest.Config), rt)
|
be, err = rest.Open(cfg.(rest.Config), rt)
|
||||||
case "rclone":
|
case "rclone":
|
||||||
|
@ -760,7 +764,7 @@ func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend,
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if config is there
|
// check if config is there
|
||||||
fi, err := be.Stat(globalOptions.ctx, restic.Handle{Type: restic.ConfigFile})
|
fi, err := be.Stat(ctx, restic.Handle{Type: restic.ConfigFile})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Fatalf("unable to open config file: %v\nIs there a repository at the following location?\n%v", err, location.StripPassword(s))
|
return nil, errors.Fatalf("unable to open config file: %v\nIs there a repository at the following location?\n%v", err, location.StripPassword(s))
|
||||||
}
|
}
|
||||||
|
@ -773,7 +777,7 @@ func open(s string, gopts GlobalOptions, opts options.Options) (restic.Backend,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the backend specified by URI.
|
// Create the backend specified by URI.
|
||||||
func create(s string, opts options.Options) (restic.Backend, error) {
|
func create(ctx context.Context, s string, opts options.Options) (restic.Backend, error) {
|
||||||
debug.Log("parsing location %v", s)
|
debug.Log("parsing location %v", s)
|
||||||
loc, err := location.Parse(s)
|
loc, err := location.Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -792,23 +796,23 @@ func create(s string, opts options.Options) (restic.Backend, error) {
|
||||||
|
|
||||||
switch loc.Scheme {
|
switch loc.Scheme {
|
||||||
case "local":
|
case "local":
|
||||||
return local.Create(globalOptions.ctx, cfg.(local.Config))
|
return local.Create(ctx, cfg.(local.Config))
|
||||||
case "sftp":
|
case "sftp":
|
||||||
return sftp.Create(globalOptions.ctx, cfg.(sftp.Config))
|
return sftp.Create(ctx, cfg.(sftp.Config))
|
||||||
case "s3":
|
case "s3":
|
||||||
return s3.Create(globalOptions.ctx, cfg.(s3.Config), rt)
|
return s3.Create(ctx, cfg.(s3.Config), rt)
|
||||||
case "gs":
|
case "gs":
|
||||||
return gs.Create(cfg.(gs.Config), rt)
|
return gs.Create(cfg.(gs.Config), rt)
|
||||||
case "azure":
|
case "azure":
|
||||||
return azure.Create(cfg.(azure.Config), rt)
|
return azure.Create(cfg.(azure.Config), rt)
|
||||||
case "swift":
|
case "swift":
|
||||||
return swift.Open(globalOptions.ctx, cfg.(swift.Config), rt)
|
return swift.Open(ctx, cfg.(swift.Config), rt)
|
||||||
case "b2":
|
case "b2":
|
||||||
return b2.Create(globalOptions.ctx, cfg.(b2.Config), rt)
|
return b2.Create(ctx, cfg.(b2.Config), rt)
|
||||||
case "rest":
|
case "rest":
|
||||||
return rest.Create(globalOptions.ctx, cfg.(rest.Config), rt)
|
return rest.Create(ctx, cfg.(rest.Config), rt)
|
||||||
case "rclone":
|
case "rclone":
|
||||||
return rclone.Create(globalOptions.ctx, cfg.(rclone.Config))
|
return rclone.Create(ctx, cfg.(rclone.Config))
|
||||||
}
|
}
|
||||||
|
|
||||||
debug.Log("invalid repository scheme: %v", s)
|
debug.Log("invalid repository scheme: %v", s)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -57,7 +58,7 @@ func testRunMount(t testing.TB, gopts GlobalOptions, dir string) {
|
||||||
opts := MountOptions{
|
opts := MountOptions{
|
||||||
TimeTemplate: time.RFC3339,
|
TimeTemplate: time.RFC3339,
|
||||||
}
|
}
|
||||||
rtest.OK(t, runMount(opts, gopts, []string{dir}))
|
rtest.OK(t, runMount(context.TODO(), opts, gopts, []string{dir}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunUmount(t testing.TB, gopts GlobalOptions, dir string) {
|
func testRunUmount(t testing.TB, gopts GlobalOptions, dir string) {
|
||||||
|
@ -119,7 +120,7 @@ func checkSnapshots(t testing.TB, global GlobalOptions, repo *repository.Reposit
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, id := range snapshotIDs {
|
for _, id := range snapshotIDs {
|
||||||
snapshot, err := restic.LoadSnapshot(global.ctx, repo, id)
|
snapshot, err := restic.LoadSnapshot(context.TODO(), repo, id)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
ts := snapshot.Time.Format(time.RFC3339)
|
ts := snapshot.Time.Format(time.RFC3339)
|
||||||
|
@ -160,7 +161,7 @@ func TestMount(t *testing.T) {
|
||||||
|
|
||||||
testRunInit(t, env.gopts)
|
testRunInit(t, env.gopts)
|
||||||
|
|
||||||
repo, err := OpenRepository(env.gopts)
|
repo, err := OpenRepository(context.TODO(), env.gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
checkSnapshots(t, env.gopts, repo, env.mountpoint, env.repo, []restic.ID{}, 0)
|
checkSnapshots(t, env.gopts, repo, env.mountpoint, env.repo, []restic.ID{}, 0)
|
||||||
|
@ -205,7 +206,7 @@ func TestMountSameTimestamps(t *testing.T) {
|
||||||
|
|
||||||
rtest.SetupTarTestFixture(t, env.base, filepath.Join("testdata", "repo-same-timestamps.tar.gz"))
|
rtest.SetupTarTestFixture(t, env.base, filepath.Join("testdata", "repo-same-timestamps.tar.gz"))
|
||||||
|
|
||||||
repo, err := OpenRepository(env.gopts)
|
repo, err := OpenRepository(context.TODO(), env.gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
ids := []restic.ID{
|
ids := []restic.ID{
|
||||||
|
|
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -193,7 +192,6 @@ func withTestEnvironment(t testing.TB) (env *testEnvironment, cleanup func()) {
|
||||||
Repo: env.repo,
|
Repo: env.repo,
|
||||||
Quiet: true,
|
Quiet: true,
|
||||||
CacheDir: env.cache,
|
CacheDir: env.cache,
|
||||||
ctx: context.Background(),
|
|
||||||
password: rtest.TestPassword,
|
password: rtest.TestPassword,
|
||||||
stdout: os.Stdout,
|
stdout: os.Stdout,
|
||||||
stderr: os.Stderr,
|
stderr: os.Stderr,
|
||||||
|
|
|
@ -52,12 +52,12 @@ func testRunInit(t testing.TB, opts GlobalOptions) {
|
||||||
restic.TestDisableCheckPolynomial(t)
|
restic.TestDisableCheckPolynomial(t)
|
||||||
restic.TestSetLockTimeout(t, 0)
|
restic.TestSetLockTimeout(t, 0)
|
||||||
|
|
||||||
rtest.OK(t, runInit(InitOptions{}, opts, nil))
|
rtest.OK(t, runInit(context.TODO(), InitOptions{}, opts, nil))
|
||||||
t.Logf("repository initialized at %v", opts.Repo)
|
t.Logf("repository initialized at %v", opts.Repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunBackupAssumeFailure(t testing.TB, dir string, target []string, opts BackupOptions, gopts GlobalOptions) error {
|
func testRunBackupAssumeFailure(t testing.TB, dir string, target []string, opts BackupOptions, gopts GlobalOptions) error {
|
||||||
ctx, cancel := context.WithCancel(gopts.ctx)
|
ctx, cancel := context.WithCancel(context.TODO())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
var wg errgroup.Group
|
var wg errgroup.Group
|
||||||
|
@ -71,7 +71,7 @@ func testRunBackupAssumeFailure(t testing.TB, dir string, target []string, opts
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
}
|
}
|
||||||
|
|
||||||
backupErr := runBackup(opts, gopts, term, target)
|
backupErr := runBackup(ctx, opts, gopts, term, target)
|
||||||
|
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ func testRunList(t testing.TB, tpe string, opts GlobalOptions) restic.IDs {
|
||||||
globalOptions.stdout = os.Stdout
|
globalOptions.stdout = os.Stdout
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rtest.OK(t, runList(cmdList, opts, []string{tpe}))
|
rtest.OK(t, runList(context.TODO(), cmdList, opts, []string{tpe}))
|
||||||
return parseIDsFromReader(t, buf)
|
return parseIDsFromReader(t, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ func testRunRestoreLatest(t testing.TB, gopts GlobalOptions, dir string, paths [
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
rtest.OK(t, runRestore(opts, gopts, []string{"latest"}))
|
rtest.OK(t, runRestore(context.TODO(), opts, gopts, []string{"latest"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunRestoreExcludes(t testing.TB, gopts GlobalOptions, dir string, snapshotID restic.ID, excludes []string) {
|
func testRunRestoreExcludes(t testing.TB, gopts GlobalOptions, dir string, snapshotID restic.ID, excludes []string) {
|
||||||
|
@ -121,7 +121,7 @@ func testRunRestoreExcludes(t testing.TB, gopts GlobalOptions, dir string, snaps
|
||||||
Exclude: excludes,
|
Exclude: excludes,
|
||||||
}
|
}
|
||||||
|
|
||||||
rtest.OK(t, runRestore(opts, gopts, []string{snapshotID.String()}))
|
rtest.OK(t, runRestore(context.TODO(), opts, gopts, []string{snapshotID.String()}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunRestoreIncludes(t testing.TB, gopts GlobalOptions, dir string, snapshotID restic.ID, includes []string) {
|
func testRunRestoreIncludes(t testing.TB, gopts GlobalOptions, dir string, snapshotID restic.ID, includes []string) {
|
||||||
|
@ -130,11 +130,11 @@ func testRunRestoreIncludes(t testing.TB, gopts GlobalOptions, dir string, snaps
|
||||||
Include: includes,
|
Include: includes,
|
||||||
}
|
}
|
||||||
|
|
||||||
rtest.OK(t, runRestore(opts, gopts, []string{snapshotID.String()}))
|
rtest.OK(t, runRestore(context.TODO(), opts, gopts, []string{snapshotID.String()}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunRestoreAssumeFailure(t testing.TB, snapshotID string, opts RestoreOptions, gopts GlobalOptions) error {
|
func testRunRestoreAssumeFailure(t testing.TB, snapshotID string, opts RestoreOptions, gopts GlobalOptions) error {
|
||||||
err := runRestore(opts, gopts, []string{snapshotID})
|
err := runRestore(context.TODO(), opts, gopts, []string{snapshotID})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ func testRunCheck(t testing.TB, gopts GlobalOptions) {
|
||||||
ReadData: true,
|
ReadData: true,
|
||||||
CheckUnused: true,
|
CheckUnused: true,
|
||||||
}
|
}
|
||||||
rtest.OK(t, runCheck(opts, gopts, nil))
|
rtest.OK(t, runCheck(context.TODO(), opts, gopts, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunCheckOutput(gopts GlobalOptions) (string, error) {
|
func testRunCheckOutput(gopts GlobalOptions) (string, error) {
|
||||||
|
@ -159,7 +159,7 @@ func testRunCheckOutput(gopts GlobalOptions) (string, error) {
|
||||||
ReadData: true,
|
ReadData: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := runCheck(opts, gopts, nil)
|
err := runCheck(context.TODO(), opts, gopts, nil)
|
||||||
return buf.String(), err
|
return buf.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ func testRunDiffOutput(gopts GlobalOptions, firstSnapshotID string, secondSnapsh
|
||||||
opts := DiffOptions{
|
opts := DiffOptions{
|
||||||
ShowMetadata: false,
|
ShowMetadata: false,
|
||||||
}
|
}
|
||||||
err := runDiff(opts, gopts, []string{firstSnapshotID, secondSnapshotID})
|
err := runDiff(context.TODO(), opts, gopts, []string{firstSnapshotID, secondSnapshotID})
|
||||||
return buf.String(), err
|
return buf.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +187,7 @@ func testRunRebuildIndex(t testing.TB, gopts GlobalOptions) {
|
||||||
globalOptions.stdout = os.Stdout
|
globalOptions.stdout = os.Stdout
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rtest.OK(t, runRebuildIndex(RebuildIndexOptions{}, gopts))
|
rtest.OK(t, runRebuildIndex(context.TODO(), RebuildIndexOptions{}, gopts))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunLs(t testing.TB, gopts GlobalOptions, snapshotID string) []string {
|
func testRunLs(t testing.TB, gopts GlobalOptions, snapshotID string) []string {
|
||||||
|
@ -202,7 +202,7 @@ func testRunLs(t testing.TB, gopts GlobalOptions, snapshotID string) []string {
|
||||||
|
|
||||||
opts := LsOptions{}
|
opts := LsOptions{}
|
||||||
|
|
||||||
rtest.OK(t, runLs(opts, gopts, []string{snapshotID}))
|
rtest.OK(t, runLs(context.TODO(), opts, gopts, []string{snapshotID}))
|
||||||
|
|
||||||
return strings.Split(buf.String(), "\n")
|
return strings.Split(buf.String(), "\n")
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ func testRunFind(t testing.TB, wantJSON bool, gopts GlobalOptions, pattern strin
|
||||||
|
|
||||||
opts := FindOptions{}
|
opts := FindOptions{}
|
||||||
|
|
||||||
rtest.OK(t, runFind(opts, gopts, []string{pattern}))
|
rtest.OK(t, runFind(context.TODO(), opts, gopts, []string{pattern}))
|
||||||
|
|
||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ func testRunSnapshots(t testing.TB, gopts GlobalOptions) (newest *Snapshot, snap
|
||||||
|
|
||||||
opts := SnapshotOptions{}
|
opts := SnapshotOptions{}
|
||||||
|
|
||||||
rtest.OK(t, runSnapshots(opts, globalOptions, []string{}))
|
rtest.OK(t, runSnapshots(context.TODO(), opts, globalOptions, []string{}))
|
||||||
|
|
||||||
snapshots := []Snapshot{}
|
snapshots := []Snapshot{}
|
||||||
rtest.OK(t, json.Unmarshal(buf.Bytes(), &snapshots))
|
rtest.OK(t, json.Unmarshal(buf.Bytes(), &snapshots))
|
||||||
|
@ -251,7 +251,7 @@ func testRunSnapshots(t testing.TB, gopts GlobalOptions) (newest *Snapshot, snap
|
||||||
|
|
||||||
func testRunForget(t testing.TB, gopts GlobalOptions, args ...string) {
|
func testRunForget(t testing.TB, gopts GlobalOptions, args ...string) {
|
||||||
opts := ForgetOptions{}
|
opts := ForgetOptions{}
|
||||||
rtest.OK(t, runForget(opts, gopts, args))
|
rtest.OK(t, runForget(context.TODO(), opts, gopts, args))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunForgetJSON(t testing.TB, gopts GlobalOptions, args ...string) {
|
func testRunForgetJSON(t testing.TB, gopts GlobalOptions, args ...string) {
|
||||||
|
@ -269,7 +269,7 @@ func testRunForgetJSON(t testing.TB, gopts GlobalOptions, args ...string) {
|
||||||
Last: 1,
|
Last: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
rtest.OK(t, runForget(opts, gopts, args))
|
rtest.OK(t, runForget(context.TODO(), opts, gopts, args))
|
||||||
|
|
||||||
var forgets []*ForgetGroup
|
var forgets []*ForgetGroup
|
||||||
rtest.OK(t, json.Unmarshal(buf.Bytes(), &forgets))
|
rtest.OK(t, json.Unmarshal(buf.Bytes(), &forgets))
|
||||||
|
@ -288,7 +288,7 @@ func testRunPrune(t testing.TB, gopts GlobalOptions, opts PruneOptions) {
|
||||||
defer func() {
|
defer func() {
|
||||||
gopts.backendTestHook = oldHook
|
gopts.backendTestHook = oldHook
|
||||||
}()
|
}()
|
||||||
rtest.OK(t, runPrune(opts, gopts))
|
rtest.OK(t, runPrune(context.TODO(), opts, gopts))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSetupBackupData(t testing.TB, env *testEnvironment) string {
|
func testSetupBackupData(t testing.TB, env *testEnvironment) string {
|
||||||
|
@ -437,11 +437,11 @@ func TestBackupNonExistingFile(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func removePacksExcept(gopts GlobalOptions, t *testing.T, keep restic.IDSet, removeTreePacks bool) {
|
func removePacksExcept(gopts GlobalOptions, t *testing.T, keep restic.IDSet, removeTreePacks bool) {
|
||||||
r, err := OpenRepository(gopts)
|
r, err := OpenRepository(context.TODO(), gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
// Get all tree packs
|
// Get all tree packs
|
||||||
rtest.OK(t, r.LoadIndex(gopts.ctx))
|
rtest.OK(t, r.LoadIndex(context.TODO()))
|
||||||
|
|
||||||
treePacks := restic.NewIDSet()
|
treePacks := restic.NewIDSet()
|
||||||
r.Index().Each(context.TODO(), func(pb restic.PackedBlob) {
|
r.Index().Each(context.TODO(), func(pb restic.PackedBlob) {
|
||||||
|
@ -451,11 +451,11 @@ func removePacksExcept(gopts GlobalOptions, t *testing.T, keep restic.IDSet, rem
|
||||||
})
|
})
|
||||||
|
|
||||||
// remove all packs containing data blobs
|
// remove all packs containing data blobs
|
||||||
rtest.OK(t, r.List(gopts.ctx, restic.PackFile, func(id restic.ID, size int64) error {
|
rtest.OK(t, r.List(context.TODO(), restic.PackFile, func(id restic.ID, size int64) error {
|
||||||
if treePacks.Has(id) != removeTreePacks || keep.Has(id) {
|
if treePacks.Has(id) != removeTreePacks || keep.Has(id) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return r.Backend().Remove(gopts.ctx, restic.Handle{Type: restic.PackFile, Name: id.String()})
|
return r.Backend().Remove(context.TODO(), restic.Handle{Type: restic.PackFile, Name: id.String()})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ func TestBackupSelfHealing(t *testing.T) {
|
||||||
|
|
||||||
testRunRebuildIndex(t, env.gopts)
|
testRunRebuildIndex(t, env.gopts)
|
||||||
// now the repo is also missing the data blob in the index; check should report this
|
// now the repo is also missing the data blob in the index; check should report this
|
||||||
rtest.Assert(t, runCheck(CheckOptions{}, env.gopts, nil) != nil,
|
rtest.Assert(t, runCheck(context.TODO(), CheckOptions{}, env.gopts, nil) != nil,
|
||||||
"check should have reported an error")
|
"check should have reported an error")
|
||||||
|
|
||||||
// second backup should report an error but "heal" this situation
|
// second backup should report an error but "heal" this situation
|
||||||
|
@ -502,9 +502,9 @@ func TestBackupTreeLoadError(t *testing.T) {
|
||||||
// Backup a subdirectory first, such that we can remove the tree pack for the subdirectory
|
// Backup a subdirectory first, such that we can remove the tree pack for the subdirectory
|
||||||
testRunBackup(t, env.testdata, []string{"test"}, opts, env.gopts)
|
testRunBackup(t, env.testdata, []string{"test"}, opts, env.gopts)
|
||||||
|
|
||||||
r, err := OpenRepository(env.gopts)
|
r, err := OpenRepository(context.TODO(), env.gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
rtest.OK(t, r.LoadIndex(env.gopts.ctx))
|
rtest.OK(t, r.LoadIndex(context.TODO()))
|
||||||
treePacks := restic.NewIDSet()
|
treePacks := restic.NewIDSet()
|
||||||
r.Index().Each(context.TODO(), func(pb restic.PackedBlob) {
|
r.Index().Each(context.TODO(), func(pb restic.PackedBlob) {
|
||||||
if pb.Type == restic.TreeBlob {
|
if pb.Type == restic.TreeBlob {
|
||||||
|
@ -517,11 +517,11 @@ func TestBackupTreeLoadError(t *testing.T) {
|
||||||
|
|
||||||
// delete the subdirectory pack first
|
// delete the subdirectory pack first
|
||||||
for id := range treePacks {
|
for id := range treePacks {
|
||||||
rtest.OK(t, r.Backend().Remove(env.gopts.ctx, restic.Handle{Type: restic.PackFile, Name: id.String()}))
|
rtest.OK(t, r.Backend().Remove(context.TODO(), restic.Handle{Type: restic.PackFile, Name: id.String()}))
|
||||||
}
|
}
|
||||||
testRunRebuildIndex(t, env.gopts)
|
testRunRebuildIndex(t, env.gopts)
|
||||||
// now the repo is missing the tree blob in the index; check should report this
|
// now the repo is missing the tree blob in the index; check should report this
|
||||||
rtest.Assert(t, runCheck(CheckOptions{}, env.gopts, nil) != nil, "check should have reported an error")
|
rtest.Assert(t, runCheck(context.TODO(), CheckOptions{}, env.gopts, nil) != nil, "check should have reported an error")
|
||||||
// second backup should report an error but "heal" this situation
|
// second backup should report an error but "heal" this situation
|
||||||
err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
||||||
rtest.Assert(t, err != nil, "backup should have reported an error for the subdirectory")
|
rtest.Assert(t, err != nil, "backup should have reported an error for the subdirectory")
|
||||||
|
@ -531,7 +531,7 @@ func TestBackupTreeLoadError(t *testing.T) {
|
||||||
removePacksExcept(env.gopts, t, restic.NewIDSet(), true)
|
removePacksExcept(env.gopts, t, restic.NewIDSet(), true)
|
||||||
testRunRebuildIndex(t, env.gopts)
|
testRunRebuildIndex(t, env.gopts)
|
||||||
// now the repo is also missing the data blob in the index; check should report this
|
// now the repo is also missing the data blob in the index; check should report this
|
||||||
rtest.Assert(t, runCheck(CheckOptions{}, env.gopts, nil) != nil, "check should have reported an error")
|
rtest.Assert(t, runCheck(context.TODO(), CheckOptions{}, env.gopts, nil) != nil, "check should have reported an error")
|
||||||
// second backup should report an error but "heal" this situation
|
// second backup should report an error but "heal" this situation
|
||||||
err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
err = testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{filepath.Base(env.testdata)}, opts, env.gopts)
|
||||||
rtest.Assert(t, err != nil, "backup should have reported an error")
|
rtest.Assert(t, err != nil, "backup should have reported an error")
|
||||||
|
@ -761,7 +761,7 @@ func testRunCopy(t testing.TB, srcGopts GlobalOptions, dstGopts GlobalOptions) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
rtest.OK(t, runCopy(copyOpts, gopts, nil))
|
rtest.OK(t, runCopy(context.TODO(), copyOpts, gopts, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCopy(t *testing.T) {
|
func TestCopy(t *testing.T) {
|
||||||
|
@ -903,15 +903,15 @@ func TestInitCopyChunkerParams(t *testing.T) {
|
||||||
password: env2.gopts.password,
|
password: env2.gopts.password,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
rtest.Assert(t, runInit(initOpts, env.gopts, nil) != nil, "expected invalid init options to fail")
|
rtest.Assert(t, runInit(context.TODO(), initOpts, env.gopts, nil) != nil, "expected invalid init options to fail")
|
||||||
|
|
||||||
initOpts.CopyChunkerParameters = true
|
initOpts.CopyChunkerParameters = true
|
||||||
rtest.OK(t, runInit(initOpts, env.gopts, nil))
|
rtest.OK(t, runInit(context.TODO(), initOpts, env.gopts, nil))
|
||||||
|
|
||||||
repo, err := OpenRepository(env.gopts)
|
repo, err := OpenRepository(context.TODO(), env.gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
otherRepo, err := OpenRepository(env2.gopts)
|
otherRepo, err := OpenRepository(context.TODO(), env2.gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
rtest.Assert(t, repo.Config().ChunkerPolynomial == otherRepo.Config().ChunkerPolynomial,
|
rtest.Assert(t, repo.Config().ChunkerPolynomial == otherRepo.Config().ChunkerPolynomial,
|
||||||
|
@ -920,7 +920,7 @@ func TestInitCopyChunkerParams(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunTag(t testing.TB, opts TagOptions, gopts GlobalOptions) {
|
func testRunTag(t testing.TB, opts TagOptions, gopts GlobalOptions) {
|
||||||
rtest.OK(t, runTag(opts, gopts, []string{}))
|
rtest.OK(t, runTag(context.TODO(), opts, gopts, []string{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTag(t *testing.T) {
|
func TestTag(t *testing.T) {
|
||||||
|
@ -1012,7 +1012,7 @@ func testRunKeyListOtherIDs(t testing.TB, gopts GlobalOptions) []string {
|
||||||
globalOptions.stdout = os.Stdout
|
globalOptions.stdout = os.Stdout
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rtest.OK(t, runKey(gopts, []string{"list"}))
|
rtest.OK(t, runKey(context.TODO(), gopts, []string{"list"}))
|
||||||
|
|
||||||
scanner := bufio.NewScanner(buf)
|
scanner := bufio.NewScanner(buf)
|
||||||
exp := regexp.MustCompile(`^ ([a-f0-9]+) `)
|
exp := regexp.MustCompile(`^ ([a-f0-9]+) `)
|
||||||
|
@ -1033,7 +1033,7 @@ func testRunKeyAddNewKey(t testing.TB, newPassword string, gopts GlobalOptions)
|
||||||
testKeyNewPassword = ""
|
testKeyNewPassword = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rtest.OK(t, runKey(gopts, []string{"add"}))
|
rtest.OK(t, runKey(context.TODO(), gopts, []string{"add"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunKeyAddNewKeyUserHost(t testing.TB, gopts GlobalOptions) {
|
func testRunKeyAddNewKeyUserHost(t testing.TB, gopts GlobalOptions) {
|
||||||
|
@ -1047,11 +1047,11 @@ func testRunKeyAddNewKeyUserHost(t testing.TB, gopts GlobalOptions) {
|
||||||
rtest.OK(t, cmdKey.Flags().Parse([]string{"--user=john", "--host=example.com"}))
|
rtest.OK(t, cmdKey.Flags().Parse([]string{"--user=john", "--host=example.com"}))
|
||||||
|
|
||||||
t.Log("adding key for john@example.com")
|
t.Log("adding key for john@example.com")
|
||||||
rtest.OK(t, runKey(gopts, []string{"add"}))
|
rtest.OK(t, runKey(context.TODO(), gopts, []string{"add"}))
|
||||||
|
|
||||||
repo, err := OpenRepository(gopts)
|
repo, err := OpenRepository(context.TODO(), gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
key, err := repository.SearchKey(gopts.ctx, repo, testKeyNewPassword, 2, "")
|
key, err := repository.SearchKey(context.TODO(), repo, testKeyNewPassword, 2, "")
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
rtest.Equals(t, "john", key.Username)
|
rtest.Equals(t, "john", key.Username)
|
||||||
|
@ -1064,13 +1064,13 @@ func testRunKeyPasswd(t testing.TB, newPassword string, gopts GlobalOptions) {
|
||||||
testKeyNewPassword = ""
|
testKeyNewPassword = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rtest.OK(t, runKey(gopts, []string{"passwd"}))
|
rtest.OK(t, runKey(context.TODO(), gopts, []string{"passwd"}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRunKeyRemove(t testing.TB, gopts GlobalOptions, IDs []string) {
|
func testRunKeyRemove(t testing.TB, gopts GlobalOptions, IDs []string) {
|
||||||
t.Logf("remove %d keys: %q\n", len(IDs), IDs)
|
t.Logf("remove %d keys: %q\n", len(IDs), IDs)
|
||||||
for _, id := range IDs {
|
for _, id := range IDs {
|
||||||
rtest.OK(t, runKey(gopts, []string{"remove", id}))
|
rtest.OK(t, runKey(context.TODO(), gopts, []string{"remove", id}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,7 +1100,7 @@ func TestKeyAddRemove(t *testing.T) {
|
||||||
|
|
||||||
env.gopts.password = passwordList[len(passwordList)-1]
|
env.gopts.password = passwordList[len(passwordList)-1]
|
||||||
t.Logf("testing access with last password %q\n", env.gopts.password)
|
t.Logf("testing access with last password %q\n", env.gopts.password)
|
||||||
rtest.OK(t, runKey(env.gopts, []string{"list"}))
|
rtest.OK(t, runKey(context.TODO(), env.gopts, []string{"list"}))
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
|
|
||||||
testRunKeyAddNewKeyUserHost(t, env.gopts)
|
testRunKeyAddNewKeyUserHost(t, env.gopts)
|
||||||
|
@ -1128,16 +1128,16 @@ func TestKeyProblems(t *testing.T) {
|
||||||
testKeyNewPassword = ""
|
testKeyNewPassword = ""
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err := runKey(env.gopts, []string{"passwd"})
|
err := runKey(context.TODO(), env.gopts, []string{"passwd"})
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
rtest.Assert(t, err != nil, "expected passwd change to fail")
|
rtest.Assert(t, err != nil, "expected passwd change to fail")
|
||||||
|
|
||||||
err = runKey(env.gopts, []string{"add"})
|
err = runKey(context.TODO(), env.gopts, []string{"add"})
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
rtest.Assert(t, err != nil, "expected key adding to fail")
|
rtest.Assert(t, err != nil, "expected key adding to fail")
|
||||||
|
|
||||||
t.Logf("testing access with initial password %q\n", env.gopts.password)
|
t.Logf("testing access with initial password %q\n", env.gopts.password)
|
||||||
rtest.OK(t, runKey(env.gopts, []string{"list"}))
|
rtest.OK(t, runKey(context.TODO(), env.gopts, []string{"list"}))
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1549,7 +1549,7 @@ func TestRebuildIndexFailsOnAppendOnly(t *testing.T) {
|
||||||
env.gopts.backendTestHook = func(r restic.Backend) (restic.Backend, error) {
|
env.gopts.backendTestHook = func(r restic.Backend) (restic.Backend, error) {
|
||||||
return &appendOnlyBackend{r}, nil
|
return &appendOnlyBackend{r}, nil
|
||||||
}
|
}
|
||||||
err := runRebuildIndex(RebuildIndexOptions{}, env.gopts)
|
err := runRebuildIndex(context.TODO(), RebuildIndexOptions{}, env.gopts)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected rebuildIndex to fail")
|
t.Error("expected rebuildIndex to fail")
|
||||||
}
|
}
|
||||||
|
@ -1645,18 +1645,18 @@ func testPrune(t *testing.T, pruneOpts PruneOptions, checkOpts CheckOptions) {
|
||||||
testRunForgetJSON(t, env.gopts)
|
testRunForgetJSON(t, env.gopts)
|
||||||
testRunForget(t, env.gopts, firstSnapshot[0].String())
|
testRunForget(t, env.gopts, firstSnapshot[0].String())
|
||||||
testRunPrune(t, env.gopts, pruneOpts)
|
testRunPrune(t, env.gopts, pruneOpts)
|
||||||
rtest.OK(t, runCheck(checkOpts, env.gopts, nil))
|
rtest.OK(t, runCheck(context.TODO(), checkOpts, env.gopts, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
var pruneDefaultOptions = PruneOptions{MaxUnused: "5%"}
|
var pruneDefaultOptions = PruneOptions{MaxUnused: "5%"}
|
||||||
|
|
||||||
func listPacks(gopts GlobalOptions, t *testing.T) restic.IDSet {
|
func listPacks(gopts GlobalOptions, t *testing.T) restic.IDSet {
|
||||||
r, err := OpenRepository(gopts)
|
r, err := OpenRepository(context.TODO(), gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
packs := restic.NewIDSet()
|
packs := restic.NewIDSet()
|
||||||
|
|
||||||
rtest.OK(t, r.List(gopts.ctx, restic.PackFile, func(id restic.ID, size int64) error {
|
rtest.OK(t, r.List(context.TODO(), restic.PackFile, func(id restic.ID, size int64) error {
|
||||||
packs.Insert(id)
|
packs.Insert(id)
|
||||||
return nil
|
return nil
|
||||||
}))
|
}))
|
||||||
|
@ -1697,7 +1697,7 @@ func TestPruneWithDamagedRepository(t *testing.T) {
|
||||||
env.gopts.backendTestHook = oldHook
|
env.gopts.backendTestHook = oldHook
|
||||||
}()
|
}()
|
||||||
// prune should fail
|
// prune should fail
|
||||||
rtest.Assert(t, runPrune(pruneDefaultOptions, env.gopts) == errorPacksMissing,
|
rtest.Assert(t, runPrune(context.TODO(), pruneDefaultOptions, env.gopts) == errorPacksMissing,
|
||||||
"prune should have reported index not complete error")
|
"prune should have reported index not complete error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1769,7 +1769,7 @@ func testEdgeCaseRepo(t *testing.T, tarfile string, optionsCheck CheckOptions, o
|
||||||
if checkOK {
|
if checkOK {
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
} else {
|
} else {
|
||||||
rtest.Assert(t, runCheck(optionsCheck, env.gopts, nil) != nil,
|
rtest.Assert(t, runCheck(context.TODO(), optionsCheck, env.gopts, nil) != nil,
|
||||||
"check should have reported an error")
|
"check should have reported an error")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1777,7 +1777,7 @@ func testEdgeCaseRepo(t *testing.T, tarfile string, optionsCheck CheckOptions, o
|
||||||
testRunPrune(t, env.gopts, optionsPrune)
|
testRunPrune(t, env.gopts, optionsPrune)
|
||||||
testRunCheck(t, env.gopts)
|
testRunCheck(t, env.gopts)
|
||||||
} else {
|
} else {
|
||||||
rtest.Assert(t, runPrune(optionsPrune, env.gopts) != nil,
|
rtest.Assert(t, runPrune(context.TODO(), optionsPrune, env.gopts) != nil,
|
||||||
"prune should have reported an error")
|
"prune should have reported an error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1848,10 +1848,10 @@ func TestListOnce(t *testing.T) {
|
||||||
testRunForgetJSON(t, env.gopts)
|
testRunForgetJSON(t, env.gopts)
|
||||||
testRunForget(t, env.gopts, firstSnapshot[0].String())
|
testRunForget(t, env.gopts, firstSnapshot[0].String())
|
||||||
testRunPrune(t, env.gopts, pruneOpts)
|
testRunPrune(t, env.gopts, pruneOpts)
|
||||||
rtest.OK(t, runCheck(checkOpts, env.gopts, nil))
|
rtest.OK(t, runCheck(context.TODO(), checkOpts, env.gopts, nil))
|
||||||
|
|
||||||
rtest.OK(t, runRebuildIndex(RebuildIndexOptions{}, env.gopts))
|
rtest.OK(t, runRebuildIndex(context.TODO(), RebuildIndexOptions{}, env.gopts))
|
||||||
rtest.OK(t, runRebuildIndex(RebuildIndexOptions{ReadAllPacks: true}, env.gopts))
|
rtest.OK(t, runRebuildIndex(context.TODO(), RebuildIndexOptions{ReadAllPacks: true}, env.gopts))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHardLink(t *testing.T) {
|
func TestHardLink(t *testing.T) {
|
||||||
|
@ -2204,7 +2204,7 @@ func TestFindListOnce(t *testing.T) {
|
||||||
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "3")}, opts, env.gopts)
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "3")}, opts, env.gopts)
|
||||||
thirdSnapshot := restic.NewIDSet(testRunList(t, "snapshots", env.gopts)...)
|
thirdSnapshot := restic.NewIDSet(testRunList(t, "snapshots", env.gopts)...)
|
||||||
|
|
||||||
repo, err := OpenRepository(env.gopts)
|
repo, err := OpenRepository(context.TODO(), env.gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
|
|
||||||
snapshotIDs := restic.NewIDSet()
|
snapshotIDs := restic.NewIDSet()
|
||||||
|
|
Loading…
Reference in a new issue