controller/volume/selinuxwarning: Improve goroutine mgmt

Make sure all threads are terminated when Run returns.
This commit is contained in:
Ondra Kupka
2025-10-29 11:54:00 +01:00
parent 1e6ad423bf
commit e08d03b1b5
2 changed files with 22 additions and 5 deletions

View File

@@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
"sync"
"time"
v1 "k8s.io/api/core/v1"
@@ -343,10 +344,16 @@ func (c *Controller) enqueueAllPodsForCSIDriver(csiDriverName string) {
func (c *Controller) Run(ctx context.Context, workers int) {
defer utilruntime.HandleCrash()
defer c.queue.ShutDown()
logger := klog.FromContext(ctx)
logger.Info("Starting SELinux warning controller")
defer logger.Info("Shutting down SELinux warning controller")
var wg sync.WaitGroup
defer func() {
logger.Info("Shutting down SELinux warning controller")
c.queue.ShutDown()
wg.Wait()
}()
c.eventBroadcaster.StartStructuredLogging(3) // verbosity level 3 is used by the other KCM controllers
c.eventBroadcaster.StartRecordingToSink(&v1core.EventSinkImpl{Interface: c.kubeClient.CoreV1().Events("")})
@@ -357,9 +364,10 @@ func (c *Controller) Run(ctx context.Context, workers int) {
}
for i := 0; i < workers; i++ {
go wait.UntilWithContext(ctx, c.runWorker, time.Second)
wg.Go(func() {
wait.UntilWithContext(ctx, c.runWorker, time.Second)
})
}
<-ctx.Done()
}

View File

@@ -17,8 +17,10 @@ limitations under the License.
package selinuxwarning
import (
"context"
"reflect"
"sort"
"sync"
"testing"
v1 "k8s.io/api/core/v1"
@@ -355,7 +357,12 @@ func TestSELinuxWarningController_Sync(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SELinuxChangePolicy, true)
var wg sync.WaitGroup
defer wg.Wait()
_, ctx := ktesting.NewTestContext(t)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
_, plugin := volumetesting.GetTestKubeletVolumePluginMgr(t)
plugin.SupportsSELinux = true
@@ -393,7 +400,9 @@ func TestSELinuxWarningController_Sync(t *testing.T) {
fakeInformerFactory.Start(ctx.Done())
fakeInformerFactory.WaitForCacheSync(ctx.Done())
// Start the controller
go c.Run(ctx, 1)
wg.Go(func() {
c.Run(ctx, 1)
})
// Inject fake existing objects
for _, pvc := range tt.existingPVCs {