From d97f49285f632a84b95a965f381bfb669bbc5875 Mon Sep 17 00:00:00 2001 From: Jarek Kowalski Date: Mon, 19 Feb 2018 10:53:29 -0800 Subject: [PATCH] policy CLI and API cleanup --- cli/command_policy_set.go | 23 ++++++++++++----- cli/command_policy_show.go | 47 +++++++++++++++++++++++++++++++++- cli/command_snapshot_expire.go | 44 +++++++++++++++---------------- policy/policy.go | 20 +++++++-------- policy/policy_manager.go | 8 ------ 5 files changed, 95 insertions(+), 47 deletions(-) diff --git a/cli/command_policy_set.go b/cli/command_policy_set.go index 01df0bc81..b0600d7c8 100644 --- a/cli/command_policy_set.go +++ b/cli/command_policy_set.go @@ -63,27 +63,27 @@ func setPolicy(context *kingpin.ParseContext) error { p = &policy.Policy{} } - if err := applyPolicyNumber(target, "number of annual backups to keep", &p.ExpirationPolicy.KeepAnnual, *policySetKeepAnnual); err != nil { + if err := applyPolicyNumber(target, "number of annual backups to keep", &p.RetentionPolicy.KeepAnnual, *policySetKeepAnnual); err != nil { return err } - if err := applyPolicyNumber(target, "number of monthly backups to keep", &p.ExpirationPolicy.KeepMonthly, *policySetKeepMonthly); err != nil { + if err := applyPolicyNumber(target, "number of monthly backups to keep", &p.RetentionPolicy.KeepMonthly, *policySetKeepMonthly); err != nil { return err } - if err := applyPolicyNumber(target, "number of weekly backups to keep", &p.ExpirationPolicy.KeepWeekly, *policySetKeepWeekly); err != nil { + if err := applyPolicyNumber(target, "number of weekly backups to keep", &p.RetentionPolicy.KeepWeekly, *policySetKeepWeekly); err != nil { return err } - if err := applyPolicyNumber(target, "number of daily backups to keep", &p.ExpirationPolicy.KeepDaily, *policySetKeepDaily); err != nil { + if err := applyPolicyNumber(target, "number of daily backups to keep", &p.RetentionPolicy.KeepDaily, *policySetKeepDaily); err != nil { return err } - if err := applyPolicyNumber(target, "number of hourly backups to keep", &p.ExpirationPolicy.KeepHourly, *policySetKeepHourly); err != nil { + if err := applyPolicyNumber(target, "number of hourly backups to keep", &p.RetentionPolicy.KeepHourly, *policySetKeepHourly); err != nil { return err } - if err := applyPolicyNumber(target, "number of latest backups to keep", &p.ExpirationPolicy.KeepLatest, *policySetKeepLatest); err != nil { + if err := applyPolicyNumber(target, "number of latest backups to keep", &p.RetentionPolicy.KeepLatest, *policySetKeepLatest); err != nil { return err } @@ -104,6 +104,17 @@ func setPolicy(context *kingpin.ParseContext) error { p.FilesPolicy.Exclude = nil } + for _, path := range *policySetAddInclude { + p.FilesPolicy.Include = addString(p.FilesPolicy.Include, path) + } + + for _, path := range *policySetRemoveInclude { + p.FilesPolicy.Include = removeString(p.FilesPolicy.Include, path) + } + + if *policySetClearInclude { + p.FilesPolicy.Include = nil + } if err := mgr.SetPolicy(target.UserName, target.Host, target.Path, p); err != nil { return fmt.Errorf("can't save policy for %v: %v", target, err) } diff --git a/cli/command_policy_show.go b/cli/command_policy_show.go index 320287dbf..89ad27bad 100644 --- a/cli/command_policy_show.go +++ b/cli/command_policy_show.go @@ -1,9 +1,11 @@ package cli import ( + "bytes" "fmt" "os" + "github.com/kopia/kopia/internal/units" "github.com/kopia/kopia/policy" kingpin "gopkg.in/alecthomas/kingpin.v2" ) @@ -43,7 +45,7 @@ func showPolicy(context *kingpin.ParseContext) error { if err == nil { fmt.Printf("The %v policy for %q:\n", policyKind, target) - fmt.Println(p) + fmt.Println(policyToString(p)) continue } @@ -57,3 +59,46 @@ func showPolicy(context *kingpin.ParseContext) error { return nil } + +func policyToString(p *policy.Policy) string { + var buf bytes.Buffer + + fmt.Fprintf(&buf, "Retention policy:\n") + fmt.Fprintf(&buf, " keep annual:%v monthly:%v weekly:%v daily:%v hourly:%v latest:%v\n", + valueOrNotSet(p.RetentionPolicy.KeepAnnual), + valueOrNotSet(p.RetentionPolicy.KeepMonthly), + valueOrNotSet(p.RetentionPolicy.KeepWeekly), + valueOrNotSet(p.RetentionPolicy.KeepDaily), + valueOrNotSet(p.RetentionPolicy.KeepHourly), + valueOrNotSet(p.RetentionPolicy.KeepLatest), + ) + + fmt.Fprintf(&buf, "Files policy:\n") + + if len(p.FilesPolicy.Include) == 0 { + fmt.Fprintf(&buf, " Include all files\n") + } else { + fmt.Fprintf(&buf, " Include only:\n") + } + for _, inc := range p.FilesPolicy.Include { + fmt.Fprintf(&buf, " %v\n", inc) + } + if len(p.FilesPolicy.Exclude) > 0 { + fmt.Fprintf(&buf, " Exclude:\n") + } + for _, exc := range p.FilesPolicy.Exclude { + fmt.Fprintf(&buf, " %v\n", exc) + } + if s := p.FilesPolicy.MaxSize; s != nil { + fmt.Fprintf(&buf, " Exclude files above size: %v\n", units.BytesStringBase2(int64(*s))) + } + return buf.String() +} + +func valueOrNotSet(p *int) string { + if p == nil { + return "(none)" + } + + return fmt.Sprintf("%v", *p) +} diff --git a/cli/command_snapshot_expire.go b/cli/command_snapshot_expire.go index 501c39ff8..bd46a6c63 100644 --- a/cli/command_snapshot_expire.go +++ b/cli/command_snapshot_expire.go @@ -36,24 +36,24 @@ func expireSnapshotsForSingleSource(snapshots []*snapshot.Manifest, src *snapsho var hourlyCutoffTime time.Time var weeklyCutoffTime time.Time - if pol.ExpirationPolicy.KeepAnnual != nil { - annualCutoffTime = time.Now().AddDate(-*pol.ExpirationPolicy.KeepAnnual, 0, 0) + if pol.RetentionPolicy.KeepAnnual != nil { + annualCutoffTime = time.Now().AddDate(-*pol.RetentionPolicy.KeepAnnual, 0, 0) } - if pol.ExpirationPolicy.KeepMonthly != nil { - monthlyCutoffTime = time.Now().AddDate(0, -*pol.ExpirationPolicy.KeepMonthly, 0) + if pol.RetentionPolicy.KeepMonthly != nil { + monthlyCutoffTime = time.Now().AddDate(0, -*pol.RetentionPolicy.KeepMonthly, 0) } - if pol.ExpirationPolicy.KeepDaily != nil { - dailyCutoffTime = time.Now().AddDate(0, 0, -*pol.ExpirationPolicy.KeepDaily) + if pol.RetentionPolicy.KeepDaily != nil { + dailyCutoffTime = time.Now().AddDate(0, 0, -*pol.RetentionPolicy.KeepDaily) } - if pol.ExpirationPolicy.KeepHourly != nil { - hourlyCutoffTime = time.Now().Add(time.Duration(-*pol.ExpirationPolicy.KeepHourly) * time.Hour) + if pol.RetentionPolicy.KeepHourly != nil { + hourlyCutoffTime = time.Now().Add(time.Duration(-*pol.RetentionPolicy.KeepHourly) * time.Hour) } - if pol.ExpirationPolicy.KeepWeekly != nil { - weeklyCutoffTime = time.Now().AddDate(0, 0, -7**pol.ExpirationPolicy.KeepWeekly) + if pol.RetentionPolicy.KeepWeekly != nil { + weeklyCutoffTime = time.Now().AddDate(0, 0, -7**pol.RetentionPolicy.KeepWeekly) } fmt.Printf("\n%v\n", src) @@ -73,24 +73,24 @@ func expireSnapshotsForSingleSource(snapshots []*snapshot.Manifest, src *snapsho continue } - if pol.ExpirationPolicy.KeepLatest != nil { - registerSnapshot(fmt.Sprintf("%v", i), "latest", *pol.ExpirationPolicy.KeepLatest) + if pol.RetentionPolicy.KeepLatest != nil { + registerSnapshot(fmt.Sprintf("%v", i), "latest", *pol.RetentionPolicy.KeepLatest) } - if s.StartTime.After(annualCutoffTime) && pol.ExpirationPolicy.KeepAnnual != nil { - registerSnapshot(s.StartTime.Format("2006"), "annual", *pol.ExpirationPolicy.KeepAnnual) + if s.StartTime.After(annualCutoffTime) && pol.RetentionPolicy.KeepAnnual != nil { + registerSnapshot(s.StartTime.Format("2006"), "annual", *pol.RetentionPolicy.KeepAnnual) } - if s.StartTime.After(monthlyCutoffTime) && pol.ExpirationPolicy.KeepMonthly != nil { - registerSnapshot(s.StartTime.Format("2006-01"), "monthly", *pol.ExpirationPolicy.KeepMonthly) + if s.StartTime.After(monthlyCutoffTime) && pol.RetentionPolicy.KeepMonthly != nil { + registerSnapshot(s.StartTime.Format("2006-01"), "monthly", *pol.RetentionPolicy.KeepMonthly) } - if s.StartTime.After(weeklyCutoffTime) && pol.ExpirationPolicy.KeepWeekly != nil { + if s.StartTime.After(weeklyCutoffTime) && pol.RetentionPolicy.KeepWeekly != nil { yyyy, wk := s.StartTime.ISOWeek() - registerSnapshot(fmt.Sprintf("%04v-%02v", yyyy, wk), "weekly", *pol.ExpirationPolicy.KeepWeekly) + registerSnapshot(fmt.Sprintf("%04v-%02v", yyyy, wk), "weekly", *pol.RetentionPolicy.KeepWeekly) } - if s.StartTime.After(dailyCutoffTime) && pol.ExpirationPolicy.KeepDaily != nil { - registerSnapshot(s.StartTime.Format("2006-01-02"), "daily", *pol.ExpirationPolicy.KeepDaily) + if s.StartTime.After(dailyCutoffTime) && pol.RetentionPolicy.KeepDaily != nil { + registerSnapshot(s.StartTime.Format("2006-01-02"), "daily", *pol.RetentionPolicy.KeepDaily) } - if s.StartTime.After(hourlyCutoffTime) && pol.ExpirationPolicy.KeepHourly != nil { - registerSnapshot(s.StartTime.Format("2006-01-02 15"), "hourly", *pol.ExpirationPolicy.KeepHourly) + if s.StartTime.After(hourlyCutoffTime) && pol.RetentionPolicy.KeepHourly != nil { + registerSnapshot(s.StartTime.Format("2006-01-02 15"), "hourly", *pol.RetentionPolicy.KeepHourly) } tm := s.StartTime.Local().Format("2006-01-02 15:04:05 MST") diff --git a/policy/policy.go b/policy/policy.go index c47eadd43..c6ad08af6 100644 --- a/policy/policy.go +++ b/policy/policy.go @@ -14,8 +14,8 @@ // ErrPolicyNotFound is returned when the policy is not found. var ErrPolicyNotFound = errors.New("policy not found") -// ExpirationPolicy describes snapshot expiration policy. -type ExpirationPolicy struct { +// RetentionPolicy describes snapshot retention policy. +type RetentionPolicy struct { KeepLatest *int `json:"keepLatest,omitempty"` KeepHourly *int `json:"keepHourly,omitempty"` KeepDaily *int `json:"keepDaily,omitempty"` @@ -24,7 +24,7 @@ type ExpirationPolicy struct { KeepAnnual *int `json:"keepAnnual,omitempty"` } -var defaultExpirationPolicy = &ExpirationPolicy{ +var defaultRetentionPolicy = &RetentionPolicy{ KeepLatest: intPtr(1), KeepHourly: intPtr(48), KeepDaily: intPtr(7), @@ -75,10 +75,10 @@ func (p *FilesPolicy) ShouldInclude(e *fs.EntryMetadata) bool { // Policy describes snapshot policy for a single source. type Policy struct { - Labels map[string]string `json:"-"` - ExpirationPolicy ExpirationPolicy `json:"expiration"` - FilesPolicy FilesPolicy `json:"files"` - NoParent bool `json:"noParent,omitempty"` + Labels map[string]string `json:"-"` + RetentionPolicy RetentionPolicy `json:"retention"` + FilesPolicy FilesPolicy `json:"files"` + NoParent bool `json:"noParent,omitempty"` } func (p *Policy) String() string { @@ -109,18 +109,18 @@ func MergePolicies(policies []*Policy) *Policy { return &merged } - mergeExpirationPolicy(&merged.ExpirationPolicy, &p.ExpirationPolicy) + mergeRetentionPolicy(&merged.RetentionPolicy, &p.RetentionPolicy) mergeFilesPolicy(&merged.FilesPolicy, &p.FilesPolicy) } // Merge default expiration policy. - mergeExpirationPolicy(&merged.ExpirationPolicy, defaultExpirationPolicy) + mergeRetentionPolicy(&merged.RetentionPolicy, defaultRetentionPolicy) mergeFilesPolicy(&merged.FilesPolicy, defaultFilesPolicy) return &merged } -func mergeExpirationPolicy(dst, src *ExpirationPolicy) { +func mergeRetentionPolicy(dst, src *RetentionPolicy) { if dst.KeepLatest == nil { dst.KeepLatest = src.KeepLatest } diff --git a/policy/policy_manager.go b/policy/policy_manager.go index 53007b8be..39f742b63 100644 --- a/policy/policy_manager.go +++ b/policy/policy_manager.go @@ -5,17 +5,9 @@ "path/filepath" "github.com/kopia/kopia/manifest" - "github.com/kopia/kopia/repo" ) -// SourceInfo represents the information about snapshot source. -type SourceInfo struct { - Host string `json:"host"` - UserName string `json:"userName"` - Path string `json:"path"` -} - const policyPrefix = "P" // Manager manages snapshotting policies.