diff --git a/src/cmds/restic/cmd_backup.go b/src/cmds/restic/cmd_backup.go index f15851331..31322563e 100644 --- a/src/cmds/restic/cmd_backup.go +++ b/src/cmds/restic/cmd_backup.go @@ -51,6 +51,7 @@ type BackupOptions struct { Stdin bool StdinFilename string Tags []string + Hostname string FilesFrom string } @@ -59,6 +60,12 @@ var backupOptions BackupOptions func init() { cmdRoot.AddCommand(cmdBackup) + hostname, err := os.Hostname() + if err != nil { + debug.Log("os.Hostname() returned err: %v", err) + hostname = "" + } + f := cmdBackup.Flags() f.StringVar(&backupOptions.Parent, "parent", "", "use this parent snapshot (default: last snapshot in the repo that has the same target files/directories)") f.BoolVarP(&backupOptions.Force, "force", "f", false, `force re-reading the target files/directories. Overrides the "parent" flag`) @@ -68,6 +75,7 @@ func init() { f.BoolVar(&backupOptions.Stdin, "stdin", false, "read backup from stdin") f.StringVar(&backupOptions.StdinFilename, "stdin-filename", "stdin", "file name to use when reading from stdin") f.StringSliceVar(&backupOptions.Tags, "tag", []string{}, "add a `tag` for the new snapshot (can be specified multiple times)") + f.StringVar(&backupOptions.Hostname, "hostname", hostname, "set the `hostname` for the snapshot manually") f.StringVar(&backupOptions.FilesFrom, "files-from", "", "read the files to backup from file (can be combined with file args)") } @@ -264,7 +272,7 @@ func readBackupFromStdin(opts BackupOptions, gopts GlobalOptions, args []string) return err } - _, id, err := archiver.ArchiveReader(repo, newArchiveStdinProgress(gopts), os.Stdin, opts.StdinFilename, opts.Tags) + _, id, err := archiver.ArchiveReader(repo, newArchiveStdinProgress(gopts), os.Stdin, opts.StdinFilename, opts.Tags, opts.Hostname) if err != nil { return err } @@ -377,13 +385,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, args []string) error { // Find last snapshot to set it as parent, if not already set if !opts.Force && parentSnapshotID == nil { - hostname, err := os.Hostname() - if err != nil { - debug.Log("os.Hostname() returned err: %v", err) - hostname = "" - } - - id, err := restic.FindLatestSnapshot(repo, target, hostname) + id, err := restic.FindLatestSnapshot(repo, target, opts.Hostname) if err == nil { parentSnapshotID = &id } else if err != restic.ErrNoSnapshotFound { @@ -459,7 +461,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, args []string) error { Warnf("%s\rwarning for %s: %v\n", ClearLine(), dir, err) } - _, id, err := arch.Snapshot(newArchiveProgress(gopts, stat), target, opts.Tags, parentSnapshotID) + _, id, err := arch.Snapshot(newArchiveProgress(gopts, stat), target, opts.Tags, opts.Hostname, parentSnapshotID) if err != nil { return err } diff --git a/src/restic/archiver/archive_reader.go b/src/restic/archiver/archive_reader.go index 713799a04..43beee69a 100644 --- a/src/restic/archiver/archive_reader.go +++ b/src/restic/archiver/archive_reader.go @@ -13,13 +13,13 @@ import ( // ArchiveReader reads from the reader and archives the data. Returned is the // resulting snapshot and its ID. -func ArchiveReader(repo restic.Repository, p *restic.Progress, rd io.Reader, name string, tags []string) (*restic.Snapshot, restic.ID, error) { +func ArchiveReader(repo restic.Repository, p *restic.Progress, rd io.Reader, name string, tags []string, hostname string) (*restic.Snapshot, restic.ID, error) { if name == "" { return nil, restic.ID{}, errors.New("no filename given") } debug.Log("start archiving %s", name) - sn, err := restic.NewSnapshot([]string{name}, tags) + sn, err := restic.NewSnapshot([]string{name}, tags, hostname) if err != nil { return nil, restic.ID{}, err } diff --git a/src/restic/archiver/archive_reader_test.go b/src/restic/archiver/archive_reader_test.go index 68fde3d03..bdcc2a1e8 100644 --- a/src/restic/archiver/archive_reader_test.go +++ b/src/restic/archiver/archive_reader_test.go @@ -79,7 +79,7 @@ func TestArchiveReader(t *testing.T) { f := fakeFile(t, seed, size) - sn, id, err := ArchiveReader(repo, nil, f, "fakefile", []string{"test"}) + sn, id, err := ArchiveReader(repo, nil, f, "fakefile", []string{"test"}, "localhost") if err != nil { t.Fatalf("ArchiveReader() returned error %v", err) } @@ -99,7 +99,7 @@ func TestArchiveReaderNull(t *testing.T) { repo, cleanup := repository.TestRepository(t) defer cleanup() - sn, id, err := ArchiveReader(repo, nil, bytes.NewReader(nil), "fakefile", nil) + sn, id, err := ArchiveReader(repo, nil, bytes.NewReader(nil), "fakefile", nil, "localhost") if err != nil { t.Fatalf("ArchiveReader() returned error %v", err) } @@ -134,7 +134,7 @@ func TestArchiveReaderError(t *testing.T) { repo, cleanup := repository.TestRepository(t) defer cleanup() - sn, id, err := ArchiveReader(repo, nil, errReader("error returned by reading stdin"), "fakefile", nil) + sn, id, err := ArchiveReader(repo, nil, errReader("error returned by reading stdin"), "fakefile", nil, "localhost") if err == nil { t.Errorf("expected error not returned") } @@ -171,7 +171,7 @@ func BenchmarkArchiveReader(t *testing.B) { t.ResetTimer() for i := 0; i < t.N; i++ { - _, _, err := ArchiveReader(repo, nil, bytes.NewReader(buf), "fakefile", []string{"test"}) + _, _, err := ArchiveReader(repo, nil, bytes.NewReader(buf), "fakefile", []string{"test"}, "localhost") if err != nil { t.Fatal(err) } diff --git a/src/restic/archiver/archiver.go b/src/restic/archiver/archiver.go index b5795241b..9670db1aa 100644 --- a/src/restic/archiver/archiver.go +++ b/src/restic/archiver/archiver.go @@ -634,7 +634,7 @@ func (p baseNameSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } // Snapshot creates a snapshot of the given paths. If parentrestic.ID is set, this is // used to compare the files to the ones archived at the time this snapshot was // taken. -func (arch *Archiver) Snapshot(p *restic.Progress, paths, tags []string, parentID *restic.ID) (*restic.Snapshot, restic.ID, error) { +func (arch *Archiver) Snapshot(p *restic.Progress, paths, tags []string, hostname string, parentID *restic.ID) (*restic.Snapshot, restic.ID, error) { paths = unique(paths) sort.Sort(baseNameSlice(paths)) @@ -650,7 +650,7 @@ func (arch *Archiver) Snapshot(p *restic.Progress, paths, tags []string, parentI defer p.Done() // create new snapshot - sn, err := restic.NewSnapshot(paths, tags) + sn, err := restic.NewSnapshot(paths, tags, hostname) if err != nil { return nil, restic.ID{}, err } diff --git a/src/restic/archiver/archiver_test.go b/src/restic/archiver/archiver_test.go index 4bbfef852..3cb8ba183 100644 --- a/src/restic/archiver/archiver_test.go +++ b/src/restic/archiver/archiver_test.go @@ -104,7 +104,7 @@ func archiveDirectory(b testing.TB) { arch := archiver.New(repo) - _, id, err := arch.Snapshot(nil, []string{BenchArchiveDirectory}, nil, nil) + _, id, err := arch.Snapshot(nil, []string{BenchArchiveDirectory}, nil, "localhost", nil) OK(b, err) b.Logf("snapshot archived as %v", id) diff --git a/src/restic/archiver/testing.go b/src/restic/archiver/testing.go index fef61f6c2..aad8ea1af 100644 --- a/src/restic/archiver/testing.go +++ b/src/restic/archiver/testing.go @@ -8,7 +8,7 @@ import ( // TestSnapshot creates a new snapshot of path. func TestSnapshot(t testing.TB, repo restic.Repository, path string, parent *restic.ID) *restic.Snapshot { arch := New(repo) - sn, _, err := arch.Snapshot(nil, []string{path}, []string{"test"}, parent) + sn, _, err := arch.Snapshot(nil, []string{path}, []string{"test"}, "localhost", parent) if err != nil { t.Fatal(err) } diff --git a/src/restic/checker/checker_test.go b/src/restic/checker/checker_test.go index 40e6865a3..7c93623d9 100644 --- a/src/restic/checker/checker_test.go +++ b/src/restic/checker/checker_test.go @@ -261,7 +261,7 @@ func TestCheckerModifiedData(t *testing.T) { defer cleanup() arch := archiver.New(repo) - _, id, err := arch.Snapshot(nil, []string{"."}, nil, nil) + _, id, err := arch.Snapshot(nil, []string{"."}, nil, "localhost", nil) test.OK(t, err) t.Logf("archived as %v", id.Str()) diff --git a/src/restic/snapshot.go b/src/restic/snapshot.go index f2451a280..91ffbd558 100644 --- a/src/restic/snapshot.go +++ b/src/restic/snapshot.go @@ -2,7 +2,6 @@ package restic import ( "fmt" - "os" "os/user" "path/filepath" "time" @@ -28,7 +27,7 @@ type Snapshot struct { // NewSnapshot returns an initialized snapshot struct for the current user and // time. -func NewSnapshot(paths []string, tags []string) (*Snapshot, error) { +func NewSnapshot(paths []string, tags []string, hostname string) (*Snapshot, error) { for i, path := range paths { if p, err := filepath.Abs(path); err != nil { paths[i] = p @@ -36,17 +35,13 @@ func NewSnapshot(paths []string, tags []string) (*Snapshot, error) { } sn := &Snapshot{ - Paths: paths, - Time: time.Now(), - Tags: tags, + Paths: paths, + Time: time.Now(), + Tags: tags, + Hostname: hostname, } - hn, err := os.Hostname() - if err == nil { - sn.Hostname = hn - } - - err = sn.fillUserInfo() + err := sn.fillUserInfo() if err != nil { return nil, err } diff --git a/src/restic/snapshot_test.go b/src/restic/snapshot_test.go index 2457e8d65..76e95b171 100644 --- a/src/restic/snapshot_test.go +++ b/src/restic/snapshot_test.go @@ -10,6 +10,6 @@ import ( func TestNewSnapshot(t *testing.T) { paths := []string{"/home/foobar"} - _, err := restic.NewSnapshot(paths, nil) + _, err := restic.NewSnapshot(paths, nil, "foo") OK(t, err) } diff --git a/src/restic/testing.go b/src/restic/testing.go index 719ff336d..9df54e7b6 100644 --- a/src/restic/testing.go +++ b/src/restic/testing.go @@ -163,7 +163,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"}) + snapshot, err := NewSnapshot([]string{fakedir}, []string{"test"}, "foo") if err != nil { t.Fatal(err) } diff --git a/src/restic/walk/walk_test.go b/src/restic/walk/walk_test.go index afaebbb53..057e512ca 100644 --- a/src/restic/walk/walk_test.go +++ b/src/restic/walk/walk_test.go @@ -24,7 +24,7 @@ func TestWalkTree(t *testing.T) { // archive a few files arch := archiver.New(repo) - sn, _, err := arch.Snapshot(nil, dirs, nil, nil) + sn, _, err := arch.Snapshot(nil, dirs, nil, "localhost", nil) OK(t, err) // flush repo, write all packs