forked from TrueCloudLab/restic
wip
This commit is contained in:
parent
0c078cc205
commit
7ad648c686
4 changed files with 39 additions and 17 deletions
|
@ -21,6 +21,7 @@ import (
|
|||
"github.com/restic/restic/internal/restic"
|
||||
"github.com/restic/restic/internal/textfile"
|
||||
"github.com/restic/restic/internal/ui"
|
||||
"github.com/restic/restic/internal/ui/config"
|
||||
"github.com/restic/restic/internal/ui/termstatus"
|
||||
)
|
||||
|
||||
|
@ -43,6 +44,11 @@ given as the arguments.
|
|||
},
|
||||
DisableAutoGenTag: true,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
err := config.ApplyFlags(&backupOptions.Config, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if backupOptions.Stdin && backupOptions.FilesFrom == "-" {
|
||||
return errors.Fatal("cannot use both `--stdin` and `--files-from -`")
|
||||
}
|
||||
|
@ -51,7 +57,7 @@ given as the arguments.
|
|||
term := termstatus.New(globalOptions.stdout, globalOptions.stderr, globalOptions.Quiet)
|
||||
t.Go(func() error { term.Run(t.Context(globalOptions.ctx)); return nil })
|
||||
|
||||
err := runBackup(backupOptions, globalOptions, term, args)
|
||||
err = runBackup(backupOptions, globalOptions, term, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -62,9 +68,10 @@ given as the arguments.
|
|||
|
||||
// BackupOptions bundles all options for the backup command.
|
||||
type BackupOptions struct {
|
||||
Config config.Backup
|
||||
|
||||
Parent string
|
||||
Force bool
|
||||
Excludes []string
|
||||
ExcludeFiles []string
|
||||
ExcludeOtherFS bool
|
||||
ExcludeIfPresent []string
|
||||
|
@ -86,7 +93,9 @@ func init() {
|
|||
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)`)
|
||||
f.StringArrayVarP(&backupOptions.Excludes, "exclude", "e", nil, "exclude a `pattern` (can be specified multiple times)")
|
||||
|
||||
f.StringArrayP("exclude", "e", nil, "exclude a `pattern` (can be specified multiple times)")
|
||||
|
||||
f.StringArrayVar(&backupOptions.ExcludeFiles, "exclude-file", nil, "read exclude patterns from a `file` (can be specified multiple times)")
|
||||
f.BoolVarP(&backupOptions.ExcludeOtherFS, "one-file-system", "x", false, "exclude other file systems")
|
||||
f.StringArrayVar(&backupOptions.ExcludeIfPresent, "exclude-if-present", nil, "takes filename[:header], exclude contents of directories containing filename (except filename itself) if header of that file is as provided (can be specified multiple times)")
|
||||
|
@ -188,12 +197,12 @@ func (opts BackupOptions) Check(gopts GlobalOptions, args []string) error {
|
|||
|
||||
// collectRejectFuncs returns a list of all functions which may reject data
|
||||
// from being saved in a snapshot
|
||||
func collectRejectFuncs(opts BackupOptions, repo *repository.Repository, targets []string) (fs []RejectFunc, err error) {
|
||||
func collectRejectFuncs(opts BackupOptions, repo *repository.Repository, targets []string) (fs []RejectFunc, excludes []string, err error) {
|
||||
// allowed devices
|
||||
if opts.ExcludeOtherFS {
|
||||
f, err := rejectByDevice(targets)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
fs = append(fs, f)
|
||||
}
|
||||
|
@ -202,19 +211,21 @@ func collectRejectFuncs(opts BackupOptions, repo *repository.Repository, targets
|
|||
if repo.Cache != nil {
|
||||
f, err := rejectResticCache(repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
fs = append(fs, f)
|
||||
}
|
||||
|
||||
excludes = append(excludes, opts.Config.Excludes...)
|
||||
|
||||
// add patterns from file
|
||||
if len(opts.ExcludeFiles) > 0 {
|
||||
opts.Excludes = append(opts.Excludes, readExcludePatternsFromFiles(opts.ExcludeFiles)...)
|
||||
excludes = append(excludes, readExcludePatternsFromFiles(opts.ExcludeFiles)...)
|
||||
}
|
||||
|
||||
if len(opts.Excludes) > 0 {
|
||||
fs = append(fs, rejectByPattern(opts.Excludes))
|
||||
if len(excludes) > 0 {
|
||||
fs = append(fs, rejectByPattern(excludes))
|
||||
}
|
||||
|
||||
if opts.ExcludeCaches {
|
||||
|
@ -224,13 +235,13 @@ func collectRejectFuncs(opts BackupOptions, repo *repository.Repository, targets
|
|||
for _, spec := range opts.ExcludeIfPresent {
|
||||
f, err := rejectIfPresent(spec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
fs = append(fs, f)
|
||||
}
|
||||
|
||||
return fs, nil
|
||||
return fs, excludes, nil
|
||||
}
|
||||
|
||||
// readExcludePatternsFromFiles reads all exclude files and returns the list of
|
||||
|
@ -381,7 +392,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||
}
|
||||
|
||||
// rejectFuncs collect functions that can reject items from the backup
|
||||
rejectFuncs, err := collectRejectFuncs(opts, repo, targets)
|
||||
rejectFuncs, excludes, err := collectRejectFuncs(opts, repo, targets)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -443,7 +454,7 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||
}
|
||||
|
||||
snapshotOpts := archiver.SnapshotOptions{
|
||||
Excludes: opts.Excludes,
|
||||
Excludes: excludes,
|
||||
Tags: opts.Tags,
|
||||
Time: timeStamp,
|
||||
Hostname: opts.Hostname,
|
||||
|
|
|
@ -390,14 +390,14 @@ func TestBackupExclude(t *testing.T) {
|
|||
rtest.Assert(t, includes(files, "/testdata/foo.tar.gz"),
|
||||
"expected file %q in first snapshot, but it's not included", "foo.tar.gz")
|
||||
|
||||
opts.Excludes = []string{"*.tar.gz"}
|
||||
opts.Config.Excludes = []string{"*.tar.gz"}
|
||||
testRunBackup(t, filepath.Dir(env.testdata), []string{"testdata"}, opts, env.gopts)
|
||||
snapshots, snapshotID = lastSnapshot(snapshots, loadSnapshotMap(t, env.gopts))
|
||||
files = testRunLs(t, env.gopts, snapshotID)
|
||||
rtest.Assert(t, !includes(files, "/testdata/foo.tar.gz"),
|
||||
"expected file %q not in first snapshot, but it's included", "foo.tar.gz")
|
||||
|
||||
opts.Excludes = []string{"*.tar.gz", "private/secret"}
|
||||
opts.Config.Excludes = []string{"*.tar.gz", "private/secret"}
|
||||
testRunBackup(t, filepath.Dir(env.testdata), []string{"testdata"}, opts, env.gopts)
|
||||
_, snapshotID = lastSnapshot(snapshots, loadSnapshotMap(t, env.gopts))
|
||||
files = testRunLs(t, env.gopts, snapshotID)
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/restic/restic/internal/debug"
|
||||
"github.com/restic/restic/internal/options"
|
||||
"github.com/restic/restic/internal/restic"
|
||||
|
@ -46,6 +47,8 @@ directories in an encrypted repository stored on different backends.
|
|||
return err
|
||||
}
|
||||
|
||||
spew.Dump(globalOptions.Config)
|
||||
|
||||
// set verbosity, default is one
|
||||
globalOptions.verbosity = 1
|
||||
if globalOptions.Quiet && (globalOptions.Verbose > 1) {
|
||||
|
|
|
@ -20,7 +20,7 @@ type Config struct {
|
|||
PasswordFile string `config:"password_file" flag:"password-file" env:"RESTIC_PASSWORD_FILE"`
|
||||
|
||||
Backends map[string]Backend `config:"backend"`
|
||||
Backup *Backup `config:"backup"`
|
||||
Backup Backup `config:"backup"`
|
||||
}
|
||||
|
||||
// Backend is a configured backend to store a repository.
|
||||
|
@ -31,7 +31,8 @@ type Backend struct {
|
|||
|
||||
// Backup sets the options for the "backup" command.
|
||||
type Backup struct {
|
||||
Target []string `config:"target"`
|
||||
Target []string `config:"target"`
|
||||
Excludes []string `config:"exclude" flag:"exclude"`
|
||||
}
|
||||
|
||||
// listTags returns the all the top-level tags with the name tagname of obj.
|
||||
|
@ -190,6 +191,13 @@ func ApplyFlags(cfg interface{}, fset *pflag.FlagSet) error {
|
|||
return
|
||||
}
|
||||
field.SetString(v)
|
||||
case "stringArray":
|
||||
v, err := fset.GetStringArray(flag.Name)
|
||||
if err != nil {
|
||||
visitError = err
|
||||
return
|
||||
}
|
||||
field.SetSlice(v)
|
||||
default:
|
||||
visitError = errors.Errorf("flag %v has unknown type %v", flag.Name, flag.Value.Type())
|
||||
return
|
||||
|
|
Loading…
Reference in a new issue