From 75efb45d0d1e3e05e67ef9c30ab58e03825c1f7b Mon Sep 17 00:00:00 2001 From: Hossain Mahmud Date: Wed, 4 Oct 2023 12:32:19 +0600 Subject: [PATCH] Add support for restoring specific snapshot (#1927) /cherry-pick Signed-off-by: hmsayem Signed-off-by: Tamal Saha --- pkg/restore.go | 27 +++++++++++++++++++++------ pkg/utils.go | 9 +++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/pkg/restore.go b/pkg/restore.go index 89a78abd4..1c865eee9 100644 --- a/pkg/restore.go +++ b/pkg/restore.go @@ -238,14 +238,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(), @@ -326,9 +326,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, @@ -578,3 +577,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 || 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 { + continue + } else { + return hostSnapshot + } + } + } + return hostSnapshot +} diff --git a/pkg/utils.go b/pkg/utils.go index 4aa03b203..fe71540c7 100644 --- a/pkg/utils.go +++ b/pkg/utils.go @@ -110,3 +110,12 @@ func genPassword(length int) (string, error) { } return string(b), nil } + +func containsString(a []string, e string) bool { + for _, s := range a { + if s == e { + return true + } + } + return false +}