@@ -104,10 +104,10 @@ func NewCmdBackup() *cobra.Command {
104
104
RunE : func (cmd * cobra.Command , args []string ) error {
105
105
defer cleanup ()
106
106
107
- flags .EnsureRequiredFlags (cmd , "appbinding" , "provider" , "secret-dir " )
107
+ flags .EnsureRequiredFlags (cmd , "appbinding" , "provider" , "storage- secret-name" , "storage-secret-namespace " )
108
108
109
109
// catch sigkill signals and gracefully terminate so that cleanup functions are executed.
110
- sigChan := make (chan os.Signal )
110
+ sigChan := make (chan os.Signal , 1 )
111
111
signal .Notify (sigChan , os .Interrupt , syscall .SIGTERM )
112
112
go func () {
113
113
rcvSig := <- sigChan
@@ -183,11 +183,13 @@ func NewCmdBackup() *cobra.Command {
183
183
cmd .Flags ().StringVar (& opt .setupOptions .Endpoint , "endpoint" , opt .setupOptions .Endpoint , "Endpoint for s3/s3 compatible backend or REST server URL" )
184
184
cmd .Flags ().StringVar (& opt .setupOptions .Region , "region" , opt .setupOptions .Region , "Region for s3/s3 compatible backend" )
185
185
cmd .Flags ().StringVar (& opt .setupOptions .Path , "path" , opt .setupOptions .Path , "Directory inside the bucket where backup will be stored" )
186
- cmd .Flags ().StringVar (& opt .setupOptions .SecretDir , "secret-dir" , opt .setupOptions .SecretDir , "Directory where storage secret has been mounted" )
187
186
cmd .Flags ().StringVar (& opt .setupOptions .ScratchDir , "scratch-dir" , opt .setupOptions .ScratchDir , "Temporary directory" )
188
187
cmd .Flags ().BoolVar (& opt .setupOptions .EnableCache , "enable-cache" , opt .setupOptions .EnableCache , "Specify whether to enable caching for restic" )
189
188
cmd .Flags ().Int64Var (& opt .setupOptions .MaxConnections , "max-connections" , opt .setupOptions .MaxConnections , "Specify maximum concurrent connections for GCS, Azure and B2 backend" )
190
189
190
+ cmd .Flags ().StringVar (& opt .storageSecret .Name , "storage-secret-name" , opt .storageSecret .Name , "Name of the storage secret" )
191
+ cmd .Flags ().StringVar (& opt .storageSecret .Namespace , "storage-secret-namespace" , opt .storageSecret .Namespace , "Namespace of the storage secret" )
192
+ cmd .Flags ().StringVar (& opt .authenticationDatabase , "authentication-database" , "admin" , "Specify the authentication database" )
191
193
cmd .Flags ().StringVar (& opt .defaultBackupOptions .Host , "hostname" , opt .defaultBackupOptions .Host , "Name of the host machine" )
192
194
193
195
cmd .Flags ().Int64Var (& opt .defaultBackupOptions .RetentionPolicy .KeepLast , "retention-keep-last" , opt .defaultBackupOptions .RetentionPolicy .KeepLast , "Specify value for retention strategy" )
@@ -206,6 +208,12 @@ func NewCmdBackup() *cobra.Command {
206
208
}
207
209
208
210
func (opt * mongoOptions ) backupMongoDB (targetRef api_v1beta1.TargetRef ) (* restic.BackupOutput , error ) {
211
+ var err error
212
+ opt .setupOptions .StorageSecret , err = opt .kubeClient .CoreV1 ().Secrets (opt .storageSecret .Namespace ).Get (context .TODO (), opt .storageSecret .Name , metav1.GetOptions {})
213
+ if err != nil {
214
+ return nil , err
215
+ }
216
+
209
217
// if any pre-backup actions has been assigned to it, execute them
210
218
actionOptions := api_util.ActionOptions {
211
219
StashClient : opt .stashClient ,
@@ -214,7 +222,7 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
214
222
BackupSessionName : opt .backupSessionName ,
215
223
Namespace : opt .namespace ,
216
224
}
217
- err : = api_util .ExecutePreBackupActions (actionOptions )
225
+ err = api_util .ExecutePreBackupActions (actionOptions )
218
226
if err != nil {
219
227
return nil , err
220
228
}
@@ -233,25 +241,32 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
233
241
return nil , err
234
242
}
235
243
236
- // get app binding
237
244
appBinding , err := opt .catalogClient .AppcatalogV1alpha1 ().AppBindings (opt .namespace ).Get (context .TODO (), opt .appBindingName , metav1.GetOptions {})
238
245
if err != nil {
239
246
return nil , err
240
247
}
241
- // get secret
248
+
242
249
appBindingSecret , err := opt .kubeClient .CoreV1 ().Secrets (opt .namespace ).Get (context .TODO (), appBinding .Spec .Secret .Name , metav1.GetOptions {})
243
250
if err != nil {
244
251
return nil , err
245
252
}
246
253
247
- // transform secret
248
254
err = appBinding .TransformSecret (opt .kubeClient , appBindingSecret .Data )
249
255
if err != nil {
250
256
return nil , err
251
257
}
252
258
253
- // wait for DB ready
254
- waitForDBReady (appBinding .Spec .ClientConfig .Service .Name , appBinding .Spec .ClientConfig .Service .Port , opt .waitTimeout )
259
+ hostname , err := appBinding .Hostname ()
260
+ if err != nil {
261
+ return nil , err
262
+ }
263
+
264
+ port , err := appBinding .Port ()
265
+ if err != nil {
266
+ return nil , err
267
+ }
268
+
269
+ waitForDBReady (hostname , port , opt .waitTimeout )
255
270
256
271
// unmarshal parameter is the field has value
257
272
parameters := v1alpha1.MongoDBConfiguration {}
@@ -347,7 +362,7 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
347
362
userAuth := []interface {}{
348
363
"--username" , string (appBindingSecret .Data [MongoUserKey ]),
349
364
"--password" , string (appBindingSecret .Data [MongoPasswordKey ]),
350
- "--authenticationDatabase" , "admin" ,
365
+ "--authenticationDatabase" , opt . authenticationDatabase ,
351
366
}
352
367
mongoCreds = append (mongoCreds , userAuth ... )
353
368
dumpCreds = append (dumpCreds , userAuth ... )
@@ -373,7 +388,7 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
373
388
userArgs := strings .Fields (opt .mongoArgs )
374
389
375
390
if isStandalone {
376
- backupCmd .Args = append (backupCmd .Args , "--port=" + fmt . Sprint ( appBinding . Spec . ClientConfig . Service . Port ))
391
+ backupCmd .Args = append (backupCmd .Args , fmt . Sprintf ( "--port=%d" , port ))
377
392
} else {
378
393
// - port is already added in mongoDSN with replicasetName/host:port format.
379
394
// - oplog is enabled automatically for replicasets.
@@ -449,17 +464,16 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
449
464
}
450
465
451
466
// sharded cluster. so disable the balancer first. then perform the 'usual' tasks.
452
-
453
467
primary , secondary , err := getPrimaryNSecondaryMember (parameters .ConfigServer )
454
468
if err != nil {
455
469
return nil , err
456
470
}
457
471
458
472
// connect to mongos to disable/enable balancer
459
- err = disabelBalancer (appBinding . Spec . ClientConfig . Service . Name )
473
+ err = disabelBalancer (hostname )
460
474
cleanupFuncs = append (cleanupFuncs , func () error {
461
475
// even if error occurs, try to enable the balancer on exiting the program.
462
- return enableBalancer (appBinding . Spec . ClientConfig . Service . Name )
476
+ return enableBalancer (hostname )
463
477
})
464
478
if err != nil {
465
479
return nil , err
@@ -473,14 +487,15 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
473
487
}
474
488
475
489
err = lockConfigServer (parameters .ConfigServer , secondary )
490
+
476
491
cleanupFuncs = append (cleanupFuncs , func () error {
477
492
// even if error occurs, try to unlock the server
478
493
return unlockSecondaryMember (secondary )
479
494
})
480
495
if err != nil {
496
+ klog .Errorf ("error while locking config server. error: %v" , err )
481
497
return nil , err
482
498
}
483
-
484
499
opt .backupOptions = append (opt .backupOptions , getBackupOpt (backupHost , MongoConfigSVRHostKey , false ))
485
500
}
486
501
@@ -522,7 +537,7 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
522
537
// if parameters.ReplicaSets is nil, then the mongodb database doesn't have replicasets or sharded replicasets.
523
538
// In this case, perform normal backup with clientconfig.Service.Name mongo dsn
524
539
if parameters .ReplicaSets == nil {
525
- opt .backupOptions = append (opt .backupOptions , getBackupOpt (appBinding . Spec . ClientConfig . Service . Name , restic .DefaultHost , true ))
540
+ opt .backupOptions = append (opt .backupOptions , getBackupOpt (hostname , restic .DefaultHost , true ))
526
541
}
527
542
528
543
klog .Infoln ("processing backup." )
@@ -534,7 +549,6 @@ func (opt *mongoOptions) backupMongoDB(targetRef api_v1beta1.TargetRef) (*restic
534
549
// hide password, don't print cmd
535
550
resticWrapper .HideCMD ()
536
551
537
- // Run backup
538
552
return resticWrapper .RunParallelBackup (opt .backupOptions , targetRef , opt .maxConcurrency )
539
553
}
540
554
@@ -656,12 +670,12 @@ func enableBalancer(mongosHost string) error {
656
670
657
671
func lockConfigServer (configSVRDSN , secondaryHost string ) error {
658
672
klog .Infoln ("Attempting to lock configserver" , configSVRDSN )
673
+
659
674
if secondaryHost == "" {
660
675
klog .Warningln ("locking configserver is skipped. secondary host is empty" )
661
676
return nil
662
677
}
663
678
v := make (map [string ]interface {})
664
-
665
679
// findAndModify BackupControlDocument. skip single quote inside single quote: https://stackoverflow.com/a/28786747/4628962
666
680
args := append ([]interface {}{
667
681
"config" ,
@@ -672,12 +686,10 @@ func lockConfigServer(configSVRDSN, secondaryHost string) error {
672
686
if err := sh .Command (MongoCMD , args ... ).Command ("/usr/bin/tail" , "-1" ).UnmarshalJSON (& v ); err != nil {
673
687
return err
674
688
}
675
-
676
689
val , ok := v ["counter" ].(float64 )
677
690
if ! ok || int (val ) == 0 {
678
691
return fmt .Errorf ("unable to modify BackupControlDocument. got response: %v" , v )
679
692
}
680
-
681
693
val2 := float64 (0 )
682
694
timer := 0 // wait approximately 5 minutes.
683
695
for timer < 60 && (int (val2 ) == 0 || int (val ) != int (val2 )) {
@@ -687,17 +699,17 @@ func lockConfigServer(configSVRDSN, secondaryHost string) error {
687
699
"config" ,
688
700
"--host" , secondaryHost ,
689
701
"--quiet" ,
690
- "--eval" , "rs.slaveOk(); db.BackupControl.find({ '_id' : 'BackupControlDocument' }).readConcern('majority');" ,
691
- }, mongoCreds ... )
692
- if err := sh .Command (MongoCMD , args ... ).Command ("/usr/bin/tail" , "-1" ).UnmarshalJSON (& v ); err != nil {
702
+ "--eval" , "rs.secondaryOk(); db.BackupControl.find({ '_id' : 'BackupControlDocument' }).readConcern('majority');" ,
703
+ }, adminCreds ... )
704
+
705
+ if err := sh .Command (MongoCMD , args ... ).UnmarshalJSON (& v ); err != nil {
693
706
return err
694
707
}
695
708
696
709
val2 , ok = v ["counter" ].(float64 )
697
710
if ! ok {
698
711
return fmt .Errorf ("unable to get BackupControlDocument. got response: %v" , v )
699
712
}
700
-
701
713
if int (val ) != int (val2 ) {
702
714
klog .V (5 ).Infof ("BackupDocument counter in secondary is not same. Expected %v, but got %v. Full response: %v" , val , val2 , v )
703
715
time .Sleep (time .Second * 5 )
@@ -706,7 +718,6 @@ func lockConfigServer(configSVRDSN, secondaryHost string) error {
706
718
if timer >= 60 {
707
719
return fmt .Errorf ("timeout while waiting for BackupDocument counter in secondary to be same as primary. Expected %v, but got %v. Full response: %v" , val , val2 , v )
708
720
}
709
-
710
721
// lock secondary
711
722
return lockSecondaryMember (secondaryHost )
712
723
}
0 commit comments