forked from TrueCloudLab/restic
backup: Add --hostname
parameter
This commit is contained in:
parent
073edd914d
commit
f145e1de0f
11 changed files with 31 additions and 34 deletions
|
@ -51,6 +51,7 @@ type BackupOptions struct {
|
||||||
Stdin bool
|
Stdin bool
|
||||||
StdinFilename string
|
StdinFilename string
|
||||||
Tags []string
|
Tags []string
|
||||||
|
Hostname string
|
||||||
FilesFrom string
|
FilesFrom string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +60,12 @@ var backupOptions BackupOptions
|
||||||
func init() {
|
func init() {
|
||||||
cmdRoot.AddCommand(cmdBackup)
|
cmdRoot.AddCommand(cmdBackup)
|
||||||
|
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
debug.Log("os.Hostname() returned err: %v", err)
|
||||||
|
hostname = ""
|
||||||
|
}
|
||||||
|
|
||||||
f := cmdBackup.Flags()
|
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.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`)
|
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.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.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.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)")
|
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
|
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 {
|
if err != nil {
|
||||||
return err
|
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
|
// Find last snapshot to set it as parent, if not already set
|
||||||
if !opts.Force && parentSnapshotID == nil {
|
if !opts.Force && parentSnapshotID == nil {
|
||||||
hostname, err := os.Hostname()
|
id, err := restic.FindLatestSnapshot(repo, target, opts.Hostname)
|
||||||
if err != nil {
|
|
||||||
debug.Log("os.Hostname() returned err: %v", err)
|
|
||||||
hostname = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
id, err := restic.FindLatestSnapshot(repo, target, hostname)
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
parentSnapshotID = &id
|
parentSnapshotID = &id
|
||||||
} else if err != restic.ErrNoSnapshotFound {
|
} 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)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,13 +13,13 @@ import (
|
||||||
|
|
||||||
// ArchiveReader reads from the reader and archives the data. Returned is the
|
// ArchiveReader reads from the reader and archives the data. Returned is the
|
||||||
// resulting snapshot and its ID.
|
// 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 == "" {
|
if name == "" {
|
||||||
return nil, restic.ID{}, errors.New("no filename given")
|
return nil, restic.ID{}, errors.New("no filename given")
|
||||||
}
|
}
|
||||||
|
|
||||||
debug.Log("start archiving %s", name)
|
debug.Log("start archiving %s", name)
|
||||||
sn, err := restic.NewSnapshot([]string{name}, tags)
|
sn, err := restic.NewSnapshot([]string{name}, tags, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, restic.ID{}, err
|
return nil, restic.ID{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ func TestArchiveReader(t *testing.T) {
|
||||||
|
|
||||||
f := fakeFile(t, seed, size)
|
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 {
|
if err != nil {
|
||||||
t.Fatalf("ArchiveReader() returned error %v", err)
|
t.Fatalf("ArchiveReader() returned error %v", err)
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ func TestArchiveReaderNull(t *testing.T) {
|
||||||
repo, cleanup := repository.TestRepository(t)
|
repo, cleanup := repository.TestRepository(t)
|
||||||
defer cleanup()
|
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 {
|
if err != nil {
|
||||||
t.Fatalf("ArchiveReader() returned error %v", err)
|
t.Fatalf("ArchiveReader() returned error %v", err)
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ func TestArchiveReaderError(t *testing.T) {
|
||||||
repo, cleanup := repository.TestRepository(t)
|
repo, cleanup := repository.TestRepository(t)
|
||||||
defer cleanup()
|
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 {
|
if err == nil {
|
||||||
t.Errorf("expected error not returned")
|
t.Errorf("expected error not returned")
|
||||||
}
|
}
|
||||||
|
@ -171,7 +171,7 @@ func BenchmarkArchiveReader(t *testing.B) {
|
||||||
t.ResetTimer()
|
t.ResetTimer()
|
||||||
|
|
||||||
for i := 0; i < t.N; i++ {
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// 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
|
// used to compare the files to the ones archived at the time this snapshot was
|
||||||
// taken.
|
// 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)
|
paths = unique(paths)
|
||||||
sort.Sort(baseNameSlice(paths))
|
sort.Sort(baseNameSlice(paths))
|
||||||
|
|
||||||
|
@ -650,7 +650,7 @@ func (arch *Archiver) Snapshot(p *restic.Progress, paths, tags []string, parentI
|
||||||
defer p.Done()
|
defer p.Done()
|
||||||
|
|
||||||
// create new snapshot
|
// create new snapshot
|
||||||
sn, err := restic.NewSnapshot(paths, tags)
|
sn, err := restic.NewSnapshot(paths, tags, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, restic.ID{}, err
|
return nil, restic.ID{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ func archiveDirectory(b testing.TB) {
|
||||||
|
|
||||||
arch := archiver.New(repo)
|
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)
|
OK(b, err)
|
||||||
|
|
||||||
b.Logf("snapshot archived as %v", id)
|
b.Logf("snapshot archived as %v", id)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
// TestSnapshot creates a new snapshot of path.
|
// TestSnapshot creates a new snapshot of path.
|
||||||
func TestSnapshot(t testing.TB, repo restic.Repository, path string, parent *restic.ID) *restic.Snapshot {
|
func TestSnapshot(t testing.TB, repo restic.Repository, path string, parent *restic.ID) *restic.Snapshot {
|
||||||
arch := New(repo)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,7 +261,7 @@ func TestCheckerModifiedData(t *testing.T) {
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
arch := archiver.New(repo)
|
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)
|
test.OK(t, err)
|
||||||
t.Logf("archived as %v", id.Str())
|
t.Logf("archived as %v", id.Str())
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package restic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
@ -28,7 +27,7 @@ type Snapshot struct {
|
||||||
|
|
||||||
// NewSnapshot returns an initialized snapshot struct for the current user and
|
// NewSnapshot returns an initialized snapshot struct for the current user and
|
||||||
// time.
|
// time.
|
||||||
func NewSnapshot(paths []string, tags []string) (*Snapshot, error) {
|
func NewSnapshot(paths []string, tags []string, hostname string) (*Snapshot, error) {
|
||||||
for i, path := range paths {
|
for i, path := range paths {
|
||||||
if p, err := filepath.Abs(path); err != nil {
|
if p, err := filepath.Abs(path); err != nil {
|
||||||
paths[i] = p
|
paths[i] = p
|
||||||
|
@ -39,14 +38,10 @@ func NewSnapshot(paths []string, tags []string) (*Snapshot, error) {
|
||||||
Paths: paths,
|
Paths: paths,
|
||||||
Time: time.Now(),
|
Time: time.Now(),
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
|
Hostname: hostname,
|
||||||
}
|
}
|
||||||
|
|
||||||
hn, err := os.Hostname()
|
err := sn.fillUserInfo()
|
||||||
if err == nil {
|
|
||||||
sn.Hostname = hn
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sn.fillUserInfo()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,6 @@ import (
|
||||||
func TestNewSnapshot(t *testing.T) {
|
func TestNewSnapshot(t *testing.T) {
|
||||||
paths := []string{"/home/foobar"}
|
paths := []string{"/home/foobar"}
|
||||||
|
|
||||||
_, err := restic.NewSnapshot(paths, nil)
|
_, err := restic.NewSnapshot(paths, nil, "foo")
|
||||||
OK(t, err)
|
OK(t, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
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"))
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ func TestWalkTree(t *testing.T) {
|
||||||
|
|
||||||
// archive a few files
|
// archive a few files
|
||||||
arch := archiver.New(repo)
|
arch := archiver.New(repo)
|
||||||
sn, _, err := arch.Snapshot(nil, dirs, nil, nil)
|
sn, _, err := arch.Snapshot(nil, dirs, nil, "localhost", nil)
|
||||||
OK(t, err)
|
OK(t, err)
|
||||||
|
|
||||||
// flush repo, write all packs
|
// flush repo, write all packs
|
||||||
|
|
Loading…
Reference in a new issue