github.com/mckael/restic@v0.8.3/internal/restic/snapshot_find.go (about)

     1  package restic
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"time"
     8  
     9  	"github.com/restic/restic/internal/errors"
    10  )
    11  
    12  // ErrNoSnapshotFound is returned when no snapshot for the given criteria could be found.
    13  var ErrNoSnapshotFound = errors.New("no snapshot found")
    14  
    15  // FindLatestSnapshot finds latest snapshot with optional target/directory, tags and hostname filters.
    16  func FindLatestSnapshot(ctx context.Context, repo Repository, targets []string, tagLists []TagList, hostname string) (ID, error) {
    17  	var (
    18  		latest   time.Time
    19  		latestID ID
    20  		found    bool
    21  	)
    22  
    23  	err := repo.List(ctx, SnapshotFile, func(snapshotID ID, size int64) error {
    24  		snapshot, err := LoadSnapshot(ctx, repo, snapshotID)
    25  		if err != nil {
    26  			return errors.Errorf("Error loading snapshot %v: %v", snapshotID.Str(), err)
    27  		}
    28  		if snapshot.Time.Before(latest) || (hostname != "" && hostname != snapshot.Hostname) {
    29  			return nil
    30  		}
    31  
    32  		if !snapshot.HasTagList(tagLists) {
    33  			return nil
    34  		}
    35  
    36  		if !snapshot.HasPaths(targets) {
    37  			return nil
    38  		}
    39  
    40  		latest = snapshot.Time
    41  		latestID = snapshotID
    42  		found = true
    43  		return nil
    44  	})
    45  
    46  	if err != nil {
    47  		return ID{}, err
    48  	}
    49  
    50  	if !found {
    51  		return ID{}, ErrNoSnapshotFound
    52  	}
    53  
    54  	return latestID, nil
    55  }
    56  
    57  // FindSnapshot takes a string and tries to find a snapshot whose ID matches
    58  // the string as closely as possible.
    59  func FindSnapshot(repo Repository, s string) (ID, error) {
    60  
    61  	// find snapshot id with prefix
    62  	name, err := Find(repo.Backend(), SnapshotFile, s)
    63  	if err != nil {
    64  		return ID{}, err
    65  	}
    66  
    67  	return ParseID(name)
    68  }
    69  
    70  // FindFilteredSnapshots yields Snapshots filtered from the list of all
    71  // snapshots.
    72  func FindFilteredSnapshots(ctx context.Context, repo Repository, host string, tags []TagList, paths []string) (Snapshots, error) {
    73  	results := make(Snapshots, 0, 20)
    74  
    75  	err := repo.List(ctx, SnapshotFile, func(id ID, size int64) error {
    76  		sn, err := LoadSnapshot(ctx, repo, id)
    77  		if err != nil {
    78  			fmt.Fprintf(os.Stderr, "could not load snapshot %v: %v\n", id.Str(), err)
    79  			return nil
    80  		}
    81  
    82  		if (host != "" && host != sn.Hostname) || !sn.HasTagList(tags) || !sn.HasPaths(paths) {
    83  			return nil
    84  		}
    85  
    86  		results = append(results, sn)
    87  		return nil
    88  	})
    89  
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	return results, nil
    95  }