diff --git a/cmd/restic/cmd_list.go b/cmd/restic/cmd_list.go index 11f4bd8d6..6883eae61 100644 --- a/cmd/restic/cmd_list.go +++ b/cmd/restic/cmd_list.go @@ -8,6 +8,8 @@ import ( ) type CmdList struct { + NoLock bool `long:"no-lock" default:"false" description:"Do not lock repository, this allows listing a read-only repo"` + global *GlobalOptions } @@ -35,10 +37,12 @@ func (cmd CmdList) Execute(args []string) error { return err } - lock, err := lockRepo(repo) - defer unlockRepo(lock) - if err != nil { - return err + if !cmd.NoLock { + lock, err := lockRepo(repo) + defer unlockRepo(lock) + if err != nil { + return err + } } var t backend.Type diff --git a/cmd/restic/cmd_restore.go b/cmd/restic/cmd_restore.go index 26ef9b9e0..389d0b5cc 100644 --- a/cmd/restic/cmd_restore.go +++ b/cmd/restic/cmd_restore.go @@ -13,6 +13,7 @@ type CmdRestore struct { Exclude []string `short:"e" long:"exclude" description:"Exclude a pattern (can be specified multiple times)"` Include []string `short:"i" long:"include" description:"Include a pattern, exclude everything else (can be specified multiple times)"` Target string `short:"t" long:"target" description:"Directory to restore to"` + NoLock bool ` long:"no-lock" default:"false" description:"Do not lock repository, this allows restoring a read-only repo"` global *GlobalOptions } @@ -53,10 +54,12 @@ func (cmd CmdRestore) Execute(args []string) error { return err } - lock, err := lockRepo(repo) - defer unlockRepo(lock) - if err != nil { - return err + if !cmd.NoLock { + lock, err := lockRepo(repo) + defer unlockRepo(lock) + if err != nil { + return err + } } err = repo.LoadIndex() diff --git a/cmd/restic/integration_test.go b/cmd/restic/integration_test.go index 3cbfde18a..21e118d60 100644 --- a/cmd/restic/integration_test.go +++ b/cmd/restic/integration_test.go @@ -62,20 +62,31 @@ func cmdBackupExcludes(t testing.TB, global GlobalOptions, target []string, pare } func cmdList(t testing.TB, global GlobalOptions, tpe string) backend.IDs { - var buf bytes.Buffer - global.stdout = &buf cmd := &CmdList{global: &global} + return executeAndParseIDs(t, cmd, tpe) +} - OK(t, cmd.Execute([]string{tpe})) - IDs := parseIDsFromReader(t, &buf) +func executeAndParseIDs(t testing.TB, cmd *CmdList, args ...string) backend.IDs { + buf := bytes.NewBuffer(nil) + cmd.global.stdout = buf + OK(t, cmd.Execute(args)) + return parseIDsFromReader(t, buf) +} - return IDs +func cmdListNoLock(t testing.TB, global GlobalOptions, tpe string) backend.IDs { + cmd := &CmdList{global: &global, NoLock: true} + return executeAndParseIDs(t, cmd, tpe) } func cmdRestore(t testing.TB, global GlobalOptions, dir string, snapshotID backend.ID) { cmdRestoreExcludes(t, global, dir, snapshotID, nil) } +func cmdRestoreNoLock(t testing.TB, global GlobalOptions, dir string, snapshotID backend.ID) { + cmd := &CmdRestore{global: &global, Target: dir, NoLock: true} + OK(t, cmd.Execute([]string{snapshotID.String()})) +} + func cmdRestoreExcludes(t testing.TB, global GlobalOptions, dir string, snapshotID backend.ID, excludes []string) { cmd := &CmdRestore{global: &global, Target: dir, Exclude: excludes} OK(t, cmd.Execute([]string{snapshotID.String()})) @@ -801,7 +812,7 @@ func TestOptimizeRemoveUnusedBlobs(t *testing.T) { func TestCheckRestoreNoLock(t *testing.T) { withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) { - datafile := filepath.Join("testdata", "repo-restore-permissions-test.tar.gz") + datafile := filepath.Join("testdata", "small-repo.tar.gz") SetupTarTestFixture(t, env.base, datafile) err := filepath.Walk(env.repo, func(p string, fi os.FileInfo, e error) error { @@ -813,5 +824,12 @@ func TestCheckRestoreNoLock(t *testing.T) { OK(t, err) cmdCheckNoLock(t, global) + + snapshotIDs := cmdListNoLock(t, global, "snapshots") + if len(snapshotIDs) == 0 { + t.Fatalf("found no snapshots") + } + + cmdRestoreNoLock(t, global, filepath.Join(env.base, "restore"), snapshotIDs[0]) }) } diff --git a/cmd/restic/testdata/small-repo.tar.gz b/cmd/restic/testdata/small-repo.tar.gz new file mode 100644 index 000000000..83959f539 Binary files /dev/null and b/cmd/restic/testdata/small-repo.tar.gz differ