From b4056d6e6679648a54d8abd3c3c435636012b411 Mon Sep 17 00:00:00 2001 From: hmsayem Date: Thu, 21 Sep 2023 17:22:24 +0600 Subject: [PATCH 1/2] Restore specific snapshot Signed-off-by: hmsayem --- pkg/restore.go | 28 ++++- vendor/gomodules.xyz/x/strings/fmt.go | 60 ++++++++++ vendor/gomodules.xyz/x/strings/optionals.go | 14 +++ .../gomodules.xyz/x/strings/preconditions.go | 11 ++ vendor/gomodules.xyz/x/strings/strings.go | 112 ++++++++++++++++++ vendor/modules.txt | 1 + 6 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 vendor/gomodules.xyz/x/strings/fmt.go create mode 100644 vendor/gomodules.xyz/x/strings/optionals.go create mode 100644 vendor/gomodules.xyz/x/strings/preconditions.go create mode 100644 vendor/gomodules.xyz/x/strings/strings.go diff --git a/pkg/restore.go b/pkg/restore.go index d9f0c7f3f..91ec8d5ae 100644 --- a/pkg/restore.go +++ b/pkg/restore.go @@ -35,6 +35,7 @@ import ( license "go.bytebuilders.dev/license-verifier/kubernetes" "gomodules.xyz/flags" "gomodules.xyz/pointer" + go_str "gomodules.xyz/x/strings" core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -226,14 +227,14 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti // So, for stand-alone MongoDB and MongoDB ReplicaSet, we don't have to do anything. // We only need to update totalHosts field for sharded MongoDB + restoreSession, err := opt.stashClient.StashV1beta1().RestoreSessions(opt.namespace).Get(context.TODO(), opt.restoreSessionName, metav1.GetOptions{}) + if err != nil { + return nil, err + } opt.totalHosts = 1 // For sharded MongoDB, parameter.ConfigServer will not be empty if parameters.ConfigServer != "" { opt.totalHosts = len(parameters.ReplicaSets) + 1 // for each shard there will be one key in parameters.ReplicaSet - restoreSession, err := opt.stashClient.StashV1beta1().RestoreSessions(opt.namespace).Get(context.TODO(), opt.restoreSessionName, metav1.GetOptions{}) - if err != nil { - return nil, err - } _, err = stash_cs_util.UpdateRestoreSessionStatus( context.TODO(), opt.stashClient.StashV1beta1(), @@ -311,9 +312,8 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti Host: hostKey, SourceHost: hostKey, FileName: opt.defaultDumpOptions.FileName, - Snapshot: opt.defaultDumpOptions.Snapshot, + Snapshot: opt.getSnapshotForHost(hostKey, restoreSession.Spec.Target.Rules), } - // setup pipe command restoreCmd := restic.Command{ Name: MongoRestoreCMD, @@ -426,3 +426,19 @@ func (opt *mongoOptions) getHostRestoreStats(err error) []api_v1beta1.HostRestor return restoreStats } + +func (opt *mongoOptions) getSnapshotForHost(hostname string, rules []api_v1beta1.Rule) string { + var hostSnapshot string + for _, rule := range rules { + if len(rule.TargetHosts) == 0 || go_str.Contains(rule.TargetHosts, hostname) { + hostSnapshot = rule.Snapshots[0] + // if rule has empty targetHost then check further rules to see if any other rule with non-empty targetHost matches + if len(rule.TargetHosts) == 0 { + continue + } else { + return hostSnapshot + } + } + } + return hostSnapshot +} diff --git a/vendor/gomodules.xyz/x/strings/fmt.go b/vendor/gomodules.xyz/x/strings/fmt.go new file mode 100644 index 000000000..20474bcb9 --- /dev/null +++ b/vendor/gomodules.xyz/x/strings/fmt.go @@ -0,0 +1,60 @@ +package strings + +import ( + "strings" +) + +func Fmt(s string) string { + stripper := &Stripe{ + Result: "", + } + stripper.Write(s) + return stripper.Result +} + +// Striplines wraps an output stream, stripping runs of consecutive empty lines. +// You must call Flush before the output stream will be complete. +// Implements io.WriteCloser, Writer, Closer. +type Stripe struct { + Result string + lastLine []byte + currentLine []byte +} + +func (w *Stripe) Write(p string) (int, error) { + totalN := 0 + s := string(p) + if !strings.Contains(s, "\n") { + w.currentLine = append(w.currentLine, p...) + return 0, nil + } + cur := string(append(w.currentLine, p...)) + lastN := strings.LastIndex(cur, "\n") + s = cur[:lastN] + for _, line := range strings.Split(s, "\n") { + n, err := w.writeLn(line + "\n") + w.lastLine = []byte(line) + if err != nil { + return totalN, err + } + totalN += n + } + rem := cur[(lastN + 1):] + w.currentLine = []byte(rem) + return totalN, nil +} + +// Close flushes the last of the output into the underlying writer. +func (w *Stripe) Close() error { + _, err := w.writeLn(string(w.currentLine)) + return err +} + +func (w *Stripe) writeLn(line string) (n int, err error) { + if strings.TrimSpace(string(w.lastLine)) == "" && strings.TrimSpace(line) == "" { + return 0, nil + } else { + w.Result = w.Result + line + return len(line), nil + } +} diff --git a/vendor/gomodules.xyz/x/strings/optionals.go b/vendor/gomodules.xyz/x/strings/optionals.go new file mode 100644 index 000000000..68e9dad08 --- /dev/null +++ b/vendor/gomodules.xyz/x/strings/optionals.go @@ -0,0 +1,14 @@ +package strings + +import "log" + +func VString(def string, args ...string) string { + v := def + if len(args) == 1 { + v = args[0] + } else if len(args) > 1 { + v = args[0] + log.Printf("Found more than 1 argument when expected 1 %v", args) + } + return v +} diff --git a/vendor/gomodules.xyz/x/strings/preconditions.go b/vendor/gomodules.xyz/x/strings/preconditions.go new file mode 100644 index 000000000..36b290fb6 --- /dev/null +++ b/vendor/gomodules.xyz/x/strings/preconditions.go @@ -0,0 +1,11 @@ +package strings + +import "strings" + +func Val(v string, def string) string { + trimmed := strings.TrimSpace(v) + if trimmed == "" { + return def + } + return trimmed +} diff --git a/vendor/gomodules.xyz/x/strings/strings.go b/vendor/gomodules.xyz/x/strings/strings.go new file mode 100644 index 000000000..71a0f79b4 --- /dev/null +++ b/vendor/gomodules.xyz/x/strings/strings.go @@ -0,0 +1,112 @@ +package strings + +import ( + "sort" + "strings" + "unicode/utf8" +) + +// Benchmark 19246 ns/op. +func Reverse(s string) string { + size := len(s) + buf := make([]byte, size) + for start := 0; start < size; { + r, n := utf8.DecodeRuneInString(s[start:]) + start += n + utf8.EncodeRune(buf[size-start:], r) + } + return string(buf) +} + +func PrefixFold(s, prefix string) bool { + return len(s) >= len(prefix) && strings.EqualFold(prefix, s[:len(prefix)]) +} + +func IsEmpty(s *string) bool { + return s == nil || *s == "" +} + +func IsBothAlphaNum(a string) bool { + alpha := false + num := false + for _, c := range a { + if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') { + alpha = true + } else if c >= '0' && c <= '9' { + num = true + } + if alpha && num { + return true + } + } + return false +} + +func Contains(a []string, e string) bool { + for _, s := range a { + if s == e { + return true + } + } + return false +} + +// Allowed char: [a-z0-9]([a-z0-9-]*[a-z0-9])? +// Makes it safe as a subdomain +func DomainForm(s string) string { + runes := make([]rune, len(s)) + for i, r := range strings.ToLower(s) { + if (r >= '0' && r <= '9') || (r >= 'a' && r <= 'z') || (r == '-') || (r == '.') { + runes[i] = r + } else if r == '_' { + runes[i] = '-' // _ --> - + } + } + return strings.Trim(string(runes), "-") +} + +func Filter(s []string, f func(string) bool) []string { + ret := make([]string, 0) + for _, elm := range s { + if !f(elm) { + ret = append(ret, elm) + } + } + return ret +} + +func Join(a []*string, sep string) string { + b := make([]string, len(a)) + for i, s := range a { + b[i] = *s + } + return strings.Join(b, sep) +} + +func EqualSlice(a, b []string) bool { + if a == nil && b == nil { + return true + } + + if a == nil || b == nil { + return false + } + + if len(a) != len(b) { + return false + } + + // Copy slices + aCopy := append([]string(nil), a...) + bCopy := append([]string(nil), b...) + + sort.Strings(aCopy) + sort.Strings(bCopy) + + for i := range aCopy { + if aCopy[i] != bCopy[i] { + return false + } + } + return true +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 30c0b45bd..b3d773501 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -257,6 +257,7 @@ gomodules.xyz/wait # gomodules.xyz/x v0.0.15 ## explicit; go 1.18 gomodules.xyz/x/arrays +gomodules.xyz/x/strings gomodules.xyz/x/version # google.golang.org/appengine v1.6.7 ## explicit; go 1.11 From d48db67947b188db79ad087f3b105c49a9d20491 Mon Sep 17 00:00:00 2001 From: Arnob kumar saha Date: Mon, 2 Oct 2023 11:29:34 +0600 Subject: [PATCH 2/2] contains func added Signed-off-by: Arnob kumar saha --- pkg/restore.go | 3 +- pkg/utils.go | 9 ++ vendor/gomodules.xyz/x/strings/fmt.go | 60 ---------- vendor/gomodules.xyz/x/strings/optionals.go | 14 --- .../gomodules.xyz/x/strings/preconditions.go | 11 -- vendor/gomodules.xyz/x/strings/strings.go | 112 ------------------ vendor/modules.txt | 1 - 7 files changed, 10 insertions(+), 200 deletions(-) delete mode 100644 vendor/gomodules.xyz/x/strings/fmt.go delete mode 100644 vendor/gomodules.xyz/x/strings/optionals.go delete mode 100644 vendor/gomodules.xyz/x/strings/preconditions.go delete mode 100644 vendor/gomodules.xyz/x/strings/strings.go diff --git a/pkg/restore.go b/pkg/restore.go index 91ec8d5ae..db27d0a8d 100644 --- a/pkg/restore.go +++ b/pkg/restore.go @@ -35,7 +35,6 @@ import ( license "go.bytebuilders.dev/license-verifier/kubernetes" "gomodules.xyz/flags" "gomodules.xyz/pointer" - go_str "gomodules.xyz/x/strings" core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -430,7 +429,7 @@ func (opt *mongoOptions) getHostRestoreStats(err error) []api_v1beta1.HostRestor func (opt *mongoOptions) getSnapshotForHost(hostname string, rules []api_v1beta1.Rule) string { var hostSnapshot string for _, rule := range rules { - if len(rule.TargetHosts) == 0 || go_str.Contains(rule.TargetHosts, hostname) { + if len(rule.TargetHosts) == 0 || containsString(rule.TargetHosts, hostname) { hostSnapshot = rule.Snapshots[0] // if rule has empty targetHost then check further rules to see if any other rule with non-empty targetHost matches if len(rule.TargetHosts) == 0 { diff --git a/pkg/utils.go b/pkg/utils.go index c28de5cf1..347b81234 100644 --- a/pkg/utils.go +++ b/pkg/utils.go @@ -94,3 +94,12 @@ func containsArg(args []string, checklist sets.String) bool { } return false } + +func containsString(a []string, e string) bool { + for _, s := range a { + if s == e { + return true + } + } + return false +} diff --git a/vendor/gomodules.xyz/x/strings/fmt.go b/vendor/gomodules.xyz/x/strings/fmt.go deleted file mode 100644 index 20474bcb9..000000000 --- a/vendor/gomodules.xyz/x/strings/fmt.go +++ /dev/null @@ -1,60 +0,0 @@ -package strings - -import ( - "strings" -) - -func Fmt(s string) string { - stripper := &Stripe{ - Result: "", - } - stripper.Write(s) - return stripper.Result -} - -// Striplines wraps an output stream, stripping runs of consecutive empty lines. -// You must call Flush before the output stream will be complete. -// Implements io.WriteCloser, Writer, Closer. -type Stripe struct { - Result string - lastLine []byte - currentLine []byte -} - -func (w *Stripe) Write(p string) (int, error) { - totalN := 0 - s := string(p) - if !strings.Contains(s, "\n") { - w.currentLine = append(w.currentLine, p...) - return 0, nil - } - cur := string(append(w.currentLine, p...)) - lastN := strings.LastIndex(cur, "\n") - s = cur[:lastN] - for _, line := range strings.Split(s, "\n") { - n, err := w.writeLn(line + "\n") - w.lastLine = []byte(line) - if err != nil { - return totalN, err - } - totalN += n - } - rem := cur[(lastN + 1):] - w.currentLine = []byte(rem) - return totalN, nil -} - -// Close flushes the last of the output into the underlying writer. -func (w *Stripe) Close() error { - _, err := w.writeLn(string(w.currentLine)) - return err -} - -func (w *Stripe) writeLn(line string) (n int, err error) { - if strings.TrimSpace(string(w.lastLine)) == "" && strings.TrimSpace(line) == "" { - return 0, nil - } else { - w.Result = w.Result + line - return len(line), nil - } -} diff --git a/vendor/gomodules.xyz/x/strings/optionals.go b/vendor/gomodules.xyz/x/strings/optionals.go deleted file mode 100644 index 68e9dad08..000000000 --- a/vendor/gomodules.xyz/x/strings/optionals.go +++ /dev/null @@ -1,14 +0,0 @@ -package strings - -import "log" - -func VString(def string, args ...string) string { - v := def - if len(args) == 1 { - v = args[0] - } else if len(args) > 1 { - v = args[0] - log.Printf("Found more than 1 argument when expected 1 %v", args) - } - return v -} diff --git a/vendor/gomodules.xyz/x/strings/preconditions.go b/vendor/gomodules.xyz/x/strings/preconditions.go deleted file mode 100644 index 36b290fb6..000000000 --- a/vendor/gomodules.xyz/x/strings/preconditions.go +++ /dev/null @@ -1,11 +0,0 @@ -package strings - -import "strings" - -func Val(v string, def string) string { - trimmed := strings.TrimSpace(v) - if trimmed == "" { - return def - } - return trimmed -} diff --git a/vendor/gomodules.xyz/x/strings/strings.go b/vendor/gomodules.xyz/x/strings/strings.go deleted file mode 100644 index 71a0f79b4..000000000 --- a/vendor/gomodules.xyz/x/strings/strings.go +++ /dev/null @@ -1,112 +0,0 @@ -package strings - -import ( - "sort" - "strings" - "unicode/utf8" -) - -// Benchmark 19246 ns/op. -func Reverse(s string) string { - size := len(s) - buf := make([]byte, size) - for start := 0; start < size; { - r, n := utf8.DecodeRuneInString(s[start:]) - start += n - utf8.EncodeRune(buf[size-start:], r) - } - return string(buf) -} - -func PrefixFold(s, prefix string) bool { - return len(s) >= len(prefix) && strings.EqualFold(prefix, s[:len(prefix)]) -} - -func IsEmpty(s *string) bool { - return s == nil || *s == "" -} - -func IsBothAlphaNum(a string) bool { - alpha := false - num := false - for _, c := range a { - if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') { - alpha = true - } else if c >= '0' && c <= '9' { - num = true - } - if alpha && num { - return true - } - } - return false -} - -func Contains(a []string, e string) bool { - for _, s := range a { - if s == e { - return true - } - } - return false -} - -// Allowed char: [a-z0-9]([a-z0-9-]*[a-z0-9])? -// Makes it safe as a subdomain -func DomainForm(s string) string { - runes := make([]rune, len(s)) - for i, r := range strings.ToLower(s) { - if (r >= '0' && r <= '9') || (r >= 'a' && r <= 'z') || (r == '-') || (r == '.') { - runes[i] = r - } else if r == '_' { - runes[i] = '-' // _ --> - - } - } - return strings.Trim(string(runes), "-") -} - -func Filter(s []string, f func(string) bool) []string { - ret := make([]string, 0) - for _, elm := range s { - if !f(elm) { - ret = append(ret, elm) - } - } - return ret -} - -func Join(a []*string, sep string) string { - b := make([]string, len(a)) - for i, s := range a { - b[i] = *s - } - return strings.Join(b, sep) -} - -func EqualSlice(a, b []string) bool { - if a == nil && b == nil { - return true - } - - if a == nil || b == nil { - return false - } - - if len(a) != len(b) { - return false - } - - // Copy slices - aCopy := append([]string(nil), a...) - bCopy := append([]string(nil), b...) - - sort.Strings(aCopy) - sort.Strings(bCopy) - - for i := range aCopy { - if aCopy[i] != bCopy[i] { - return false - } - } - return true -} diff --git a/vendor/modules.txt b/vendor/modules.txt index b3d773501..30c0b45bd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -257,7 +257,6 @@ gomodules.xyz/wait # gomodules.xyz/x v0.0.15 ## explicit; go 1.18 gomodules.xyz/x/arrays -gomodules.xyz/x/strings gomodules.xyz/x/version # google.golang.org/appengine v1.6.7 ## explicit; go 1.11