forked from TrueCloudLab/restic
Allow restoring and listing without locking
This commit is contained in:
parent
c79dcbd7c4
commit
6edb7e02d0
4 changed files with 39 additions and 14 deletions
|
@ -8,6 +8,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type CmdList struct {
|
type CmdList struct {
|
||||||
|
NoLock bool `long:"no-lock" default:"false" description:"Do not lock repository, this allows listing a read-only repo"`
|
||||||
|
|
||||||
global *GlobalOptions
|
global *GlobalOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,10 +37,12 @@ func (cmd CmdList) Execute(args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := lockRepo(repo)
|
if !cmd.NoLock {
|
||||||
defer unlockRepo(lock)
|
lock, err := lockRepo(repo)
|
||||||
if err != nil {
|
defer unlockRepo(lock)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var t backend.Type
|
var t backend.Type
|
||||||
|
|
|
@ -13,6 +13,7 @@ type CmdRestore struct {
|
||||||
Exclude []string `short:"e" long:"exclude" description:"Exclude a pattern (can be specified multiple times)"`
|
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)"`
|
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"`
|
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
|
global *GlobalOptions
|
||||||
}
|
}
|
||||||
|
@ -53,10 +54,12 @@ func (cmd CmdRestore) Execute(args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lock, err := lockRepo(repo)
|
if !cmd.NoLock {
|
||||||
defer unlockRepo(lock)
|
lock, err := lockRepo(repo)
|
||||||
if err != nil {
|
defer unlockRepo(lock)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = repo.LoadIndex()
|
err = repo.LoadIndex()
|
||||||
|
|
|
@ -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 {
|
func cmdList(t testing.TB, global GlobalOptions, tpe string) backend.IDs {
|
||||||
var buf bytes.Buffer
|
|
||||||
global.stdout = &buf
|
|
||||||
cmd := &CmdList{global: &global}
|
cmd := &CmdList{global: &global}
|
||||||
|
return executeAndParseIDs(t, cmd, tpe)
|
||||||
|
}
|
||||||
|
|
||||||
OK(t, cmd.Execute([]string{tpe}))
|
func executeAndParseIDs(t testing.TB, cmd *CmdList, args ...string) backend.IDs {
|
||||||
IDs := parseIDsFromReader(t, &buf)
|
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) {
|
func cmdRestore(t testing.TB, global GlobalOptions, dir string, snapshotID backend.ID) {
|
||||||
cmdRestoreExcludes(t, global, dir, snapshotID, nil)
|
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) {
|
func cmdRestoreExcludes(t testing.TB, global GlobalOptions, dir string, snapshotID backend.ID, excludes []string) {
|
||||||
cmd := &CmdRestore{global: &global, Target: dir, Exclude: excludes}
|
cmd := &CmdRestore{global: &global, Target: dir, Exclude: excludes}
|
||||||
OK(t, cmd.Execute([]string{snapshotID.String()}))
|
OK(t, cmd.Execute([]string{snapshotID.String()}))
|
||||||
|
@ -801,7 +812,7 @@ func TestOptimizeRemoveUnusedBlobs(t *testing.T) {
|
||||||
|
|
||||||
func TestCheckRestoreNoLock(t *testing.T) {
|
func TestCheckRestoreNoLock(t *testing.T) {
|
||||||
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
|
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)
|
SetupTarTestFixture(t, env.base, datafile)
|
||||||
|
|
||||||
err := filepath.Walk(env.repo, func(p string, fi os.FileInfo, e error) error {
|
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)
|
OK(t, err)
|
||||||
|
|
||||||
cmdCheckNoLock(t, global)
|
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])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
BIN
cmd/restic/testdata/small-repo.tar.gz
vendored
Normal file
BIN
cmd/restic/testdata/small-repo.tar.gz
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue