Skip to content

Commit 525adda

Browse files
authored
[cherry-pick] Fix component status updating for shard backup and restore (#1806) (#1833)
Signed-off-by: hmsayem <hmsayem@appscode.com>
1 parent ec116a6 commit 525adda

File tree

239 files changed

+21146
-11781
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

239 files changed

+21146
-11781
lines changed

go.mod

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,33 @@ go 1.18
44

55
require (
66
github.com/pkg/errors v0.9.1
7-
github.com/spf13/cobra v1.6.0
7+
github.com/spf13/cobra v1.7.0
88
go.bytebuilders.dev/license-verifier/kubernetes v0.12.0
99
gomodules.xyz/flags v0.1.3
1010
gomodules.xyz/go-sh v0.1.0
1111
gomodules.xyz/logs v0.0.6
1212
gomodules.xyz/pointer v0.1.0
13-
gomodules.xyz/x v0.0.14
14-
k8s.io/api v0.25.1
13+
gomodules.xyz/x v0.0.15
14+
k8s.io/api v0.25.3
1515
k8s.io/apimachinery v0.25.3
16-
k8s.io/client-go v0.25.1
16+
k8s.io/client-go v0.25.3
1717
k8s.io/klog/v2 v2.80.1
18-
kmodules.xyz/client-go v0.25.19
19-
kmodules.xyz/custom-resources v0.25.0
20-
kmodules.xyz/offshoot-api v0.25.0
21-
kubedb.dev/apimachinery v0.28.4-0.20220918021210-a0b96812228b
22-
stash.appscode.dev/apimachinery v0.29.0
18+
kmodules.xyz/client-go v0.25.23
19+
kmodules.xyz/custom-resources v0.25.1
20+
kmodules.xyz/offshoot-api v0.25.3
21+
kubedb.dev/apimachinery v0.33.1
22+
stash.appscode.dev/apimachinery v0.29.1-0.20230529131221-1e979c48da10
2323
)
2424

2525
require (
2626
cloud.google.com/go v0.99.0 // indirect
2727
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
28-
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
29-
github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect
28+
github.com/Azure/go-autorest/autorest v0.11.28 // indirect
29+
github.com/Azure/go-autorest/autorest/adal v0.9.21 // indirect
3030
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
3131
github.com/Azure/go-autorest/logger v0.2.1 // indirect
3232
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
33-
github.com/Masterminds/semver/v3 v3.1.1 // indirect
33+
github.com/Masterminds/semver/v3 v3.2.1 // indirect
3434
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 // indirect
3535
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 // indirect
3636
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -49,7 +49,7 @@ require (
4949
github.com/google/go-cmp v0.5.9 // indirect
5050
github.com/google/gofuzz v1.2.0 // indirect
5151
github.com/imdario/mergo v0.3.13 // indirect
52-
github.com/inconshreveable/mousetrap v1.0.1 // indirect
52+
github.com/inconshreveable/mousetrap v1.1.0 // indirect
5353
github.com/josharian/intern v1.0.0 // indirect
5454
github.com/json-iterator/go v1.1.12 // indirect
5555
github.com/mailru/easyjson v0.7.7 // indirect
@@ -62,16 +62,16 @@ require (
6262
github.com/yudai/gojsondiff v1.0.0 // indirect
6363
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 // indirect
6464
go.bytebuilders.dev/license-proxyserver v0.0.3 // indirect
65-
go.bytebuilders.dev/license-verifier v0.12.1-0.20221113063237-6eb88040dd50 // indirect
66-
golang.org/x/crypto v0.6.0 // indirect
67-
golang.org/x/net v0.7.0 // indirect
65+
go.bytebuilders.dev/license-verifier v0.12.1 // indirect
66+
golang.org/x/crypto v0.9.0 // indirect
67+
golang.org/x/net v0.10.0 // indirect
6868
golang.org/x/oauth2 v0.5.0 // indirect
69-
golang.org/x/sys v0.5.0 // indirect
70-
golang.org/x/term v0.5.0 // indirect
71-
golang.org/x/text v0.7.0 // indirect
72-
golang.org/x/time v0.1.0 // indirect
69+
golang.org/x/sys v0.8.0 // indirect
70+
golang.org/x/term v0.8.0 // indirect
71+
golang.org/x/text v0.9.0 // indirect
72+
golang.org/x/time v0.3.0 // indirect
7373
gomodules.xyz/clock v0.0.0-20200817085942-06523dba733f // indirect
74-
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
74+
gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
7575
gomodules.xyz/mergo v0.3.13 // indirect
7676
gomodules.xyz/sets v0.2.1 // indirect
7777
gomodules.xyz/wait v0.2.0 // indirect
@@ -80,11 +80,11 @@ require (
8080
gopkg.in/inf.v0 v0.9.1 // indirect
8181
gopkg.in/yaml.v2 v2.4.0 // indirect
8282
gopkg.in/yaml.v3 v3.0.1 // indirect
83-
k8s.io/apiextensions-apiserver v0.25.1 // indirect
84-
k8s.io/apiserver v0.25.1 // indirect
83+
k8s.io/apiextensions-apiserver v0.25.3 // indirect
84+
k8s.io/apiserver v0.25.3 // indirect
8585
k8s.io/kube-aggregator v0.25.1 // indirect
86-
k8s.io/kube-openapi v0.0.0-20220803164354-a70c9af30aea // indirect
87-
k8s.io/utils v0.0.0-20220823124924-e9cbc92d1a73 // indirect
86+
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
87+
k8s.io/utils v0.0.0-20221012122500-cfd413dd9e85 // indirect
8888
kmodules.xyz/apiversion v0.2.0 // indirect
8989
kmodules.xyz/objectstore-api v0.25.1-0.20221104003322-f0289b5b6ca2 // indirect
9090
kmodules.xyz/prober v0.25.0 // indirect

go.sum

Lines changed: 54 additions & 58 deletions
Large diffs are not rendered by default.

pkg/backup.go

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,8 @@ func NewCmdBackup() *cobra.Command {
149149
if err != nil {
150150
backupOutput = &restic.BackupOutput{
151151
BackupTargetStatus: api_v1beta1.BackupTargetStatus{
152-
Ref: targetRef,
153-
Stats: []api_v1beta1.HostBackupStats{
154-
{
155-
Hostname: opt.defaultBackupOptions.Host,
156-
Phase: api_v1beta1.HostBackupFailed,
157-
Error: err.Error(),
158-
},
159-
},
152+
Ref: targetRef,
153+
Stats: opt.getHostBackupStats(err),
160154
},
161155
}
162156
}
@@ -301,8 +295,10 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
301295
// So, for stand-alone MongoDB and MongoDB ReplicaSet, we don't have to do anything.
302296
// We only need to update totalHosts field for sharded MongoDB
303297

298+
opt.totalHosts = 1
304299
// For sharded MongoDB, parameter.ConfigServer will not be empty
305300
if parameters.ConfigServer != "" {
301+
opt.totalHosts = len(parameters.ReplicaSets) + 1 // for each shard there will be one key in parameters.ReplicaSet
306302
backupSession, err := opt.stashClient.StashV1beta1().BackupSessions(opt.namespace).Get(context.TODO(), opt.backupSessionName, metav1.GetOptions{})
307303
if err != nil {
308304
return nil, err
@@ -314,7 +310,7 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
314310
opt.stashClient.StashV1beta1(),
315311
backupSession.ObjectMeta,
316312
func(status *api_v1beta1.BackupSessionStatus) (types.UID, *api_v1beta1.BackupSessionStatus) {
317-
status.Targets[i].TotalHosts = pointer.Int32P(int32(len(parameters.ReplicaSets) + 1)) // for each shard there will be one key in parameters.ReplicaSet
313+
status.Targets[i].TotalHosts = pointer.Int32P(int32(opt.totalHosts))
318314
return backupSession.UID, status
319315
},
320316
metav1.UpdateOptions{},
@@ -571,7 +567,12 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
571567
// hide password, don't print cmd
572568
resticWrapper.HideCMD()
573569

574-
return resticWrapper.RunParallelBackup(opt.backupOptions, targetRef, opt.maxConcurrency)
570+
out, err := resticWrapper.RunParallelBackup(opt.backupOptions, targetRef, opt.maxConcurrency)
571+
if err != nil {
572+
klog.Warningln("backup failed!", err.Error())
573+
}
574+
// error not returned, error is encoded into output
575+
return out, nil
575576
}
576577

577578
// cleanup usually unlocks the locked servers
@@ -583,6 +584,32 @@ func cleanup() {
583584
}
584585
}
585586

587+
func (opt *mongoOptions) getHostBackupStats(err error) []api_v1beta1.HostBackupStats {
588+
var backupStats []api_v1beta1.HostBackupStats
589+
590+
errMsg := fmt.Sprintf("failed to start backup: %s", err.Error())
591+
for _, backupOpt := range opt.backupOptions {
592+
backupStats = append(backupStats, api_v1beta1.HostBackupStats{
593+
Hostname: backupOpt.Host,
594+
Phase: api_v1beta1.HostBackupFailed,
595+
Error: errMsg,
596+
})
597+
}
598+
599+
if opt.totalHosts > len(backupStats) {
600+
rem := opt.totalHosts - len(backupStats)
601+
for i := 0; i < rem; i++ {
602+
backupStats = append(backupStats, api_v1beta1.HostBackupStats{
603+
Hostname: fmt.Sprintf("unknown-%s", strconv.Itoa(i)),
604+
Phase: api_v1beta1.HostBackupFailed,
605+
Error: errMsg,
606+
})
607+
}
608+
}
609+
610+
return backupStats
611+
}
612+
586613
func getSSLUser(path string) (string, error) {
587614
data, err := sh.Command(OpenSSLCMD, "x509", "-in", path, "-inform", "PEM", "-subject", "-nameopt", "RFC2253", "-noout").Output()
588615
if err != nil {

pkg/restore.go

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"os"
2424
"path/filepath"
25+
"strconv"
2526
"strings"
2627

2728
api_v1beta1 "stash.appscode.dev/apimachinery/apis/stash/v1beta1"
@@ -33,7 +34,6 @@ import (
3334
"github.com/spf13/cobra"
3435
license "go.bytebuilders.dev/license-verifier/kubernetes"
3536
"gomodules.xyz/flags"
36-
"gomodules.xyz/go-sh"
3737
"gomodules.xyz/pointer"
3838
core "k8s.io/api/core/v1"
3939
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -106,14 +106,8 @@ func NewCmdRestore() *cobra.Command {
106106
if err != nil {
107107
restoreOutput = &restic.RestoreOutput{
108108
RestoreTargetStatus: api_v1beta1.RestoreMemberStatus{
109-
Ref: targetRef,
110-
Stats: []api_v1beta1.HostRestoreStats{
111-
{
112-
Hostname: opt.defaultDumpOptions.Host,
113-
Phase: api_v1beta1.HostRestoreFailed,
114-
Error: err.Error(),
115-
},
116-
},
109+
Ref: targetRef,
110+
Stats: opt.getHostRestoreStats(err),
117111
},
118112
}
119113
}
@@ -232,8 +226,10 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
232226
// So, for stand-alone MongoDB and MongoDB ReplicaSet, we don't have to do anything.
233227
// We only need to update totalHosts field for sharded MongoDB
234228

229+
opt.totalHosts = 1
235230
// For sharded MongoDB, parameter.ConfigServer will not be empty
236231
if parameters.ConfigServer != "" {
232+
opt.totalHosts = len(parameters.ReplicaSets) + 1 // for each shard there will be one key in parameters.ReplicaSet
237233
restoreSession, err := opt.stashClient.StashV1beta1().RestoreSessions(opt.namespace).Get(context.TODO(), opt.restoreSessionName, metav1.GetOptions{})
238234
if err != nil {
239235
return nil, err
@@ -243,7 +239,7 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
243239
opt.stashClient.StashV1beta1(),
244240
restoreSession.ObjectMeta,
245241
func(status *api_v1beta1.RestoreSessionStatus) (types.UID, *api_v1beta1.RestoreSessionStatus) {
246-
status.TotalHosts = pointer.Int32P(int32(len(parameters.ReplicaSets) + 1)) // for each shard there will be one key in parameters.ReplicaSet
242+
status.TotalHosts = pointer.Int32P(int32(opt.totalHosts))
247243
return restoreSession.UID, status
248244
},
249245
metav1.UpdateOptions{},
@@ -397,29 +393,36 @@ func (opt *mongoOptions) restoreMongoDB(targetRef api_v1beta1.TargetRef) (*resti
397393
resticWrapper.HideCMD()
398394

399395
// Run dump
400-
restoreOutput, err := resticWrapper.ParallelDump(opt.dumpOptions, targetRef, opt.maxConcurrency)
396+
out, err := resticWrapper.ParallelDump(opt.dumpOptions, targetRef, opt.maxConcurrency)
401397
if err != nil {
402-
return nil, err
398+
klog.Warningln("restore failed!", err.Error())
403399
}
400+
// error not returned, error is encoded into output
401+
return out, nil
402+
}
404403

405-
if parameters.ConfigServer != "" {
406-
err = dropTempReshardCollection(parameters.ConfigServer)
407-
if err != nil {
408-
klog.Errorf("error while deleting temporary reshard collection for %v. error: %v", parameters.ConfigServer, err)
409-
return nil, err
410-
}
411-
}
404+
func (opt *mongoOptions) getHostRestoreStats(err error) []api_v1beta1.HostRestoreStats {
405+
var restoreStats []api_v1beta1.HostRestoreStats
412406

413-
return restoreOutput, nil
414-
}
407+
errMsg := fmt.Sprintf("failed to start data restoration: %s", err.Error())
408+
for _, dumpOpt := range opt.dumpOptions {
409+
restoreStats = append(restoreStats, api_v1beta1.HostRestoreStats{
410+
Hostname: dumpOpt.Host,
411+
Phase: api_v1beta1.HostRestoreFailed,
412+
Error: errMsg,
413+
})
414+
}
415415

416-
func dropTempReshardCollection(configsvrDSN string) error {
417-
args := append([]interface{}{
418-
"config",
419-
"--host", configsvrDSN,
420-
"--quiet",
421-
"--eval", `db.reshardingOperations_temp.drop()`,
422-
}, mongoCreds...)
416+
if opt.totalHosts > len(restoreStats) {
417+
rem := opt.totalHosts - len(restoreStats)
418+
for i := 0; i < rem; i++ {
419+
restoreStats = append(restoreStats, api_v1beta1.HostRestoreStats{
420+
Hostname: fmt.Sprintf("unknown-%s", strconv.Itoa(i)),
421+
Phase: api_v1beta1.HostRestoreFailed,
422+
Error: errMsg,
423+
})
424+
}
425+
}
423426

424-
return sh.Command(MongoCMD, args...).Command("/usr/bin/tail", "-1").Run()
427+
return restoreStats
425428
}

pkg/utils.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type mongoOptions struct {
6868
dumpOptions []restic.DumpOptions
6969
defaultDumpOptions restic.DumpOptions
7070
config *restclient.Config
71+
totalHosts int
7172
}
7273

7374
func waitForDBReady(host string, port, waitTimeout int32) {

vendor/github.com/Masterminds/semver/v3/.golangci.yml

Lines changed: 12 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/Masterminds/semver/v3/CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/Masterminds/semver/v3/Makefile

Lines changed: 5 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)