Move FindSnapshot, make Repository.List() return IDs

This commit is contained in:
Alexander Neumann 2015-05-17 20:48:59 +02:00
parent cf37b619fd
commit 6e38a8a033
12 changed files with 75 additions and 97 deletions

View file

@ -56,18 +56,6 @@ func Find(be Lister, t Type, prefix string) (string, error) {
return "", ErrNoIDPrefixFound
}
// FindSnapshot takes a string and tries to find a snapshot whose ID matches
// the string as closely as possible.
func FindSnapshot(be Lister, s string) (string, error) {
// find snapshot id with prefix
name, err := Find(be, Snapshot, s)
if err != nil {
return "", err
}
return name, nil
}
// PrefixLength returns the number of bytes required so that all prefixes of
// all names of type t are unique.
func PrefixLength(be Lister, t Type) (int, error) {

View file

@ -185,28 +185,20 @@ func (cmd CmdBackup) Execute(args []string) error {
return err
}
var (
parentSnapshot string
parentSnapshotID backend.ID
)
var parentSnapshotID backend.ID
// Force using a parent
if !cmd.Force && cmd.Parent != "" {
parentSnapshot, err = s.FindSnapshot(cmd.Parent)
parentSnapshotID, err = restic.FindSnapshot(s, cmd.Parent)
if err != nil {
return fmt.Errorf("invalid id %q: %v", cmd.Parent, err)
}
parentSnapshotID, err = backend.ParseID(parentSnapshot)
if err != nil {
return fmt.Errorf("invalid parent snapshot id %v", parentSnapshot)
}
fmt.Printf("found parent snapshot %v\n", parentSnapshotID)
}
// Find last snapshot to set it as parent, if not already set
if !cmd.Force && parentSnapshot == "" {
if !cmd.Force && parentSnapshotID == nil {
samePaths := func(expected, actual []string) bool {
if len(expected) != len(actual) {
return false
@ -221,24 +213,19 @@ func (cmd CmdBackup) Execute(args []string) error {
var latest time.Time
for snapshotIDString := range s.List(backend.Snapshot, make(chan struct{})) {
snapshotID, err := backend.ParseID(snapshotIDString)
if err != nil {
return fmt.Errorf("Error with the listing of snapshots inputting invalid backend ids: %v", err)
}
snapshot, err := restic.LoadSnapshot(s, snapshotID)
for id := range s.List(backend.Snapshot, make(chan struct{})) {
snapshot, err := restic.LoadSnapshot(s, id)
if err != nil {
return fmt.Errorf("Error listing snapshot: %v", err)
}
if snapshot.Time.After(latest) && samePaths(snapshot.Paths, target) {
latest = snapshot.Time
parentSnapshotID = snapshotID
parentSnapshot = snapshotIDString
parentSnapshotID = id
}
}
if parentSnapshot != "" {
if parentSnapshotID != nil {
fmt.Printf("using parent snapshot %v\n", parentSnapshotID)
}
}

View file

@ -53,12 +53,7 @@ func (cmd CmdCat) Execute(args []string) error {
}
// find snapshot id with prefix
name, err := s.FindSnapshot(args[1])
if err != nil {
return err
}
id, err = backend.ParseID(name)
id, err = restic.FindSnapshot(s, args[1])
if err != nil {
return err
}

View file

@ -105,13 +105,8 @@ func (c CmdFind) findInTree(repo *repository.Repository, id backend.ID, path str
return results, nil
}
func (c CmdFind) findInSnapshot(repo *repository.Repository, name string) error {
debug.Log("restic.find", "searching in snapshot %s\n for entries within [%s %s]", name, c.oldest, c.newest)
id, err := backend.ParseID(name)
if err != nil {
return err
}
func (c CmdFind) findInSnapshot(repo *repository.Repository, id backend.ID) error {
debug.Log("restic.find", "searching in snapshot %s\n for entries within [%s %s]", id.Str(), c.oldest, c.newest)
sn, err := restic.LoadSnapshot(repo, id)
if err != nil {
@ -169,7 +164,7 @@ func (c CmdFind) Execute(args []string) error {
c.pattern = args[0]
if c.Snapshot != "" {
snapshotID, err := backend.FindSnapshot(s, c.Snapshot)
snapshotID, err := restic.FindSnapshot(s, c.Snapshot)
if err != nil {
return fmt.Errorf("invalid id %q: %v", args[1], err)
}

View file

@ -198,16 +198,11 @@ func (cmd CmdFsck) Execute(args []string) error {
}
if cmd.Snapshot != "" {
name, err := s.FindSnapshot(cmd.Snapshot)
id, err := restic.FindSnapshot(s, cmd.Snapshot)
if err != nil {
return fmt.Errorf("invalid id %q: %v", cmd.Snapshot, err)
}
id, err := backend.ParseID(name)
if err != nil {
fmt.Fprintf(os.Stderr, "invalid snapshot id %v\n", name)
}
err = fsckSnapshot(cmd, s, id)
if err != nil {
fmt.Fprintf(os.Stderr, "check for snapshot %v failed\n", id)
@ -225,13 +220,7 @@ func (cmd CmdFsck) Execute(args []string) error {
defer close(done)
var firstErr error
for name := range s.List(backend.Snapshot, done) {
id, err := backend.ParseID(name)
if err != nil {
fmt.Fprintf(os.Stderr, "invalid snapshot id %v\n", name)
continue
}
for id := range s.List(backend.Snapshot, done) {
err = fsckSnapshot(cmd, s, id)
if err != nil {
fmt.Fprintf(os.Stderr, "check for snapshot %v failed\n", id)

View file

@ -34,20 +34,20 @@ func listKeys(s *repository.Repository) error {
done := make(chan struct{})
defer close(done)
for name := range s.List(backend.Key, done) {
k, err := repository.LoadKey(s, name)
for id := range s.List(backend.Key, done) {
k, err := repository.LoadKey(s, id.String())
if err != nil {
fmt.Fprintf(os.Stderr, "LoadKey() failed: %v\n", err)
continue
}
var current string
if name == s.KeyName() {
if id.String() == s.KeyName() {
current = "*"
} else {
current = " "
}
tab.Rows = append(tab.Rows, []interface{}{current, name[:plen],
tab.Rows = append(tab.Rows, []interface{}{current, id.String()[:plen],
k.Username, k.Hostname, k.Created.Format(TimeFormat)})
}
@ -133,7 +133,7 @@ func (cmd CmdKey) Execute(args []string) error {
case "add":
return addKey(s)
case "rm":
id, err := backend.Find(s, backend.Key, args[1])
id, err := backend.Find(s.Backend(), backend.Key, args[1])
if err != nil {
return err
}

View file

@ -77,12 +77,7 @@ func (cmd CmdLs) Execute(args []string) error {
return err
}
name, err := backend.FindSnapshot(s, args[0])
if err != nil {
return err
}
id, err := backend.ParseID(name)
id, err := restic.FindSnapshot(s, args[0])
if err != nil {
return err
}

View file

@ -6,7 +6,6 @@ import (
"path/filepath"
"github.com/restic/restic"
"github.com/restic/restic/backend"
)
type CmdRestore struct{}
@ -40,12 +39,7 @@ func (cmd CmdRestore) Execute(args []string) error {
return err
}
name, err := backend.FindSnapshot(s, args[0])
if err != nil {
errx(1, "invalid id %q: %v", args[0], err)
}
id, err := backend.ParseID(name)
id, err := restic.FindSnapshot(s, args[0])
if err != nil {
errx(1, "invalid id %q: %v", args[0], err)
}

View file

@ -105,13 +105,7 @@ func (cmd CmdSnapshots) Execute(args []string) error {
defer close(done)
list := []*restic.Snapshot{}
for name := range s.List(backend.Snapshot, done) {
id, err := backend.ParseID(name)
if err != nil {
fmt.Fprintf(os.Stderr, "error parsing id: %v", name)
continue
}
for id := range s.List(backend.Snapshot, done) {
sn, err := restic.LoadSnapshot(s, id)
if err != nil {
fmt.Fprintf(os.Stderr, "error loading snapshot %s: %v\n", id, err)

View file

@ -98,7 +98,7 @@ func SearchKey(s *Repository, password string) (*Key, error) {
// try all keys in repo
done := make(chan struct{})
defer close(done)
for name := range s.List(backend.Key, done) {
for name := range s.Backend().List(backend.Key, done) {
key, err := OpenKey(s, name, password)
if err != nil {
continue

View file

@ -52,12 +52,6 @@ func (s *Repository) Find(t backend.Type, prefix string) (string, error) {
return backend.Find(s.be, t, prefix)
}
// FindSnapshot takes a string and tries to find a snapshot whose ID matches
// the string as closely as possible.
func (s *Repository) FindSnapshot(name string) (string, error) {
return backend.FindSnapshot(s.be, name)
}
// PrefixLength returns the number of bytes required so that all prefixes of
// all IDs of type t are unique.
func (s *Repository) PrefixLength(t backend.Type) (int, error) {
@ -637,14 +631,49 @@ func (s *Repository) Count(t backend.Type) (n uint) {
return
}
// Proxy methods to backend
func (s *Repository) list(t backend.Type, done <-chan struct{}, out chan<- backend.ID) {
defer close(out)
in := s.be.List(t, done)
func (s *Repository) Get(t backend.Type, name string) (io.ReadCloser, error) {
return s.be.Get(t, name)
var (
// disable sending on the outCh until we received a job
outCh chan<- backend.ID
// enable receiving from in
inCh = in
id backend.ID
err error
)
for {
select {
case <-done:
return
case strID, ok := <-inCh:
if !ok {
// input channel closed, we're done
return
}
id, err = backend.ParseID(strID)
if err != nil {
// ignore invalid IDs
continue
}
inCh = nil
outCh = out
case outCh <- id:
outCh = nil
inCh = in
}
}
}
func (s *Repository) List(t backend.Type, done <-chan struct{}) <-chan string {
return s.be.List(t, done)
func (s *Repository) List(t backend.Type, done <-chan struct{}) <-chan backend.ID {
outCh := make(chan backend.ID)
go s.list(t, done, outCh)
return outCh
}
func (s *Repository) Test(t backend.Type, name string) (bool, error) {

View file

@ -89,3 +89,15 @@ func (sn *Snapshot) fillUserInfo() error {
return nil
}
// FindSnapshot takes a string and tries to find a snapshot whose ID matches
// the string as closely as possible.
func FindSnapshot(repo *repository.Repository, s string) (backend.ID, error) {
// find snapshot id with prefix
name, err := backend.Find(repo.Backend(), backend.Snapshot, s)
if err != nil {
return nil, err
}
return backend.ParseID(name)
}