Merge pull request #350 from restic/allow-read-only-ops

Allow check/restore read-only, without locking
This commit is contained in:
Alexander Neumann 2015-11-13 23:48:05 +01:00
commit 6b9c8ffd14
6 changed files with 54 additions and 21 deletions

View File

@ -9,8 +9,8 @@ import (
) )
type CmdCheck struct { type CmdCheck struct {
ReadData bool `long:"read-data" description:"Read data blobs" default:"false"` ReadData bool `long:"read-data" default:"false" description:"Read data blobs"`
CheckUnused bool `long:"check-unused" description:"Check for unused blobs" default:"false"` CheckUnused bool `long:"check-unused" default:"false" description:"Check for unused blobs"`
global *GlobalOptions global *GlobalOptions
} }
@ -39,11 +39,13 @@ func (cmd CmdCheck) Execute(args []string) error {
return err return err
} }
cmd.global.Verbosef("Create exclusive lock for repository\n") if !cmd.global.NoLock {
lock, err := lockRepoExclusive(repo) cmd.global.Verbosef("Create exclusive lock for repository\n")
defer unlockRepo(lock) lock, err := lockRepoExclusive(repo)
if err != nil { defer unlockRepo(lock)
return err if err != nil {
return err
}
} }
chkr := checker.New(repo) chkr := checker.New(repo)

View File

@ -35,10 +35,12 @@ func (cmd CmdList) Execute(args []string) error {
return err return err
} }
lock, err := lockRepo(repo) if !cmd.global.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

View File

@ -53,10 +53,12 @@ func (cmd CmdRestore) Execute(args []string) error {
return err return err
} }
lock, err := lockRepo(repo) if !cmd.global.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()

View File

@ -24,6 +24,7 @@ type GlobalOptions struct {
Repo string `short:"r" long:"repo" description:"Repository directory to backup to/restore from"` Repo string `short:"r" long:"repo" description:"Repository directory to backup to/restore from"`
CacheDir string ` long:"cache-dir" description:"Directory to use as a local cache"` CacheDir string ` long:"cache-dir" description:"Directory to use as a local cache"`
Quiet bool `short:"q" long:"quiet" default:"false" description:"Do not output comprehensive progress report"` Quiet bool `short:"q" long:"quiet" default:"false" description:"Do not output comprehensive progress report"`
NoLock bool ` long:"no-lock" default:"false" description:"Do not lock the repo, this allows some operations on read-only repos."`
password string password string
stdout io.Writer stdout io.Writer

View File

@ -62,14 +62,15 @@ 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
return IDs OK(t, cmd.Execute(args))
return parseIDsFromReader(t, buf)
} }
func cmdRestore(t testing.TB, global GlobalOptions, dir string, snapshotID backend.ID) { func cmdRestore(t testing.TB, global GlobalOptions, dir string, snapshotID backend.ID) {
@ -788,3 +789,28 @@ func TestOptimizeRemoveUnusedBlobs(t *testing.T) {
}) })
} }
} }
func TestCheckRestoreNoLock(t *testing.T) {
withTestEnvironment(t, func(env *testEnvironment, global GlobalOptions) {
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 {
if e != nil {
return e
}
return os.Chmod(p, fi.Mode() & ^(os.FileMode(0222)))
})
OK(t, err)
global.NoLock = true
cmdCheck(t, global)
snapshotIDs := cmdList(t, global, "snapshots")
if len(snapshotIDs) == 0 {
t.Fatalf("found no snapshots")
}
cmdRestore(t, global, filepath.Join(env.base, "restore"), snapshotIDs[0])
})
}

BIN
cmd/restic/testdata/small-repo.tar.gz vendored Normal file

Binary file not shown.