diff --git a/cmd/restic/cmd_backup.go b/cmd/restic/cmd_backup.go index c866e788a..48a607ecb 100644 --- a/cmd/restic/cmd_backup.go +++ b/cmd/restic/cmd_backup.go @@ -2,7 +2,6 @@ package main import ( "bufio" - "context" "fmt" "io" "os" @@ -256,7 +255,7 @@ func readBackupFromStdin(opts BackupOptions, gopts GlobalOptions, args []string) return err } - err = repo.LoadIndex(context.TODO()) + err = repo.LoadIndex(gopts.ctx) if err != nil { return err } @@ -267,7 +266,7 @@ func readBackupFromStdin(opts BackupOptions, gopts GlobalOptions, args []string) Hostname: opts.Hostname, } - _, id, err := r.Archive(context.TODO(), opts.StdinFilename, os.Stdin, newArchiveStdinProgress(gopts)) + _, id, err := r.Archive(gopts.ctx, opts.StdinFilename, os.Stdin, newArchiveStdinProgress(gopts)) if err != nil { return err } @@ -404,7 +403,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, args []string) error { rejectFuncs = append(rejectFuncs, f) } - err = repo.LoadIndex(context.TODO()) + err = repo.LoadIndex(gopts.ctx) if err != nil { return err } @@ -423,7 +422,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, args []string) error { // Find last snapshot to set it as parent, if not already set if !opts.Force && parentSnapshotID == nil { - id, err := restic.FindLatestSnapshot(context.TODO(), repo, target, []restic.TagList{}, opts.Hostname) + id, err := restic.FindLatestSnapshot(gopts.ctx, repo, target, []restic.TagList{}, opts.Hostname) if err == nil { parentSnapshotID = &id } else if err != restic.ErrNoSnapshotFound { @@ -469,7 +468,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, args []string) error { } } - _, id, err := arch.Snapshot(context.TODO(), newArchiveProgress(gopts, stat), target, opts.Tags, opts.Hostname, parentSnapshotID, timeStamp) + _, id, err := arch.Snapshot(gopts.ctx, newArchiveProgress(gopts, stat), target, opts.Tags, opts.Hostname, parentSnapshotID, timeStamp) if err != nil { return err } diff --git a/cmd/restic/cmd_cat.go b/cmd/restic/cmd_cat.go index 8926f11a5..7e66af734 100644 --- a/cmd/restic/cmd_cat.go +++ b/cmd/restic/cmd_cat.go @@ -1,7 +1,6 @@ package main import ( - "context" "encoding/json" "fmt" "os" @@ -75,7 +74,7 @@ func runCat(gopts GlobalOptions, args []string) error { fmt.Println(string(buf)) return nil case "index": - buf, err := repo.LoadAndDecrypt(context.TODO(), restic.IndexFile, id) + buf, err := repo.LoadAndDecrypt(gopts.ctx, restic.IndexFile, id) if err != nil { return err } @@ -85,7 +84,7 @@ func runCat(gopts GlobalOptions, args []string) error { case "snapshot": sn := &restic.Snapshot{} - err = repo.LoadJSONUnpacked(context.TODO(), restic.SnapshotFile, id, sn) + err = repo.LoadJSONUnpacked(gopts.ctx, restic.SnapshotFile, id, sn) if err != nil { return err } @@ -100,7 +99,7 @@ func runCat(gopts GlobalOptions, args []string) error { return nil case "key": h := restic.Handle{Type: restic.KeyFile, Name: id.String()} - buf, err := backend.LoadAll(context.TODO(), repo.Backend(), h) + buf, err := backend.LoadAll(gopts.ctx, repo.Backend(), h) if err != nil { return err } @@ -127,7 +126,7 @@ func runCat(gopts GlobalOptions, args []string) error { fmt.Println(string(buf)) return nil case "lock": - lock, err := restic.LoadLock(context.TODO(), repo, id) + lock, err := restic.LoadLock(gopts.ctx, repo, id) if err != nil { return err } @@ -143,7 +142,7 @@ func runCat(gopts GlobalOptions, args []string) error { } // load index, handle all the other types - err = repo.LoadIndex(context.TODO()) + err = repo.LoadIndex(gopts.ctx) if err != nil { return err } @@ -151,7 +150,7 @@ func runCat(gopts GlobalOptions, args []string) error { switch tpe { case "pack": h := restic.Handle{Type: restic.DataFile, Name: id.String()} - buf, err := backend.LoadAll(context.TODO(), repo.Backend(), h) + buf, err := backend.LoadAll(gopts.ctx, repo.Backend(), h) if err != nil { return err } @@ -173,7 +172,7 @@ func runCat(gopts GlobalOptions, args []string) error { blob := list[0] buf := make([]byte, blob.Length) - n, err := repo.LoadBlob(context.TODO(), t, id, buf) + n, err := repo.LoadBlob(gopts.ctx, t, id, buf) if err != nil { return err } diff --git a/cmd/restic/cmd_check.go b/cmd/restic/cmd_check.go index e1fd1208f..9be7c2ee2 100644 --- a/cmd/restic/cmd_check.go +++ b/cmd/restic/cmd_check.go @@ -1,7 +1,6 @@ package main import ( - "context" "fmt" "os" "time" @@ -104,7 +103,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error { chkr := checker.New(repo) Verbosef("load indexes\n") - hints, errs := chkr.LoadIndex(context.TODO()) + hints, errs := chkr.LoadIndex(gopts.ctx) dupFound := false for _, hint := range hints { @@ -129,7 +128,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error { errChan := make(chan error) Verbosef("check all packs\n") - go chkr.Packs(context.TODO(), errChan) + go chkr.Packs(gopts.ctx, errChan) for err := range errChan { errorsFound = true @@ -138,7 +137,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error { Verbosef("check snapshots, trees and blobs\n") errChan = make(chan error) - go chkr.Structure(context.TODO(), errChan) + go chkr.Structure(gopts.ctx, errChan) for err := range errChan { errorsFound = true @@ -165,7 +164,7 @@ func runCheck(opts CheckOptions, gopts GlobalOptions, args []string) error { p := newReadProgress(gopts, restic.Stat{Blobs: chkr.CountPacks()}) errChan := make(chan error) - go chkr.ReadData(context.TODO(), p, errChan) + go chkr.ReadData(gopts.ctx, p, errChan) for err := range errChan { errorsFound = true diff --git a/cmd/restic/cmd_debug.go b/cmd/restic/cmd_debug.go index 6a06e96ed..9ac7abad3 100644 --- a/cmd/restic/cmd_debug.go +++ b/cmd/restic/cmd_debug.go @@ -183,7 +183,7 @@ func runDebugDump(gopts GlobalOptions, args []string) error { } } - err = repo.LoadIndex(context.TODO()) + err = repo.LoadIndex(gopts.ctx) if err != nil { return err } diff --git a/cmd/restic/cmd_dump.go b/cmd/restic/cmd_dump.go index 7d07552d2..eb8250979 100644 --- a/cmd/restic/cmd_dump.go +++ b/cmd/restic/cmd_dump.go @@ -162,7 +162,7 @@ func runDump(opts DumpOptions, gopts GlobalOptions, args []string) error { } } - sn, err := restic.LoadSnapshot(context.TODO(), repo, id) + sn, err := restic.LoadSnapshot(gopts.ctx, repo, id) if err != nil { Exitf(2, "loading snapshot %q failed: %v", snapshotIDString, err) } diff --git a/cmd/restic/cmd_find.go b/cmd/restic/cmd_find.go index 16e631ef9..6ec8f116f 100644 --- a/cmd/restic/cmd_find.go +++ b/cmd/restic/cmd_find.go @@ -180,7 +180,7 @@ type Finder struct { notfound restic.IDSet } -func (f *Finder) findInTree(treeID restic.ID, prefix string) error { +func (f *Finder) findInTree(ctx context.Context, treeID restic.ID, prefix string) error { if f.notfound.Has(treeID) { debug.Log("%v skipping tree %v, has already been checked", prefix, treeID.Str()) return nil @@ -188,7 +188,7 @@ func (f *Finder) findInTree(treeID restic.ID, prefix string) error { debug.Log("%v checking tree %v\n", prefix, treeID.Str()) - tree, err := f.repo.LoadTree(context.TODO(), treeID) + tree, err := f.repo.LoadTree(ctx, treeID) if err != nil { return err } @@ -224,7 +224,7 @@ func (f *Finder) findInTree(treeID restic.ID, prefix string) error { } if node.Type == "dir" { - if err := f.findInTree(*node.Subtree, filepath.Join(prefix, node.Name)); err != nil { + if err := f.findInTree(ctx, *node.Subtree, filepath.Join(prefix, node.Name)); err != nil { return err } } @@ -237,11 +237,11 @@ func (f *Finder) findInTree(treeID restic.ID, prefix string) error { return nil } -func (f *Finder) findInSnapshot(sn *restic.Snapshot) error { +func (f *Finder) findInSnapshot(ctx context.Context, sn *restic.Snapshot) error { debug.Log("searching in snapshot %s\n for entries within [%s %s]", sn.ID(), f.pat.oldest, f.pat.newest) f.out.newsn = sn - if err := f.findInTree(*sn.Tree, string(filepath.Separator)); err != nil { + if err := f.findInTree(ctx, *sn.Tree, string(filepath.Separator)); err != nil { return err } return nil @@ -284,7 +284,7 @@ func runFind(opts FindOptions, gopts GlobalOptions, args []string) error { } } - if err = repo.LoadIndex(context.TODO()); err != nil { + if err = repo.LoadIndex(gopts.ctx); err != nil { return err } @@ -298,7 +298,7 @@ func runFind(opts FindOptions, gopts GlobalOptions, args []string) error { notfound: restic.NewIDSet(), } for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, opts.Snapshots) { - if err = f.findInSnapshot(sn); err != nil { + if err = f.findInSnapshot(ctx, sn); err != nil { return err } } diff --git a/cmd/restic/cmd_forget.go b/cmd/restic/cmd_forget.go index 128b73905..00b573a0f 100644 --- a/cmd/restic/cmd_forget.go +++ b/cmd/restic/cmd_forget.go @@ -125,7 +125,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error { // When explicit snapshots args are given, remove them immediately. if !opts.DryRun { h := restic.Handle{Type: restic.SnapshotFile, Name: sn.ID().String()} - if err = repo.Backend().Remove(context.TODO(), h); err != nil { + if err = repo.Backend().Remove(gopts.ctx, h); err != nil { return err } Verbosef("removed snapshot %v\n", sn.ID().Str()) @@ -223,7 +223,7 @@ func runForget(opts ForgetOptions, gopts GlobalOptions, args []string) error { if !opts.DryRun { for _, sn := range remove { h := restic.Handle{Type: restic.SnapshotFile, Name: sn.ID().String()} - err = repo.Backend().Remove(context.TODO(), h) + err = repo.Backend().Remove(gopts.ctx, h) if err != nil { return err } diff --git a/cmd/restic/cmd_init.go b/cmd/restic/cmd_init.go index d4bcd9a0e..ed349bb71 100644 --- a/cmd/restic/cmd_init.go +++ b/cmd/restic/cmd_init.go @@ -1,8 +1,6 @@ package main import ( - "context" - "github.com/restic/restic/internal/errors" "github.com/restic/restic/internal/repository" @@ -44,7 +42,7 @@ func runInit(gopts GlobalOptions, args []string) error { s := repository.New(be) - err = s.Init(context.TODO(), gopts.password) + err = s.Init(gopts.ctx, gopts.password) if err != nil { return errors.Fatalf("create key in backend at %s failed: %v\n", gopts.Repo, err) } diff --git a/cmd/restic/cmd_key.go b/cmd/restic/cmd_key.go index 1fbbd0f3f..e89a69b63 100644 --- a/cmd/restic/cmd_key.go +++ b/cmd/restic/cmd_key.go @@ -76,7 +76,7 @@ func addKey(gopts GlobalOptions, repo *repository.Repository) error { return err } - id, err := repository.AddKey(context.TODO(), repo, pw, repo.Key()) + id, err := repository.AddKey(gopts.ctx, repo, pw, repo.Key()) if err != nil { return errors.Fatalf("creating new key failed: %v\n", err) } @@ -86,13 +86,13 @@ func addKey(gopts GlobalOptions, repo *repository.Repository) error { return nil } -func deleteKey(repo *repository.Repository, name string) error { +func deleteKey(ctx context.Context, repo *repository.Repository, name string) error { if name == repo.KeyName() { return errors.Fatal("refusing to remove key currently used to access repository") } h := restic.Handle{Type: restic.KeyFile, Name: name} - err := repo.Backend().Remove(context.TODO(), h) + err := repo.Backend().Remove(ctx, h) if err != nil { return err } @@ -107,13 +107,13 @@ func changePassword(gopts GlobalOptions, repo *repository.Repository) error { return err } - id, err := repository.AddKey(context.TODO(), repo, pw, repo.Key()) + id, err := repository.AddKey(gopts.ctx, repo, pw, repo.Key()) if err != nil { return errors.Fatalf("creating new key failed: %v\n", err) } h := restic.Handle{Type: restic.KeyFile, Name: repo.KeyName()} - err = repo.Backend().Remove(context.TODO(), h) + err = repo.Backend().Remove(gopts.ctx, h) if err != nil { return err } @@ -165,7 +165,7 @@ func runKey(gopts GlobalOptions, args []string) error { return err } - return deleteKey(repo, id) + return deleteKey(gopts.ctx, repo, id) case "passwd": lock, err := lockRepoExclusive(repo) defer unlockRepo(lock) diff --git a/cmd/restic/cmd_list.go b/cmd/restic/cmd_list.go index ea8fb3876..0a7e9ca01 100644 --- a/cmd/restic/cmd_list.go +++ b/cmd/restic/cmd_list.go @@ -1,7 +1,6 @@ package main import ( - "context" "fmt" "github.com/restic/restic/internal/errors" @@ -58,7 +57,7 @@ func runList(opts GlobalOptions, args []string) error { case "locks": t = restic.LockFile case "blobs": - idx, err := index.Load(context.TODO(), repo, nil) + idx, err := index.Load(opts.ctx, repo, nil) if err != nil { return err } @@ -74,7 +73,7 @@ func runList(opts GlobalOptions, args []string) error { return errors.Fatal("invalid type") } - for id := range repo.List(context.TODO(), t) { + for id := range repo.List(opts.ctx, t) { Printf("%s\n", id) } diff --git a/cmd/restic/cmd_ls.go b/cmd/restic/cmd_ls.go index 7ea0759a5..4a046b7ef 100644 --- a/cmd/restic/cmd_ls.go +++ b/cmd/restic/cmd_ls.go @@ -46,8 +46,8 @@ func init() { flags.StringArrayVar(&lsOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path`, when no snapshot ID is given") } -func printTree(repo *repository.Repository, id *restic.ID, prefix string) error { - tree, err := repo.LoadTree(context.TODO(), *id) +func printTree(ctx context.Context, repo *repository.Repository, id *restic.ID, prefix string) error { + tree, err := repo.LoadTree(ctx, *id) if err != nil { return err } @@ -56,7 +56,7 @@ func printTree(repo *repository.Repository, id *restic.ID, prefix string) error Printf("%s\n", formatNode(prefix, entry, lsOptions.ListLong)) if entry.Type == "dir" && entry.Subtree != nil { - if err = printTree(repo, entry.Subtree, filepath.Join(prefix, entry.Name)); err != nil { + if err = printTree(ctx, repo, entry.Subtree, filepath.Join(prefix, entry.Name)); err != nil { return err } } @@ -75,7 +75,7 @@ func runLs(opts LsOptions, gopts GlobalOptions, args []string) error { return err } - if err = repo.LoadIndex(context.TODO()); err != nil { + if err = repo.LoadIndex(gopts.ctx); err != nil { return err } @@ -84,7 +84,7 @@ func runLs(opts LsOptions, gopts GlobalOptions, args []string) error { for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args) { Verbosef("snapshot %s of %v at %s):\n", sn.ID().Str(), sn.Paths, sn.Time) - if err = printTree(repo, sn.Tree, string(filepath.Separator)); err != nil { + if err = printTree(gopts.ctx, repo, sn.Tree, string(filepath.Separator)); err != nil { return err } } diff --git a/cmd/restic/cmd_mount.go b/cmd/restic/cmd_mount.go index b38d13cdb..5f57efa9c 100644 --- a/cmd/restic/cmd_mount.go +++ b/cmd/restic/cmd_mount.go @@ -4,7 +4,6 @@ package main import ( - "context" "os" "github.com/spf13/cobra" @@ -73,7 +72,7 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error { return err } - err = repo.LoadIndex(context.TODO()) + err = repo.LoadIndex(gopts.ctx) if err != nil { return err } @@ -114,7 +113,7 @@ func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error { Tags: opts.Tags, Paths: opts.Paths, } - root, err := fuse.NewRoot(context.TODO(), repo, cfg) + root, err := fuse.NewRoot(gopts.ctx, repo, cfg) if err != nil { return err } diff --git a/cmd/restic/cmd_tag.go b/cmd/restic/cmd_tag.go index a07d627c5..e38125cd1 100644 --- a/cmd/restic/cmd_tag.go +++ b/cmd/restic/cmd_tag.go @@ -53,7 +53,7 @@ func init() { tagFlags.StringArrayVar(&tagOptions.Paths, "path", nil, "only consider snapshots which include this (absolute) `path`, when no snapshot-ID is given") } -func changeTags(repo *repository.Repository, sn *restic.Snapshot, setTags, addTags, removeTags []string) (bool, error) { +func changeTags(ctx context.Context, repo *repository.Repository, sn *restic.Snapshot, setTags, addTags, removeTags []string) (bool, error) { var changed bool if len(setTags) != 0 { @@ -77,20 +77,20 @@ func changeTags(repo *repository.Repository, sn *restic.Snapshot, setTags, addTa } // Save the new snapshot. - id, err := repo.SaveJSONUnpacked(context.TODO(), restic.SnapshotFile, sn) + id, err := repo.SaveJSONUnpacked(ctx, restic.SnapshotFile, sn) if err != nil { return false, err } debug.Log("new snapshot saved as %v", id.Str()) - if err = repo.Flush(); err != nil { + if err = repo.Flush(ctx); err != nil { return false, err } // Remove the old snapshot. h := restic.Handle{Type: restic.SnapshotFile, Name: sn.ID().String()} - if err = repo.Backend().Remove(context.TODO(), h); err != nil { + if err = repo.Backend().Remove(ctx, h); err != nil { return false, err } @@ -125,7 +125,7 @@ func runTag(opts TagOptions, gopts GlobalOptions, args []string) error { ctx, cancel := context.WithCancel(gopts.ctx) defer cancel() for sn := range FindFilteredSnapshots(ctx, repo, opts.Host, opts.Tags, opts.Paths, args) { - changed, err := changeTags(repo, sn, opts.SetTags, opts.AddTags, opts.RemoveTags) + changed, err := changeTags(ctx, repo, sn, opts.SetTags, opts.AddTags, opts.RemoveTags) if err != nil { Warnf("unable to modify the tags for snapshot ID %q, ignoring: %v\n", sn.ID(), err) continue diff --git a/cmd/restic/cmd_unlock.go b/cmd/restic/cmd_unlock.go index 5297b0e4e..4b216905d 100644 --- a/cmd/restic/cmd_unlock.go +++ b/cmd/restic/cmd_unlock.go @@ -1,8 +1,6 @@ package main import ( - "context" - "github.com/restic/restic/internal/restic" "github.com/spf13/cobra" ) @@ -43,7 +41,7 @@ func runUnlock(opts UnlockOptions, gopts GlobalOptions) error { fn = restic.RemoveAllLocks } - err = fn(context.TODO(), repo) + err = fn(gopts.ctx, repo) if err != nil { return err } diff --git a/cmd/restic/global.go b/cmd/restic/global.go index eb6b5a646..6827f512d 100644 --- a/cmd/restic/global.go +++ b/cmd/restic/global.go @@ -344,7 +344,7 @@ func OpenRepository(opts GlobalOptions) (*repository.Repository, error) { return nil, err } - err = s.SearchKey(context.TODO(), opts.password, maxKeys) + err = s.SearchKey(opts.ctx, opts.password, maxKeys) if err != nil { return nil, err } @@ -555,7 +555,7 @@ func open(s string, opts options.Options) (restic.Backend, error) { case "swift": be, err = swift.Open(cfg.(swift.Config), rt) case "b2": - be, err = b2.Open(cfg.(b2.Config), rt) + be, err = b2.Open(globalOptions.ctx, cfg.(b2.Config), rt) case "rest": be, err = rest.Open(cfg.(rest.Config), rt) @@ -568,7 +568,7 @@ func open(s string, opts options.Options) (restic.Backend, error) { } // check if config is there - fi, err := be.Stat(context.TODO(), restic.Handle{Type: restic.ConfigFile}) + fi, err := be.Stat(globalOptions.ctx, restic.Handle{Type: restic.ConfigFile}) if err != nil { return nil, errors.Fatalf("unable to open config file: %v\nIs there a repository at the following location?\n%v", err, s) } @@ -612,7 +612,7 @@ func create(s string, opts options.Options) (restic.Backend, error) { case "swift": return swift.Open(cfg.(swift.Config), rt) case "b2": - return b2.Create(cfg.(b2.Config), rt) + return b2.Create(globalOptions.ctx, cfg.(b2.Config), rt) case "rest": return rest.Create(cfg.(rest.Config), rt) } diff --git a/internal/archiver/archive_reader.go b/internal/archiver/archive_reader.go index b6dab993b..07b224ad8 100644 --- a/internal/archiver/archive_reader.go +++ b/internal/archiver/archive_reader.go @@ -103,7 +103,7 @@ func (r *Reader) Archive(ctx context.Context, name string, rd io.Reader, p *rest debug.Log("snapshot saved as %v", id.Str()) - err = repo.Flush() + err = repo.Flush(ctx) if err != nil { return nil, restic.ID{}, err } diff --git a/internal/archiver/archiver.go b/internal/archiver/archiver.go index 967972700..20ba863c3 100644 --- a/internal/archiver/archiver.go +++ b/internal/archiver/archiver.go @@ -764,7 +764,7 @@ func (arch *Archiver) Snapshot(ctx context.Context, p *restic.Progress, paths, t debug.Log("workers terminated") // flush repository - err = arch.repo.Flush() + err = arch.repo.Flush(ctx) if err != nil { return nil, restic.ID{}, err } diff --git a/internal/archiver/archiver_duplication_test.go b/internal/archiver/archiver_duplication_test.go index 2ac2c1308..783dce11c 100644 --- a/internal/archiver/archiver_duplication_test.go +++ b/internal/archiver/archiver_duplication_test.go @@ -144,7 +144,7 @@ func testArchiverDuplication(t *testing.T) { wg.Wait() - err = repo.Flush() + err = repo.Flush(context.Background()) if err != nil { t.Fatal(err) } diff --git a/internal/archiver/archiver_test.go b/internal/archiver/archiver_test.go index 293de9152..e578ab3de 100644 --- a/internal/archiver/archiver_test.go +++ b/internal/archiver/archiver_test.go @@ -248,7 +248,7 @@ func testParallelSaveWithDuplication(t *testing.T, seed int) { rtest.OK(t, <-errChan) } - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) rtest.OK(t, repo.SaveIndex(context.TODO())) chkr := createAndInitChecker(t, repo) diff --git a/internal/backend/b2/b2.go b/internal/backend/b2/b2.go index 7e570c6eb..f24b8ec98 100644 --- a/internal/backend/b2/b2.go +++ b/internal/backend/b2/b2.go @@ -41,10 +41,10 @@ func newClient(ctx context.Context, cfg Config, rt http.RoundTripper) (*b2.Clien } // Open opens a connection to the B2 service. -func Open(cfg Config, rt http.RoundTripper) (restic.Backend, error) { +func Open(ctx context.Context, cfg Config, rt http.RoundTripper) (restic.Backend, error) { debug.Log("cfg %#v", cfg) - ctx, cancel := context.WithCancel(context.TODO()) + ctx, cancel := context.WithCancel(ctx) defer cancel() client, err := newClient(ctx, cfg, rt) @@ -79,10 +79,10 @@ func Open(cfg Config, rt http.RoundTripper) (restic.Backend, error) { // Create opens a connection to the B2 service. If the bucket does not exist yet, // it is created. -func Create(cfg Config, rt http.RoundTripper) (restic.Backend, error) { +func Create(ctx context.Context, cfg Config, rt http.RoundTripper) (restic.Backend, error) { debug.Log("cfg %#v", cfg) - ctx, cancel := context.WithCancel(context.TODO()) + ctx, cancel := context.WithCancel(ctx) defer cancel() client, err := newClient(ctx, cfg, rt) @@ -115,7 +115,7 @@ func Create(cfg Config, rt http.RoundTripper) (restic.Backend, error) { sem: sem, } - present, err := be.Test(context.TODO(), restic.Handle{Type: restic.ConfigFile}) + present, err := be.Test(ctx, restic.Handle{Type: restic.ConfigFile}) if err != nil { return nil, err } diff --git a/internal/backend/b2/b2_test.go b/internal/backend/b2/b2_test.go index 5784bd9a2..7f22a7986 100644 --- a/internal/backend/b2/b2_test.go +++ b/internal/backend/b2/b2_test.go @@ -45,19 +45,19 @@ func newB2TestSuite(t testing.TB) *test.Suite { // CreateFn is a function that creates a temporary repository for the tests. Create: func(config interface{}) (restic.Backend, error) { cfg := config.(b2.Config) - return b2.Create(cfg, tr) + return b2.Create(context.Background(), cfg, tr) }, // OpenFn is a function that opens a previously created temporary repository. Open: func(config interface{}) (restic.Backend, error) { cfg := config.(b2.Config) - return b2.Open(cfg, tr) + return b2.Open(context.Background(), cfg, tr) }, // CleanupFn removes data created during the tests. Cleanup: func(config interface{}) error { cfg := config.(b2.Config) - be, err := b2.Open(cfg, tr) + be, err := b2.Open(context.Background(), cfg, tr) if err != nil { return err } diff --git a/internal/backend/backend_retry.go b/internal/backend/backend_retry.go index 1d4c24859..45a30e468 100644 --- a/internal/backend/backend_retry.go +++ b/internal/backend/backend_retry.go @@ -33,15 +33,17 @@ func NewRetryBackend(be restic.Backend, maxTries int, report func(string, error, } } -func (be *RetryBackend) retry(msg string, f func() error) error { - return backoff.RetryNotify(f, - backoff.WithMaxTries(backoff.NewExponentialBackOff(), uint64(be.MaxTries)), +func (be *RetryBackend) retry(ctx context.Context, msg string, f func() error) error { + err := backoff.RetryNotify(f, + backoff.WithContext(backoff.WithMaxTries(backoff.NewExponentialBackOff(), uint64(be.MaxTries)), ctx), func(err error, d time.Duration) { if be.Report != nil { be.Report(msg, err, d) } }, ) + + return err } // Save stores the data in the backend under the given handle. @@ -60,7 +62,7 @@ func (be *RetryBackend) Save(ctx context.Context, h restic.Handle, rd io.Reader) return errors.Errorf("reader is not at the beginning (pos %v)", pos) } - return be.retry(fmt.Sprintf("Save(%v)", h), func() error { + return be.retry(ctx, fmt.Sprintf("Save(%v)", h), func() error { _, err := seeker.Seek(0, io.SeekStart) if err != nil { return err @@ -87,7 +89,7 @@ func (be *RetryBackend) Save(ctx context.Context, h restic.Handle, rd io.Reader) // is returned. rd must be closed after use. If an error is returned, the // ReadCloser must be nil. func (be *RetryBackend) Load(ctx context.Context, h restic.Handle, length int, offset int64) (rd io.ReadCloser, err error) { - err = be.retry(fmt.Sprintf("Load(%v, %v, %v)", h, length, offset), + err = be.retry(ctx, fmt.Sprintf("Load(%v, %v, %v)", h, length, offset), func() error { var innerError error rd, innerError = be.Backend.Load(ctx, h, length, offset) @@ -99,7 +101,7 @@ func (be *RetryBackend) Load(ctx context.Context, h restic.Handle, length int, o // Stat returns information about the File identified by h. func (be *RetryBackend) Stat(ctx context.Context, h restic.Handle) (fi restic.FileInfo, err error) { - err = be.retry(fmt.Sprintf("Stat(%v)", h), + err = be.retry(ctx, fmt.Sprintf("Stat(%v)", h), func() error { var innerError error fi, innerError = be.Backend.Stat(ctx, h) diff --git a/internal/repository/packer_manager.go b/internal/repository/packer_manager.go index 3b905903c..cfee2e365 100644 --- a/internal/repository/packer_manager.go +++ b/internal/repository/packer_manager.go @@ -89,7 +89,7 @@ func (r *packerManager) insertPacker(p *Packer) { } // savePacker stores p in the backend. -func (r *Repository) savePacker(t restic.BlobType, p *Packer) error { +func (r *Repository) savePacker(ctx context.Context, t restic.BlobType, p *Packer) error { debug.Log("save packer for %v with %d blobs (%d bytes)\n", t, p.Packer.Count(), p.Packer.Size()) _, err := p.Packer.Finalize() if err != nil { @@ -104,7 +104,7 @@ func (r *Repository) savePacker(t restic.BlobType, p *Packer) error { id := restic.IDFromHash(p.hw.Sum(nil)) h := restic.Handle{Type: restic.DataFile, Name: id.String()} - err = r.be.Save(context.TODO(), h, p.tmpfile) + err = r.be.Save(ctx, h, p.tmpfile) if err != nil { debug.Log("Save(%v) error: %v", h, err) return err diff --git a/internal/repository/repack.go b/internal/repository/repack.go index 3eacea182..b8e80c3a2 100644 --- a/internal/repository/repack.go +++ b/internal/repository/repack.go @@ -126,7 +126,7 @@ func Repack(ctx context.Context, repo restic.Repository, packs restic.IDSet, kee } } - if err := repo.Flush(); err != nil { + if err := repo.Flush(ctx); err != nil { return nil, err } diff --git a/internal/repository/repack_test.go b/internal/repository/repack_test.go index 2f265150d..2d29a589a 100644 --- a/internal/repository/repack_test.go +++ b/internal/repository/repack_test.go @@ -55,13 +55,13 @@ func createRandomBlobs(t testing.TB, repo restic.Repository, blobs int, pData fl } if rand.Float32() < 0.2 { - if err = repo.Flush(); err != nil { + if err = repo.Flush(context.Background()); err != nil { t.Fatalf("repo.Flush() returned error %v", err) } } } - if err := repo.Flush(); err != nil { + if err := repo.Flush(context.Background()); err != nil { t.Fatalf("repo.Flush() returned error %v", err) } } diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 9bf686548..193ec1ca7 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -250,7 +250,7 @@ func (r *Repository) SaveAndEncrypt(ctx context.Context, t restic.BlobType, data } // else write the pack to the backend - return *id, r.savePacker(t, packer) + return *id, r.savePacker(ctx, t, packer) } // SaveJSONUnpacked serialises item as JSON and encrypts and saves it in the @@ -289,7 +289,7 @@ func (r *Repository) SaveUnpacked(ctx context.Context, t restic.FileType, p []by } // Flush saves all remaining packs. -func (r *Repository) Flush() error { +func (r *Repository) Flush(ctx context.Context) error { pms := []struct { t restic.BlobType pm *packerManager @@ -303,7 +303,7 @@ func (r *Repository) Flush() error { debug.Log("manually flushing %d packs", len(p.pm.packers)) for _, packer := range p.pm.packers { - err := r.savePacker(p.t, packer) + err := r.savePacker(ctx, p.t, packer) if err != nil { p.pm.pm.Unlock() return err diff --git a/internal/repository/repository_test.go b/internal/repository/repository_test.go index d3b9dec93..a90f0959b 100644 --- a/internal/repository/repository_test.go +++ b/internal/repository/repository_test.go @@ -37,7 +37,7 @@ func TestSave(t *testing.T) { rtest.Equals(t, id, sid) - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) // rtest.OK(t, repo.SaveIndex()) // read back @@ -72,7 +72,7 @@ func TestSaveFrom(t *testing.T) { rtest.OK(t, err) rtest.Equals(t, id, id2) - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) // read back buf := restic.NewBlobBuffer(size) @@ -122,7 +122,7 @@ func TestLoadTree(t *testing.T) { // archive a few files sn := archiver.TestSnapshot(t, repo, rtest.BenchArchiveDirectory, nil) - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) _, err := repo.LoadTree(context.TODO(), *sn.Tree) rtest.OK(t, err) @@ -138,7 +138,7 @@ func BenchmarkLoadTree(t *testing.B) { // archive a few files sn := archiver.TestSnapshot(t, repo, rtest.BenchArchiveDirectory, nil) - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) t.ResetTimer() @@ -159,7 +159,7 @@ func TestLoadBlob(t *testing.T) { id, err := repo.SaveBlob(context.TODO(), restic.DataBlob, buf, restic.ID{}) rtest.OK(t, err) - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) // first, test with buffers that are too small for _, testlength := range []int{length - 20, length, restic.CiphertextLength(length) - 1} { @@ -204,7 +204,7 @@ func BenchmarkLoadBlob(b *testing.B) { id, err := repo.SaveBlob(context.TODO(), restic.DataBlob, buf, restic.ID{}) rtest.OK(b, err) - rtest.OK(b, repo.Flush()) + rtest.OK(b, repo.Flush(context.Background())) b.ResetTimer() b.SetBytes(int64(length)) @@ -352,7 +352,7 @@ func TestRepositoryIncrementalIndex(t *testing.T) { // add 3 packs, write intermediate index for i := 0; i < 3; i++ { saveRandomDataBlobs(t, repo, 5, 1<<15) - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) } rtest.OK(t, repo.SaveFullIndex(context.TODO())) @@ -361,7 +361,7 @@ func TestRepositoryIncrementalIndex(t *testing.T) { // add another 5 packs for i := 0; i < 5; i++ { saveRandomDataBlobs(t, repo, 5, 1<<15) - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) } // save final index diff --git a/internal/restic/repository.go b/internal/restic/repository.go index 6c8cad863..2daae41b2 100644 --- a/internal/restic/repository.go +++ b/internal/restic/repository.go @@ -29,7 +29,7 @@ type Repository interface { List(context.Context, FileType) <-chan ID ListPack(context.Context, ID) ([]Blob, int64, error) - Flush() error + Flush(context.Context) error SaveUnpacked(context.Context, FileType, []byte) (ID, error) SaveJSONUnpacked(context.Context, FileType, interface{}) (ID, error) diff --git a/internal/restic/restorer_test.go b/internal/restic/restorer_test.go index 43dc4d742..9e3c5528a 100644 --- a/internal/restic/restorer_test.go +++ b/internal/restic/restorer_test.go @@ -90,7 +90,7 @@ func saveSnapshot(t testing.TB, repo restic.Repository, snapshot Snapshot) (rest treeID := saveDir(t, repo, snapshot.Nodes) - err := repo.Flush() + err := repo.Flush(ctx) if err != nil { t.Fatal(err) } diff --git a/internal/restic/testing.go b/internal/restic/testing.go index 5e1f3372b..ad7604a6c 100644 --- a/internal/restic/testing.go +++ b/internal/restic/testing.go @@ -189,7 +189,7 @@ func TestCreateSnapshot(t testing.TB, repo Repository, at time.Time, depth int, t.Logf("saved snapshot %v", id.Str()) - err = repo.Flush() + err = repo.Flush(context.Background()) if err != nil { t.Fatal(err) } diff --git a/internal/restic/tree_test.go b/internal/restic/tree_test.go index d1cc8df91..2bcda6760 100644 --- a/internal/restic/tree_test.go +++ b/internal/restic/tree_test.go @@ -103,7 +103,7 @@ func TestLoadTree(t *testing.T) { rtest.OK(t, err) // save packs - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) // load tree again tree2, err := repo.LoadTree(context.TODO(), id) diff --git a/internal/walk/walk_test.go b/internal/walk/walk_test.go index 2e6d4f7cc..b67ae9151 100644 --- a/internal/walk/walk_test.go +++ b/internal/walk/walk_test.go @@ -29,7 +29,7 @@ func TestWalkTree(t *testing.T) { rtest.OK(t, err) // flush repo, write all packs - rtest.OK(t, repo.Flush()) + rtest.OK(t, repo.Flush(context.Background())) // start tree walker treeJobs := make(chan walk.TreeJob)