Skip to content

Commit

Permalink
Restore specific snapshot
Browse files Browse the repository at this point in the history
Signed-off-by: hmsayem <[email protected]>
  • Loading branch information
hmsayem committed Sep 20, 2023
1 parent 83e09a4 commit 8caf598
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 4 deletions.
24 changes: 20 additions & 4 deletions pkg/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -228,9 +229,9 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti

opt.totalHosts = 1
// For sharded MongoDB, parameter.ConfigServer will not be empty
var restoreSession *api_v1beta1.RestoreSession
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{})
restoreSession, err = opt.stashClient.StashV1beta1().RestoreSessions(opt.namespace).Get(context.TODO(), opt.restoreSessionName, metav1.GetOptions{})
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
}
60 changes: 60 additions & 0 deletions vendor/gomodules.xyz/x/strings/fmt.go
Original file line number Diff line number Diff line change
@@ -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
}
}
14 changes: 14 additions & 0 deletions vendor/gomodules.xyz/x/strings/optionals.go
Original file line number Diff line number Diff line change
@@ -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
}
11 changes: 11 additions & 0 deletions vendor/gomodules.xyz/x/strings/preconditions.go
Original file line number Diff line number Diff line change
@@ -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
}
112 changes: 112 additions & 0 deletions vendor/gomodules.xyz/x/strings/strings.go
Original file line number Diff line number Diff line change
@@ -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
}
1 change: 1 addition & 0 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8caf598

Please sign in to comment.