forked from TrueCloudLab/restic
Add include filter for restore
Include and exclude filter are mutually exclusive.
This commit is contained in:
parent
c0337a2675
commit
1da89253cf
2 changed files with 25 additions and 4 deletions
|
@ -11,6 +11,7 @@ import (
|
||||||
|
|
||||||
type CmdRestore struct {
|
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)"`
|
||||||
Target string `short:"t" long:"target" description:"Directory to restore to"`
|
Target string `short:"t" long:"target" description:"Directory to restore to"`
|
||||||
|
|
||||||
global *GlobalOptions
|
global *GlobalOptions
|
||||||
|
@ -39,6 +40,10 @@ func (cmd CmdRestore) Execute(args []string) error {
|
||||||
return errors.New("please specify a directory to restore to (--target)")
|
return errors.New("please specify a directory to restore to (--target)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(cmd.Exclude) > 0 && len(cmd.Include) > 0 {
|
||||||
|
return errors.New("exclude and include patterns are mutually exclusive")
|
||||||
|
}
|
||||||
|
|
||||||
snapshotIDString := args[0]
|
snapshotIDString := args[0]
|
||||||
|
|
||||||
debug.Log("restore", "restore %v to %v", snapshotIDString, cmd.Target)
|
debug.Log("restore", "restore %v to %v", snapshotIDString, cmd.Target)
|
||||||
|
@ -74,7 +79,7 @@ func (cmd CmdRestore) Execute(args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
selectFilter := func(item string, dstpath string, node *restic.Node) bool {
|
selectExcludeFilter := func(item string, dstpath string, node *restic.Node) bool {
|
||||||
matched, err := filter.List(cmd.Exclude, item)
|
matched, err := filter.List(cmd.Exclude, item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmd.global.Warnf("error for exclude pattern: %v", err)
|
cmd.global.Warnf("error for exclude pattern: %v", err)
|
||||||
|
@ -83,8 +88,19 @@ func (cmd CmdRestore) Execute(args []string) error {
|
||||||
return !matched
|
return !matched
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectIncludeFilter := func(item string, dstpath string, node *restic.Node) bool {
|
||||||
|
matched, err := filter.List(cmd.Include, item)
|
||||||
|
if err != nil {
|
||||||
|
cmd.global.Warnf("error for include pattern: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return matched
|
||||||
|
}
|
||||||
|
|
||||||
if len(cmd.Exclude) > 0 {
|
if len(cmd.Exclude) > 0 {
|
||||||
res.SelectFilter = selectFilter
|
res.SelectFilter = selectExcludeFilter
|
||||||
|
} else if len(cmd.Include) > 0 {
|
||||||
|
res.SelectFilter = selectIncludeFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.global.Verbosef("restoring %s to %s\n", res.Snapshot(), cmd.Target)
|
cmd.global.Verbosef("restoring %s to %s\n", res.Snapshot(), cmd.Target)
|
||||||
|
|
|
@ -78,6 +78,11 @@ func cmdRestoreExcludes(t testing.TB, global GlobalOptions, dir string, snapshot
|
||||||
OK(t, cmd.Execute([]string{snapshotID.String()}))
|
OK(t, cmd.Execute([]string{snapshotID.String()}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cmdRestoreIncludes(t testing.TB, global GlobalOptions, dir string, snapshotID backend.ID, includes []string) {
|
||||||
|
cmd := &CmdRestore{global: &global, Target: dir, Include: includes}
|
||||||
|
OK(t, cmd.Execute([]string{snapshotID.String()}))
|
||||||
|
}
|
||||||
|
|
||||||
func cmdCheck(t testing.TB, global GlobalOptions) {
|
func cmdCheck(t testing.TB, global GlobalOptions) {
|
||||||
cmd := &CmdCheck{global: &global, ReadData: true}
|
cmd := &CmdCheck{global: &global, ReadData: true}
|
||||||
OK(t, cmd.Execute(nil))
|
OK(t, cmd.Execute(nil))
|
||||||
|
@ -563,7 +568,7 @@ func TestRestoreNoMetadataOnIgnoredIntermediateDirs(t *testing.T) {
|
||||||
// restore with filter "*.ext", this should restore "file.ext", but
|
// restore with filter "*.ext", this should restore "file.ext", but
|
||||||
// since the directories are ignored and only created because of
|
// since the directories are ignored and only created because of
|
||||||
// "file.ext", no meta data should be restored for them.
|
// "file.ext", no meta data should be restored for them.
|
||||||
cmdRestoreExcludes(t, global, filepath.Join(env.base, "restore0"), snapshotID, []string{"*.ext"})
|
cmdRestoreIncludes(t, global, filepath.Join(env.base, "restore0"), snapshotID, []string{"*.ext"})
|
||||||
|
|
||||||
f1 := filepath.Join(env.base, "restore0", "testdata", "subdir1", "subdir2")
|
f1 := filepath.Join(env.base, "restore0", "testdata", "subdir1", "subdir2")
|
||||||
fi, err := os.Stat(f1)
|
fi, err := os.Stat(f1)
|
||||||
|
@ -573,7 +578,7 @@ func TestRestoreNoMetadataOnIgnoredIntermediateDirs(t *testing.T) {
|
||||||
"meta data of intermediate directory has been restore although it was ignored")
|
"meta data of intermediate directory has been restore although it was ignored")
|
||||||
|
|
||||||
// restore with filter "*", this should restore meta data on everything.
|
// restore with filter "*", this should restore meta data on everything.
|
||||||
cmdRestoreExcludes(t, global, filepath.Join(env.base, "restore1"), snapshotID, []string{"*"})
|
cmdRestoreIncludes(t, global, filepath.Join(env.base, "restore1"), snapshotID, []string{"*"})
|
||||||
|
|
||||||
f2 := filepath.Join(env.base, "restore1", "testdata", "subdir1", "subdir2")
|
f2 := filepath.Join(env.base, "restore1", "testdata", "subdir1", "subdir2")
|
||||||
fi, err = os.Stat(f2)
|
fi, err = os.Stat(f2)
|
||||||
|
|
Loading…
Reference in a new issue