diff --git a/comp/core/autodiscovery/providers/kube_services.go b/comp/core/autodiscovery/providers/kube_services.go index 6cb325916697a4..db75e64e9f69a9 100644 --- a/comp/core/autodiscovery/providers/kube_services.go +++ b/comp/core/autodiscovery/providers/kube_services.go @@ -12,6 +12,7 @@ import ( "fmt" "strings" + "go.uber.org/atomic" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" listersv1 "k8s.io/client-go/listers/core/v1" @@ -35,7 +36,7 @@ const ( // KubeServiceConfigProvider implements the ConfigProvider interface for the apiserver. type KubeServiceConfigProvider struct { lister listersv1.ServiceLister - upToDate bool + upToDate *atomic.Bool configErrors map[string]ErrorMsgSet telemetryStore *telemetry.Store } @@ -58,6 +59,7 @@ func NewKubeServiceConfigProvider(_ *pkgconfigsetup.ConfigurationProviders, tele lister: servicesInformer.Lister(), configErrors: make(map[string]ErrorMsgSet), telemetryStore: telemetryStore, + upToDate: atomic.NewBool(false), } if _, err := servicesInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ @@ -91,7 +93,7 @@ func (k *KubeServiceConfigProvider) Collect(ctx context.Context) ([]integration. if err != nil { return nil, err } - k.upToDate = true + k.upToDate.Store(true) return k.parseServiceAnnotations(services, pkgconfigsetup.Datadog()) } @@ -100,13 +102,13 @@ func (k *KubeServiceConfigProvider) Collect(ctx context.Context) ([]integration. // //nolint:revive // TODO(CINT) Fix revive linter func (k *KubeServiceConfigProvider) IsUpToDate(ctx context.Context) (bool, error) { - return k.upToDate, nil + return k.upToDate.Load(), nil } func (k *KubeServiceConfigProvider) invalidate(obj interface{}) { if obj != nil { log.Trace("Invalidating configs on new/deleted service") - k.upToDate = false + k.upToDate.Store(false) } } @@ -122,7 +124,7 @@ func (k *KubeServiceConfigProvider) invalidateIfChanged(old, obj interface{}) { castedOld, ok := old.(*v1.Service) if !ok { log.Errorf("Expected a *v1.Service type, got: %T", old) - k.upToDate = false + k.upToDate.Store(false) return } // Quick exit if resversion did not change @@ -132,7 +134,7 @@ func (k *KubeServiceConfigProvider) invalidateIfChanged(old, obj interface{}) { // Compare annotations if valuesDiffer(castedObj.Annotations, castedOld.Annotations, kubeServiceAnnotationPrefix) { log.Trace("Invalidating configs on service change") - k.upToDate = false + k.upToDate.Store(false) return } } diff --git a/comp/core/autodiscovery/providers/kube_services_test.go b/comp/core/autodiscovery/providers/kube_services_test.go index 9c2112bf92a834..edf39bc61ee9af 100644 --- a/comp/core/autodiscovery/providers/kube_services_test.go +++ b/comp/core/autodiscovery/providers/kube_services_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.uber.org/atomic" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -247,6 +248,7 @@ func TestParseKubeServiceAnnotations(t *testing.T) { provider := KubeServiceConfigProvider{ telemetryStore: telemetryStore, + upToDate: atomic.NewBool(false), } cfgs, _ := provider.parseServiceAnnotations([]*v1.Service{tc.service}, cfg) assert.EqualValues(t, tc.expectedOut, cfgs) @@ -337,7 +339,7 @@ func TestInvalidateIfChanged(t *testing.T) { } { t.Run("", func(t *testing.T) { ctx := context.Background() - provider := &KubeServiceConfigProvider{upToDate: true} + provider := &KubeServiceConfigProvider{upToDate: atomic.NewBool(true)} provider.invalidateIfChanged(tc.old, tc.obj) upToDate, err := provider.IsUpToDate(ctx) @@ -475,6 +477,7 @@ func TestGetConfigErrors_KubeServices(t *testing.T) { lister: lister, configErrors: test.currentErrors, telemetryStore: telemetryStore, + upToDate: atomic.NewBool(false), } configs, err := provider.Collect(context.TODO()) diff --git a/releasenotes-dca/notes/ad-data-race-kube-services-provider-8cbf74f32595c448.yaml b/releasenotes-dca/notes/ad-data-race-kube-services-provider-8cbf74f32595c448.yaml new file mode 100644 index 00000000000000..f4426b8de5b40b --- /dev/null +++ b/releasenotes-dca/notes/ad-data-race-kube-services-provider-8cbf74f32595c448.yaml @@ -0,0 +1,11 @@ +# Each section from every release note are combined when the +# CHANGELOG-DCA.rst is rendered. So the text needs to be worded so that +# it does not depend on any information only available in another +# section. This may mean repeating some details, but each section +# must be readable independently of the other. +# +# Each section note must be formatted as reStructuredText. +--- +fixes: + - | + Fix data race in autodiscovery kube services provider.