Skip to content

Commit

Permalink
Add support for --prefix and --strip-components options on backup com…
Browse files Browse the repository at this point in the history
…mand.
  • Loading branch information
giacomocariello committed Sep 25, 2018
1 parent 6bc99ce commit 101fbef
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 9 deletions.
6 changes: 6 additions & 0 deletions cmd/restic/cmd_backup.go
Expand Up @@ -76,6 +76,8 @@ type BackupOptions struct {
FilesFrom string
TimeStamp string
WithAtime bool
RootPrefix string
RootStrip int
}

var backupOptions BackupOptions
Expand All @@ -98,6 +100,8 @@ func init() {
f.StringVar(&backupOptions.FilesFrom, "files-from", "", "read the files to backup from file (can be combined with file args)")
f.StringVar(&backupOptions.TimeStamp, "time", "", "time of the backup (ex. '2012-11-01 22:08:41') (default: now)")
f.BoolVar(&backupOptions.WithAtime, "with-atime", false, "store the atime for all files and directories")
f.StringVar(&backupOptions.RootPrefix, "prefix", "", "apply a prefix to target paths")
f.IntVar(&backupOptions.RootStrip, "strip-components", 0, "strip NUMBER leading components from target paths")
}

// filterExisting returns a slice of all existing items, or an error if no
Expand Down Expand Up @@ -484,6 +488,8 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
Time: timeStamp,
Hostname: opts.Hostname,
ParentSnapshot: *parentSnapshotID,
RootPrefix: opts.RootPrefix,
RootStrip: opts.RootStrip,
}

uploader := archiver.IndexUploader{
Expand Down
4 changes: 3 additions & 1 deletion internal/archiver/archiver.go
Expand Up @@ -705,6 +705,8 @@ type SnapshotOptions struct {
Excludes []string
Time time.Time
ParentSnapshot restic.ID
RootPrefix string
RootStrip int
}

// loadParentTree loads a tree referenced by snapshot id. If id is null, nil is returned.
Expand Down Expand Up @@ -807,7 +809,7 @@ func (arch *Archiver) Snapshot(ctx context.Context, targets []string, opts Snaps
return nil, restic.ID{}, err
}

sn, err := restic.NewSnapshot(targets, opts.Tags, opts.Hostname, opts.Time)
sn, err := restic.NewSnapshot(targets, opts.Tags, opts.Hostname, opts.Time, opts.RootPrefix, opts.RootStrip)
sn.Excludes = opts.Excludes
if !opts.ParentSnapshot.IsNull() {
id := opts.ParentSnapshot
Expand Down
35 changes: 30 additions & 5 deletions internal/restic/snapshot.go
Expand Up @@ -27,17 +27,42 @@ type Snapshot struct {
id *ID // plaintext ID, used during restore
}

func pathSplit(path string) (root string, lst []string) {
for root = filepath.Clean(path); ; {
var file string
root, file = filepath.Split(root)
if file == "" {
break
}
lst = append([]string{file}, lst...)
}
return
}

// NewSnapshot returns an initialized snapshot struct for the current user and
// time.
func NewSnapshot(paths []string, tags []string, hostname string, time time.Time) (*Snapshot, error) {
func NewSnapshot(paths []string, tags []string, hostname string, time time.Time, prefix string, strip int) (*Snapshot, error) {
absPaths := make([]string, 0, len(paths))
for _, path := range paths {
p, err := filepath.Abs(path)
if err == nil {
absPaths = append(absPaths, p)
pathRoot, pathList := pathSplit(path)
if strip > 0 {
var stripRoot int
if pathRoot != "" {
stripRoot++
}
pathList = pathList[strip-stripRoot:]
pathRoot = ""
}
if prefix != "" {
pathRoot = prefix
} else {
absPaths = append(absPaths, path)
absPath, err := filepath.Abs(pathRoot)
if err == nil {
pathRoot = absPath
}
}
p := filepath.Join(append([]string{pathRoot}, pathList...)...)
absPaths = append(absPaths, p)
}

sn := &Snapshot{
Expand Down
2 changes: 1 addition & 1 deletion internal/restic/snapshot_test.go
Expand Up @@ -11,6 +11,6 @@ import (
func TestNewSnapshot(t *testing.T) {
paths := []string{"/home/foobar"}

_, err := restic.NewSnapshot(paths, nil, "foo", time.Now())
_, err := restic.NewSnapshot(paths, nil, "foo", time.Now(), "", 0)
rtest.OK(t, err)
}
2 changes: 1 addition & 1 deletion internal/restic/testing.go
Expand Up @@ -164,7 +164,7 @@ func TestCreateSnapshot(t testing.TB, repo Repository, at time.Time, depth int,
t.Logf("create fake snapshot at %s with seed %d", at, seed)

fakedir := fmt.Sprintf("fakedir-at-%v", at.Format("2006-01-02 15:04:05"))
snapshot, err := NewSnapshot([]string{fakedir}, []string{"test"}, "foo", time.Now())
snapshot, err := NewSnapshot([]string{fakedir}, []string{"test"}, "foo", time.Now(), "", 0)
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/restorer/restorer_test.go
Expand Up @@ -107,7 +107,7 @@ func saveSnapshot(t testing.TB, repo restic.Repository, snapshot Snapshot) (*res
t.Fatal(err)
}

sn, err := restic.NewSnapshot([]string{"test"}, nil, "", time.Now())
sn, err := restic.NewSnapshot([]string{"test"}, nil, "", time.Now(), "", 0)
if err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit 101fbef

Please sign in to comment.