2017-03-08 19:19:12 +00:00
package main
import (
"context"
2021-11-06 00:23:12 +00:00
"github.com/restic/restic/internal/backend"
2017-07-24 15:42:25 +00:00
"github.com/restic/restic/internal/restic"
2022-09-02 22:19:19 +00:00
"github.com/spf13/pflag"
2017-03-08 19:19:12 +00:00
)
2022-09-02 22:19:19 +00:00
type snapshotFilterOptions struct {
Hosts [ ] string
Tags restic . TagLists
Paths [ ] string
}
// initMultiSnapshotFilterOptions is used for commands that work on multiple snapshots
func initMultiSnapshotFilterOptions ( flags * pflag . FlagSet , options * snapshotFilterOptions , addHostShorthand bool ) {
hostShorthand := "H"
if ! addHostShorthand {
hostShorthand = ""
}
flags . StringArrayVarP ( & options . Hosts , "host" , hostShorthand , nil , "only consider snapshots for this `host` (can be specified multiple times)" )
2022-09-10 21:34:46 +00:00
flags . Var ( & options . Tags , "tag" , "only consider snapshots including `tag[,tag,...]` (can be specified multiple times)" )
flags . StringArrayVar ( & options . Paths , "path" , nil , "only consider snapshots including this (absolute) `path` (can be specified multiple times)" )
2022-09-02 22:19:19 +00:00
}
// initSingleSnapshotFilterOptions is used for commands that work on a single snapshot
func initSingleSnapshotFilterOptions ( flags * pflag . FlagSet , options * snapshotFilterOptions ) {
flags . StringArrayVarP ( & options . Hosts , "host" , "H" , nil , "only consider snapshots for this `host`, when snapshot ID \"latest\" is given (can be specified multiple times)" )
2022-09-10 21:34:46 +00:00
flags . Var ( & options . Tags , "tag" , "only consider snapshots including `tag[,tag,...]`, when snapshot ID \"latest\" is given (can be specified multiple times)" )
flags . StringArrayVar ( & options . Paths , "path" , nil , "only consider snapshots including this (absolute) `path`, when snapshot ID \"latest\" is given (can be specified multiple times)" )
2022-09-02 22:19:19 +00:00
}
2017-03-08 19:19:12 +00:00
// FindFilteredSnapshots yields Snapshots, either given explicitly by `snapshotIDs` or filtered from the list of all snapshots.
2022-06-12 12:38:19 +00:00
func FindFilteredSnapshots ( ctx context . Context , be restic . Lister , loader restic . LoaderUnpacked , hosts [ ] string , tags [ ] restic . TagList , paths [ ] string , snapshotIDs [ ] string ) <- chan * restic . Snapshot {
2017-03-08 19:19:12 +00:00
out := make ( chan * restic . Snapshot )
go func ( ) {
defer close ( out )
if len ( snapshotIDs ) != 0 {
2021-11-06 00:23:12 +00:00
// memorize snapshots list to prevent repeated backend listings
be , err := backend . MemorizeList ( ctx , be , restic . SnapshotFile )
if err != nil {
Warnf ( "could not load snapshots: %v\n" , err )
return
}
2017-03-08 19:19:12 +00:00
var (
id restic . ID
usedFilter bool
)
ids := make ( restic . IDs , 0 , len ( snapshotIDs ) )
// Process all snapshot IDs given as arguments.
for _ , s := range snapshotIDs {
if s == "latest" {
2020-08-29 18:27:30 +00:00
usedFilter = true
2021-11-06 00:14:24 +00:00
id , err = restic . FindLatestSnapshot ( ctx , be , loader , paths , tags , hosts , nil )
2017-03-08 19:19:12 +00:00
if err != nil {
2020-02-26 21:17:59 +00:00
Warnf ( "Ignoring %q, no snapshot matched given filter (Paths:%v Tags:%v Hosts:%v)\n" , s , paths , tags , hosts )
2017-03-08 19:19:12 +00:00
continue
}
} else {
2021-11-06 00:14:24 +00:00
id , err = restic . FindSnapshot ( ctx , be , s )
2017-03-08 19:19:12 +00:00
if err != nil {
2021-08-25 13:46:21 +00:00
Warnf ( "Ignoring %q: %v\n" , s , err )
2017-03-08 19:19:12 +00:00
continue
}
}
ids = append ( ids , id )
}
// Give the user some indication their filters are not used.
2020-02-26 21:17:59 +00:00
if ! usedFilter && ( len ( hosts ) != 0 || len ( tags ) != 0 || len ( paths ) != 0 ) {
2017-03-08 19:19:12 +00:00
Warnf ( "Ignoring filters as there are explicit snapshot ids given\n" )
}
for _ , id := range ids . Uniq ( ) {
2021-11-06 00:14:24 +00:00
sn , err := restic . LoadSnapshot ( ctx , loader , id )
2017-03-08 19:19:12 +00:00
if err != nil {
Warnf ( "Ignoring %q, could not load snapshot: %v\n" , id , err )
continue
}
select {
case <- ctx . Done ( ) :
return
case out <- sn :
}
}
return
}
2021-11-06 00:14:24 +00:00
snapshots , err := restic . FindFilteredSnapshots ( ctx , be , loader , hosts , tags , paths )
2018-01-21 16:25:36 +00:00
if err != nil {
Warnf ( "could not load snapshots: %v\n" , err )
return
}
for _ , sn := range snapshots {
2017-03-08 19:19:12 +00:00
select {
case <- ctx . Done ( ) :
return
case out <- sn :
}
}
} ( )
return out
}