@@ -114,7 +114,7 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCluster(ctx context.Context, cr
114
114
return api .AppStateError , nil , errors .Wrap (err , "dial" )
115
115
}
116
116
117
- err := r .handleReplsetInit (ctx , cr , replset , pods .Items )
117
+ pod , primary , err := r .handleReplsetInit (ctx , cr , replset , pods .Items )
118
118
if err != nil {
119
119
return api .AppStateInit , nil , errors .Wrap (err , "handleReplsetInit" )
120
120
}
@@ -126,6 +126,7 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCluster(ctx context.Context, cr
126
126
127
127
rs := cr .Status .Replsets [replset .Name ]
128
128
rs .Initialized = true
129
+ rs .Members = map [string ]api.ReplsetMemberStatus {pod .Name : * primary }
129
130
cr .Status .Replsets [replset .Name ] = rs
130
131
131
132
cr .Status .AddCondition (api.ClusterCondition {
@@ -242,25 +243,16 @@ func (r *ReconcilePerconaServerMongoDB) reconcileCluster(ctx context.Context, cr
242
243
}
243
244
}
244
245
245
- rsMembers , err := r .updateConfigMembers (ctx , cli , cr , replset )
246
+ rsMembers , liveMembers , err := r .updateConfigMembers (ctx , cli , cr , replset )
246
247
if err != nil {
247
248
return api .AppStateError , nil , errors .Wrap (err , "failed to update config members" )
248
249
}
249
250
250
- membersLive := 0
251
- for _ , member := range rsMembers {
252
- switch member .State {
253
- case mongo .MemberStatePrimary , mongo .MemberStateSecondary , mongo .MemberStateArbiter :
254
- membersLive ++
255
- }
256
-
257
- }
258
-
259
- if membersLive == len (pods .Items ) {
251
+ if liveMembers == len (pods .Items ) {
260
252
return api .AppStateReady , rsMembers , nil
261
253
}
262
254
263
- log .V (1 ).Info ("Replset is not ready" , "liveMembers" , membersLive , "pods" , len (pods .Items ))
255
+ log .V (1 ).Info ("Replset is not ready" , "liveMembers" , liveMembers , "pods" , len (pods .Items ))
264
256
265
257
return api .AppStateInit , rsMembers , nil
266
258
}
@@ -373,10 +365,11 @@ func (r *ReconcilePerconaServerMongoDB) getConfigMemberForExternalNode(id int, e
373
365
return member
374
366
}
375
367
376
- func (r * ReconcilePerconaServerMongoDB ) updateConfigMembers (ctx context.Context , cli mongo.Client , cr * api.PerconaServerMongoDB , rs * api.ReplsetSpec ) (map [string ]api.ReplsetMemberStatus , error ) {
368
+ func (r * ReconcilePerconaServerMongoDB ) updateConfigMembers (ctx context.Context , cli mongo.Client , cr * api.PerconaServerMongoDB , rs * api.ReplsetSpec ) (map [string ]api.ReplsetMemberStatus , int , error ) {
377
369
log := logf .FromContext (ctx )
378
370
// Primary with a Secondary and an Arbiter (PSA)
379
371
unsafePSA := false
372
+ rsMembers := make (map [string ]api.ReplsetMemberStatus )
380
373
381
374
if cr .CompareVersion ("1.15.0" ) <= 0 {
382
375
unsafePSA = cr .Spec .UnsafeConf && rs .Arbiter .Enabled && rs .Arbiter .Size == 1 && ! rs .NonVoting .Enabled && rs .Size == 2
@@ -386,17 +379,17 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
386
379
387
380
pods , err := psmdb .GetRSPods (ctx , r .client , cr , rs .Name )
388
381
if err != nil {
389
- return nil , errors .Wrap (err , "get rs pods" )
382
+ return rsMembers , 0 , errors .Wrap (err , "get rs pods" )
390
383
}
391
384
392
385
cnf , err := cli .ReadConfig (ctx )
393
386
if err != nil {
394
- return nil , errors .Wrap (err , "get replset config" )
387
+ return rsMembers , 0 , errors .Wrap (err , "get replset config" )
395
388
}
396
389
397
390
rsStatus , err := cli .RSStatus (ctx )
398
391
if err != nil {
399
- return nil , errors .Wrap (err , "get replset status" )
392
+ return rsMembers , 0 , errors .Wrap (err , "get replset status" )
400
393
}
401
394
402
395
members := mongo.ConfigMembers {}
@@ -408,7 +401,7 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
408
401
409
402
member , err := r .getConfigMemberForPod (ctx , cr , rs , key , & pod )
410
403
if err != nil {
411
- return nil , errors .Wrapf (err , "get config member for pod %s" , pod .Name )
404
+ return rsMembers , 0 , errors .Wrapf (err , "get config member for pod %s" , pod .Name )
412
405
}
413
406
414
407
members = append (members , member )
@@ -433,7 +426,7 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
433
426
if member .State == mongo .MemberStatePrimary {
434
427
log .Info ("Stepping down the primary" , "member" , member .Name )
435
428
if err := cli .StepDown (ctx , 60 , false ); err != nil {
436
- return nil , errors .Wrap (err , "step down primary" )
429
+ return rsMembers , 0 , errors .Wrap (err , "step down primary" )
437
430
}
438
431
}
439
432
@@ -442,10 +435,10 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
442
435
log .Info ("Fixing hostname of member" , "replset" , rs .Name , "id" , member .Id , "member" , member .Name )
443
436
444
437
if err := cli .WriteConfig (ctx , cnf , false ); err != nil {
445
- return nil , errors .Wrap (err , "fix member hostname: write mongo config" )
438
+ return rsMembers , 0 , errors .Wrap (err , "fix member hostname: write mongo config" )
446
439
}
447
440
448
- return nil , nil
441
+ return rsMembers , 0 , nil
449
442
}
450
443
451
444
if cnf .Members .FixMemberConfigs (ctx , members ) {
@@ -454,7 +447,7 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
454
447
log .Info ("Fixing member configurations" , "replset" , rs .Name )
455
448
456
449
if err := cli .WriteConfig (ctx , cnf , false ); err != nil {
457
- return nil , errors .Wrap (err , "fix member configurations: write mongo config" )
450
+ return rsMembers , 0 , errors .Wrap (err , "fix member configurations: write mongo config" )
458
451
}
459
452
}
460
453
@@ -465,7 +458,7 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
465
458
466
459
err = cli .WriteConfig (ctx , cnf , false )
467
460
if err != nil {
468
- return nil , errors .Wrap (err , "delete: write mongo config" )
461
+ return rsMembers , 0 , errors .Wrap (err , "delete: write mongo config" )
469
462
}
470
463
}
471
464
@@ -476,7 +469,7 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
476
469
477
470
err = cli .WriteConfig (ctx , cnf , false )
478
471
if err != nil {
479
- return nil , errors .Wrap (err , "add new: write mongo config" )
472
+ return rsMembers , 0 , errors .Wrap (err , "add new: write mongo config" )
480
473
}
481
474
}
482
475
@@ -487,7 +480,7 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
487
480
488
481
err = cli .WriteConfig (ctx , cnf , false )
489
482
if err != nil {
490
- return nil , errors .Wrap (err , "update external nodes: write mongo config" )
483
+ return rsMembers , 0 , errors .Wrap (err , "update external nodes: write mongo config" )
491
484
}
492
485
}
493
486
@@ -500,41 +493,47 @@ func (r *ReconcilePerconaServerMongoDB) updateConfigMembers(ctx context.Context,
500
493
501
494
err := cli .WriteConfig (ctx , cnf , false )
502
495
if err != nil {
503
- return nil , errors .Wrap (err , "set votes: write mongo config" )
496
+ return rsMembers , 0 , errors .Wrap (err , "set votes: write mongo config" )
504
497
}
505
498
}
506
499
507
500
rsStatus , err = cli .RSStatus (ctx )
508
501
if err != nil {
509
- return nil , errors .Wrap (err , "unable to get replset members" )
502
+ return rsMembers , 0 , errors .Wrap (err , "unable to get replset members" )
510
503
}
511
504
512
- rsMembers := make ( map [ string ]api. ReplsetMemberStatus )
505
+ liveMembers := 0
513
506
for _ , member := range rsStatus .Members {
514
507
var tags mongo.ReplsetTags
508
+
515
509
for i := range cnf .Members {
516
510
if member .Id == cnf .Members [i ].ID {
517
511
tags = cnf .Members [i ].Tags
518
512
break
519
513
}
520
514
}
515
+
521
516
if _ , ok := tags ["external" ]; ok {
522
517
continue
523
518
}
524
519
525
- podName , ok := tags ["podName" ]
526
- if ! ok {
527
- continue
520
+ if podName , ok := tags ["podName" ]; ok {
521
+ rsMembers [podName ] = api.ReplsetMemberStatus {
522
+ Name : member .Name ,
523
+ State : member .State ,
524
+ StateStr : member .StateStr ,
525
+ }
528
526
}
529
527
530
- rsMembers [podName ] = api.ReplsetMemberStatus {
531
- Name : member .Name ,
532
- State : member .State ,
533
- StateStr : member .StateStr ,
528
+ log .V (1 ).Info ("Member state" , "member" , member .Name , "state" , member .State , "stateStr" , member .StateStr )
529
+
530
+ switch member .State {
531
+ case mongo .MemberStatePrimary , mongo .MemberStateSecondary , mongo .MemberStateArbiter :
532
+ liveMembers ++
534
533
}
535
534
}
536
535
537
- return rsMembers , nil
536
+ return rsMembers , liveMembers , nil
538
537
}
539
538
540
539
func inShard (ctx context.Context , client mongo.Client , rsName string ) (bool , error ) {
@@ -645,7 +644,7 @@ func (r *ReconcilePerconaServerMongoDB) handleRsAddToShard(ctx context.Context,
645
644
// This must be ran from within the running container to utilize the MongoDB Localhost Exception.
646
645
//
647
646
// See: https://www.mongodb.com/docs/manual/core/localhost-exception/
648
- func (r * ReconcilePerconaServerMongoDB ) handleReplsetInit (ctx context.Context , cr * api.PerconaServerMongoDB , replset * api.ReplsetSpec , pods []corev1.Pod ) error {
647
+ func (r * ReconcilePerconaServerMongoDB ) handleReplsetInit (ctx context.Context , cr * api.PerconaServerMongoDB , replset * api.ReplsetSpec , pods []corev1.Pod ) ( * corev1. Pod , * api. ReplsetMemberStatus , error ) {
649
648
log := logf .FromContext (ctx )
650
649
651
650
for _ , pod := range pods {
@@ -663,19 +662,19 @@ func (r *ReconcilePerconaServerMongoDB) handleReplsetInit(ctx context.Context, c
663
662
664
663
member , err := r .getConfigMemberForPod (ctx , cr , replset , 0 , & pod )
665
664
if err != nil {
666
- return errors .Wrapf (err , "get config member for pod %s" , pod .Name )
665
+ return nil , nil , errors .Wrapf (err , "get config member for pod %s" , pod .Name )
667
666
}
668
667
669
668
memberBytes , err := json .Marshal (member )
670
669
if err != nil {
671
- return errors .Wrap (err , "marshall member to json" )
670
+ return nil , nil , errors .Wrap (err , "marshall member to json" )
672
671
}
673
672
674
673
var errb , outb bytes.Buffer
675
674
676
675
err = r .clientcmd .Exec (ctx , & pod , "mongod" , []string {"mongod" , "--version" }, nil , & outb , & errb , false )
677
676
if err != nil {
678
- return fmt .Errorf ("exec --version: %v / %s / %s" , err , outb .String (), errb .String ())
677
+ return nil , nil , fmt .Errorf ("exec --version: %v / %s / %s" , err , outb .String (), errb .String ())
679
678
}
680
679
681
680
mongoCmd := "mongosh"
@@ -709,7 +708,7 @@ func (r *ReconcilePerconaServerMongoDB) handleReplsetInit(ctx context.Context, c
709
708
outb .Reset ()
710
709
err = r .clientcmd .Exec (ctx , & pod , "mongod" , cmd , nil , & outb , & errb , false )
711
710
if err != nil {
712
- return fmt .Errorf ("exec rs.initiate: %v / %s / %s" , err , outb .String (), errb .String ())
711
+ return nil , nil , fmt .Errorf ("exec rs.initiate: %v / %s / %s" , err , outb .String (), errb .String ())
713
712
}
714
713
715
714
log .Info ("replset initialized" , "replset" , replsetName , "pod" , pod .Name )
@@ -718,22 +717,26 @@ func (r *ReconcilePerconaServerMongoDB) handleReplsetInit(ctx context.Context, c
718
717
log .Info ("creating user admin" , "replset" , replsetName , "pod" , pod .Name , "user" , api .RoleUserAdmin )
719
718
userAdmin , err := getInternalCredentials (ctx , r .client , cr , api .RoleUserAdmin )
720
719
if err != nil {
721
- return errors .Wrap (err , "failed to get userAdmin credentials" )
720
+ return nil , nil , errors .Wrap (err , "failed to get userAdmin credentials" )
722
721
}
723
722
724
723
cmd [2 ] = fmt .Sprintf (`%s --eval %s` , mongoCmd , mongoInitAdminUser (userAdmin .Username , userAdmin .Password ))
725
724
errb .Reset ()
726
725
outb .Reset ()
727
726
err = r .clientcmd .Exec (ctx , & pod , "mongod" , cmd , nil , & outb , & errb , false )
728
727
if err != nil {
729
- return fmt .Errorf ("exec add admin user: %v / %s / %s" , err , outb .String (), errb .String ())
728
+ return nil , nil , fmt .Errorf ("exec add admin user: %v / %s / %s" , err , outb .String (), errb .String ())
730
729
}
731
730
log .Info ("user admin created" , "replset" , replsetName , "pod" , pod .Name , "user" , api .RoleUserAdmin )
732
731
733
- return nil
732
+ return & pod , & api.ReplsetMemberStatus {
733
+ Name : member .Host ,
734
+ State : mongo .MemberStatePrimary ,
735
+ StateStr : mongo .MemberStateStrings [mongo .MemberStatePrimary ],
736
+ }, nil
734
737
}
735
738
736
- return errNoRunningMongodContainers
739
+ return nil , nil , errNoRunningMongodContainers
737
740
}
738
741
739
742
func (r * ReconcilePerconaServerMongoDB ) handleReplicaSetNoPrimary (ctx context.Context , cr * api.PerconaServerMongoDB , replset * api.ReplsetSpec , pods []corev1.Pod ) error {
0 commit comments