@@ -478,43 +478,20 @@ func verifyAddonStatusInternal(cc *config.ClusterConfig, name string, val string
478
478
return nil
479
479
}
480
480
481
- // Start enables the default addons for a profile, plus any additional
482
- func Start (wg * sync.WaitGroup , cc * config.ClusterConfig , toEnable map [string ]bool , additional []string ) {
481
+ // Enable tries to enable the default addons for a profile plus any additional, and returns a single slice of all successfully enabled addons via channel (thread-safe).
482
+ // Since Enable is called asynchronously (so is not thread-safe for concurrent addons map updating/reading), to avoid race conditions,
483
+ // ToEnable should be called synchronously before Enable to get complete list of addons to enable, and
484
+ // UpdateConfig should be called synchronously after Enable to update the config with successfully enabled addons.
485
+ func Enable (wg * sync.WaitGroup , cc * config.ClusterConfig , toEnable map [string ]bool , enabled chan <- []string ) {
483
486
defer wg .Done ()
484
487
485
488
start := time .Now ()
486
- klog .Infof ("enableAddons start: toEnable=%v, additional=%s" , toEnable , additional )
489
+ klog .Infof ("enable addons start: toEnable=%v" , toEnable )
490
+ var enabledAddons []string
487
491
defer func () {
488
- klog .Infof ("enableAddons completed in %s" , time .Since (start ))
492
+ klog .Infof ("enable addons completed in %s: enabled=%v " , time .Since (start ), enabledAddons )
489
493
}()
490
494
491
- // Get the default values of any addons not saved to our config
492
- for name , a := range assets .Addons {
493
- defaultVal := a .IsEnabled (cc )
494
-
495
- _ , exists := toEnable [name ]
496
- if ! exists {
497
- toEnable [name ] = defaultVal
498
- }
499
- }
500
-
501
- // Apply new addons
502
- for _ , name := range additional {
503
- isDeprecated , replacement , msg := Deprecations (name )
504
- if isDeprecated && replacement == "" {
505
- out .FailureT (msg )
506
- continue
507
- } else if isDeprecated {
508
- out .Styled (style .Waiting , msg )
509
- name = replacement
510
- }
511
- // if the specified addon doesn't exist, skip enabling
512
- _ , e := isAddonValid (name )
513
- if e {
514
- toEnable [name ] = true
515
- }
516
- }
517
-
518
495
toEnableList := []string {}
519
496
for k , v := range toEnable {
520
497
if v {
@@ -525,8 +502,6 @@ func Start(wg *sync.WaitGroup, cc *config.ClusterConfig, toEnable map[string]boo
525
502
526
503
var awg sync.WaitGroup
527
504
528
- var enabledAddons []string
529
-
530
505
defer func () { // making it show after verifications (see #7613)
531
506
register .Reg .SetStep (register .EnablingAddons )
532
507
out .Step (style .AddonEnable , "Enabled addons: {{.addons}}" , out.V {"addons" : strings .Join (enabledAddons , ", " )})
@@ -544,10 +519,52 @@ func Start(wg *sync.WaitGroup, cc *config.ClusterConfig, toEnable map[string]boo
544
519
}(a )
545
520
}
546
521
547
- // Wait until all of the addons are enabled before updating the config (not thread safe)
522
+ // Wait until all of the addons are enabled
548
523
awg .Wait ()
549
524
550
- for _ , a := range enabledAddons {
525
+ // send the slice of all successfully enabled addons to channel and close
526
+ enabled <- enabledAddons
527
+ close (enabled )
528
+ }
529
+
530
+ // ToEnable returns the final list of addons to enable (not thread-safe).
531
+ func ToEnable (cc * config.ClusterConfig , existing map [string ]bool , additional []string ) map [string ]bool {
532
+ // start from existing
533
+ enable := map [string ]bool {}
534
+ for k , v := range existing {
535
+ enable [k ] = v
536
+ }
537
+
538
+ // Get the default values of any addons not saved to our config
539
+ for name , a := range assets .Addons {
540
+ if _ , exists := existing [name ]; ! exists {
541
+ enable [name ] = a .IsEnabled (cc )
542
+ }
543
+ }
544
+
545
+ // Apply new addons
546
+ for _ , name := range additional {
547
+ isDeprecated , replacement , msg := Deprecations (name )
548
+ if isDeprecated && replacement == "" {
549
+ out .FailureT (msg )
550
+ continue
551
+ } else if isDeprecated {
552
+ out .Styled (style .Waiting , msg )
553
+ name = replacement
554
+ }
555
+ // if the specified addon doesn't exist, skip enabling
556
+ if _ , e := isAddonValid (name ); e {
557
+ enable [name ] = true
558
+ }
559
+ }
560
+
561
+ return enable
562
+ }
563
+
564
+ // UpdateConfig tries to update config with all enabled addons (not thread-safe).
565
+ // Any error will be logged and it will continue.
566
+ func UpdateConfig (cc * config.ClusterConfig , enabled []string ) {
567
+ for _ , a := range enabled {
551
568
if err := Set (cc , a , "true" ); err != nil {
552
569
klog .Errorf ("store failed: %v" , err )
553
570
}
0 commit comments