diff --git a/internal/controller/datadogagent/controller_v2_test.go b/internal/controller/datadogagent/controller_v2_test.go index 23a3a11a9..ec4b8c92f 100644 --- a/internal/controller/datadogagent/controller_v2_test.go +++ b/internal/controller/datadogagent/controller_v2_test.go @@ -1753,7 +1753,7 @@ func Test_DDAI_ReconcileV3(t *testing.T) { wantFunc: func(t *testing.T, c client.Client) { expectedDDAI := getBaseDDAI(dda) expectedDDAI.Annotations = map[string]string{ - constants.MD5DDAIDeploymentAnnotationKey: "ccac39a3a007bad81d7baf8febc6445f", + constants.MD5DDAIDeploymentAnnotationKey: "d472c741d84f93e553772d29ba5ea914", } verifyDDAI(t, c, []v1alpha1.DatadogAgentInternal{expectedDDAI}) @@ -1785,7 +1785,7 @@ func Test_DDAI_ReconcileV3(t *testing.T) { baseDDAI := getBaseDDAI(dda) expectedDDAI := baseDDAI.DeepCopy() expectedDDAI.Annotations = map[string]string{ - constants.MD5DDAIDeploymentAnnotationKey: "f2aa21d0ecced63c091ca2df3d31e451", + constants.MD5DDAIDeploymentAnnotationKey: "9d6165c057934517d4c0623699a4257a", } expectedDDAI.Spec.Features.ClusterChecks.UseClusterChecksRunners = ptr.To(true) expectedDDAI.Spec.Global.Credentials = &v2alpha1.DatadogCredentials{ @@ -1861,7 +1861,7 @@ func Test_DDAI_ReconcileV3(t *testing.T) { profileDDAI := getBaseDDAI(dda) profileDDAI.Name = "foo-profile" profileDDAI.Annotations = map[string]string{ - constants.MD5DDAIDeploymentAnnotationKey: "73e0cc1e445001e326507ac23654104e", + constants.MD5DDAIDeploymentAnnotationKey: "d868cbefaa12de8dfc8e94552dcf8528", } profileDDAI.Labels[constants.ProfileLabelKey] = "foo-profile" profileDDAI.Spec.Override = map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{ @@ -2095,7 +2095,7 @@ func getBaseDDAI(dda *v2alpha1.DatadogAgent) v1alpha1.DatadogAgentInternal { func getDefaultDDAI(dda *v2alpha1.DatadogAgent) v1alpha1.DatadogAgentInternal { expectedDDAI := getBaseDDAI(dda) expectedDDAI.Annotations = map[string]string{ - constants.MD5DDAIDeploymentAnnotationKey: "f98c0497c66e2747f6d116970ab8f0b1", + constants.MD5DDAIDeploymentAnnotationKey: "1a68caa8fd645f09d034b2b97a61f543", } expectedDDAI.Spec.Override = map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{ v2alpha1.NodeAgentComponentName: { diff --git a/internal/controller/datadogagent/defaults/datadogagent_default.go b/internal/controller/datadogagent/defaults/datadogagent_default.go index 1a2c3fe69..faa470fca 100644 --- a/internal/controller/datadogagent/defaults/datadogagent_default.go +++ b/internal/controller/datadogagent/defaults/datadogagent_default.go @@ -43,8 +43,6 @@ const ( defaultGPUMonitoringEnabled bool = false - defaultServiceDiscoveryEnabled bool = false - defaultAPMEnabled bool = true defaultAPMHostPortEnabled bool = false defaultAPMHostPort int32 = 8126 @@ -304,7 +302,9 @@ func defaultFeaturesConfig(ddaSpec *v2alpha1.DatadogAgentSpec) { if ddaSpec.Features.ServiceDiscovery == nil { ddaSpec.Features.ServiceDiscovery = &v2alpha1.ServiceDiscoveryFeatureConfig{} } - apiutils.DefaultBooleanIfUnset(&ddaSpec.Features.ServiceDiscovery.Enabled, defaultServiceDiscoveryEnabled) + // Enabled is intentionally not defaulted to false — Enabled=nil (not configured by user) + // must remain distinguishable from Enabled=false (explicit opt-out) so that the feature + // can be auto-activated by the operator in the future without exposing a CRD field. // GPU monitoring feature if ddaSpec.Features.GPU == nil { diff --git a/internal/controller/datadogagent/defaults/datadogagent_default_test.go b/internal/controller/datadogagent/defaults/datadogagent_default_test.go index 0a7ca3355..e4528cf22 100644 --- a/internal/controller/datadogagent/defaults/datadogagent_default_test.go +++ b/internal/controller/datadogagent/defaults/datadogagent_default_test.go @@ -213,9 +213,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -362,9 +360,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -461,9 +457,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -597,9 +591,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -758,9 +750,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -914,9 +904,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -1070,9 +1058,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -1235,9 +1221,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -1391,9 +1375,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -1550,9 +1532,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -1752,9 +1732,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -1877,9 +1855,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -2034,9 +2010,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -2214,9 +2188,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, @@ -2373,9 +2345,7 @@ func Test_defaultFeatures(t *testing.T) { EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{ Enabled: ptr.To(defaultEBPFCheckEnabled), }, - ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ - Enabled: ptr.To(defaultServiceDiscoveryEnabled), - }, + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{}, GPU: &v2alpha1.GPUFeatureConfig{ Enabled: ptr.To(defaultGPUMonitoringEnabled), }, diff --git a/internal/controller/datadogagent/feature/servicediscovery/feature.go b/internal/controller/datadogagent/feature/servicediscovery/feature.go index 14f9e3fa7..c741a08e7 100644 --- a/internal/controller/datadogagent/feature/servicediscovery/feature.go +++ b/internal/controller/datadogagent/feature/servicediscovery/feature.go @@ -6,6 +6,8 @@ package servicediscovery import ( + "fmt" + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" @@ -30,6 +32,11 @@ func buildFeature(*feature.Options) feature.Feature { } type serviceDiscoveryFeature struct { + userExplicitlyEnabled bool + // features holds a pointer to the live DDA features struct so that ManageNodeAgent + // can re-evaluate hasOtherSystemProbeFeatures after Remote Config state has been + // merged by other features' Configure calls (e.g. USM merges RC state into the spec). + features *v2alpha1.DatadogFeatures } // ID returns the ID of the Feature @@ -39,17 +46,58 @@ func (f *serviceDiscoveryFeature) ID() feature.IDType { // Configure is used to configure the feature from a v2alpha1.DatadogAgent instance. func (f *serviceDiscoveryFeature) Configure(_ metav1.Object, ddaSpec *v2alpha1.DatadogAgentSpec, _ *v2alpha1.RemoteConfigConfiguration) (reqComp feature.RequiredComponents) { - if ddaSpec.Features != nil && ddaSpec.Features.ServiceDiscovery != nil && apiutils.BoolValue(ddaSpec.Features.ServiceDiscovery.Enabled) { - reqComp.Agent = feature.RequiredComponent{ - IsRequired: ptr.To(true), - Containers: []apicommon.AgentContainerName{apicommon.CoreAgentContainerName, apicommon.SystemProbeContainerName}, - } + if ddaSpec.Features == nil || ddaSpec.Features.ServiceDiscovery == nil { + return reqComp + } + + sd := ddaSpec.Features.ServiceDiscovery + // Enabled=nil (not configured) or Enabled=false (explicit opt-out) → disabled. + if !apiutils.BoolValue(sd.Enabled) { + return reqComp } + reqComp.Agent = feature.RequiredComponent{ + IsRequired: ptr.To(true), + Containers: []apicommon.AgentContainerName{apicommon.CoreAgentContainerName, apicommon.SystemProbeContainerName}, + } + + f.features = ddaSpec.Features + // True only when Enabled=true (user opted in); nil means operator auto-enabled (future path). + f.userExplicitlyEnabled = sd.Enabled != nil && *sd.Enabled + return reqComp } +// systemProbeLiteCommand returns the shell command for the system-probe container when +// system-probe-lite is preferred. If userOptedIn is true (user explicitly enabled discovery), +// system-probe is used as the fallback — the user has accepted the resource cost. +// Otherwise (enabled by default), the fallback is sleep infinity to avoid unexpectedly +// running system-probe on older agent images where the discovery feature may not be supported. +func systemProbeLiteCommand(socketPath string, userOptedIn bool) string { + fallback := "sleep infinity" + if userOptedIn { + fallback = "system-probe --config=/etc/datadog-agent/system-probe.yaml" + } + return fmt.Sprintf("system-probe-lite run --socket %s --log-level ${DD_LOG_LEVEL:-info} || %s", socketPath, fallback) +} + +// hasOtherSystemProbeFeatures returns true if any feature besides service discovery +// requires the full system-probe binary. When true, system-probe-lite cannot be used. +func hasOtherSystemProbeFeatures(features *v2alpha1.DatadogFeatures) bool { + if features == nil { + return false + } + return (features.NPM != nil && apiutils.BoolValue(features.NPM.Enabled)) || + (features.CWS != nil && apiutils.BoolValue(features.CWS.Enabled)) || + (features.CSPM != nil && apiutils.BoolValue(features.CSPM.Enabled) && apiutils.BoolValue(features.CSPM.RunInSystemProbe)) || + (features.USM != nil && apiutils.BoolValue(features.USM.Enabled)) || + (features.OOMKill != nil && apiutils.BoolValue(features.OOMKill.Enabled)) || + (features.TCPQueueLength != nil && apiutils.BoolValue(features.TCPQueueLength.Enabled)) || + (features.EBPFCheck != nil && apiutils.BoolValue(features.EBPFCheck.Enabled)) || + (features.GPU != nil && apiutils.BoolValue(features.GPU.Enabled) && apiutils.BoolValue(features.GPU.PrivilegedMode)) +} + // ManageDependencies allows a feature to manage its dependencies. // Feature's dependencies should be added in the store. func (f *serviceDiscoveryFeature) ManageDependencies(managers feature.ResourceManagers, provider string) error { @@ -105,6 +153,20 @@ func (f *serviceDiscoveryFeature) ManageNodeAgent(managers feature.PodTemplateMa managers.EnvVar().AddEnvVarToContainer(apicommon.CoreAgentContainerName, socketEnvVar) managers.EnvVar().AddEnvVarToContainer(apicommon.SystemProbeContainerName, socketEnvVar) + // Direct PodTemplateSpec mutation: no managers API for command overrides. + // Re-evaluate here (not cached from Configure) so that RC state merged by other + // features' Configure calls (e.g. USM) is taken into account. + if !hasOtherSystemProbeFeatures(f.features) { + for i := range managers.PodTemplateSpec().Spec.Containers { + c := &managers.PodTemplateSpec().Spec.Containers[i] + if c.Name == string(apicommon.SystemProbeContainerName) { + c.Command = []string{"/bin/sh", "-c"} + c.Args = []string{systemProbeLiteCommand(common.DefaultSystemProbeSocketPath, f.userExplicitlyEnabled)} + break + } + } + } + return nil } diff --git a/internal/controller/datadogagent/feature/servicediscovery/feature_test.go b/internal/controller/datadogagent/feature/servicediscovery/feature_test.go index 5da2b193d..9a1a8c8ca 100644 --- a/internal/controller/datadogagent/feature/servicediscovery/feature_test.go +++ b/internal/controller/datadogagent/feature/servicediscovery/feature_test.go @@ -37,6 +37,32 @@ func Test_serviceDiscoveryFeature_Configure(t *testing.T) { ddaServiceDiscoveryEnabled := ddaServiceDiscoveryDisabled.DeepCopy() ddaServiceDiscoveryEnabled.Spec.Features.ServiceDiscovery.Enabled = ptr.To(true) + ddaWithNPM := v2alpha1.DatadogAgent{ + Spec: v2alpha1.DatadogAgentSpec{ + Features: &v2alpha1.DatadogFeatures{ + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ + Enabled: ptr.To(true), + }, + NPM: &v2alpha1.NPMFeatureConfig{ + Enabled: ptr.To(true), + }, + }, + }, + } + + ddaWithCWS := v2alpha1.DatadogAgent{ + Spec: v2alpha1.DatadogAgentSpec{ + Features: &v2alpha1.DatadogFeatures{ + ServiceDiscovery: &v2alpha1.ServiceDiscoveryFeatureConfig{ + Enabled: ptr.To(true), + }, + CWS: &v2alpha1.CWSFeatureConfig{ + Enabled: ptr.To(true), + }, + }, + }, + } + tests := test.FeatureTestSuite{ { Name: "service discovery not enabled", @@ -47,14 +73,155 @@ func Test_serviceDiscoveryFeature_Configure(t *testing.T) { Name: "service discovery enabled", DDA: ddaServiceDiscoveryEnabled, WantConfigure: true, - Agent: test.NewDefaultComponentTest().WithWantFunc(getWantFunc()), + Agent: test.NewDefaultComponentTest(). + WithCreateFunc(createFuncWithSystemProbeContainer()). + WithWantFunc(getWantFunc(true, true)), + }, + { + Name: "system-probe-lite not used when NPM also enabled", + DDA: &ddaWithNPM, + WantConfigure: true, + Agent: test.NewDefaultComponentTest(). + WithCreateFunc(createFuncWithSystemProbeContainer()). + WithWantFunc(getWantFunc(false, true)), + }, + { + Name: "system-probe-lite not used when CWS also enabled", + DDA: &ddaWithCWS, + WantConfigure: true, + Agent: test.NewDefaultComponentTest(). + WithCreateFunc(createFuncWithSystemProbeContainer()). + WithWantFunc(getWantFunc(false, true)), }, } tests.Run(t, buildFeature) } -func getWantFunc() func(t testing.TB, mgrInterface feature.PodTemplateManagers) { +func Test_hasOtherSystemProbeFeatures(t *testing.T) { + tests := []struct { + name string + features *v2alpha1.DatadogFeatures + want bool + }{ + { + name: "nil features", + features: nil, + want: false, + }, + { + name: "no other features", + features: &v2alpha1.DatadogFeatures{}, + want: false, + }, + { + name: "NPM enabled", + features: &v2alpha1.DatadogFeatures{ + NPM: &v2alpha1.NPMFeatureConfig{Enabled: ptr.To(true)}, + }, + want: true, + }, + { + name: "CWS enabled", + features: &v2alpha1.DatadogFeatures{ + CWS: &v2alpha1.CWSFeatureConfig{Enabled: ptr.To(true)}, + }, + want: true, + }, + { + name: "USM enabled", + features: &v2alpha1.DatadogFeatures{ + USM: &v2alpha1.USMFeatureConfig{Enabled: ptr.To(true)}, + }, + want: true, + }, + { + name: "OOMKill enabled", + features: &v2alpha1.DatadogFeatures{ + OOMKill: &v2alpha1.OOMKillFeatureConfig{Enabled: ptr.To(true)}, + }, + want: true, + }, + { + name: "TCPQueueLength enabled", + features: &v2alpha1.DatadogFeatures{ + TCPQueueLength: &v2alpha1.TCPQueueLengthFeatureConfig{Enabled: ptr.To(true)}, + }, + want: true, + }, + { + name: "EBPFCheck enabled", + features: &v2alpha1.DatadogFeatures{ + EBPFCheck: &v2alpha1.EBPFCheckFeatureConfig{Enabled: ptr.To(true)}, + }, + want: true, + }, + { + name: "CSPM enabled with RunInSystemProbe", + features: &v2alpha1.DatadogFeatures{ + CSPM: &v2alpha1.CSPMFeatureConfig{ + Enabled: ptr.To(true), + RunInSystemProbe: ptr.To(true), + }, + }, + want: true, + }, + { + name: "CSPM enabled without RunInSystemProbe", + features: &v2alpha1.DatadogFeatures{ + CSPM: &v2alpha1.CSPMFeatureConfig{ + Enabled: ptr.To(true), + }, + }, + want: false, + }, + { + name: "GPU enabled with PrivilegedMode", + features: &v2alpha1.DatadogFeatures{ + GPU: &v2alpha1.GPUFeatureConfig{ + Enabled: ptr.To(true), + PrivilegedMode: ptr.To(true), + }, + }, + want: true, + }, + { + name: "GPU enabled without PrivilegedMode", + features: &v2alpha1.DatadogFeatures{ + GPU: &v2alpha1.GPUFeatureConfig{ + Enabled: ptr.To(true), + }, + }, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, hasOtherSystemProbeFeatures(tt.features)) + }) + } +} + +func createFuncWithSystemProbeContainer() func(testing.TB) (feature.PodTemplateManagers, string) { + return func(t testing.TB) (feature.PodTemplateManagers, string) { + newPTS := corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: string(apicommon.CoreAgentContainerName), + }, + { + Name: string(apicommon.SystemProbeContainerName), + }, + }, + }, + } + return fake.NewPodTemplateManagers(t, newPTS), "" + } +} + +func getWantFunc(useSPL bool, userOptedIn bool) func(t testing.TB, mgrInterface feature.PodTemplateManagers) { return func(t testing.TB, mgrInterface feature.PodTemplateManagers) { mgr := mgrInterface.(*fake.PodTemplateManagers) @@ -157,5 +324,19 @@ func getWantFunc() func(t testing.TB, mgrInterface feature.PodTemplateManagers) systemProbeEnvVars := mgr.EnvVarMgr.EnvVarsByC[apicommon.SystemProbeContainerName] assert.True(t, apiutils.IsEqualStruct(systemProbeEnvVars, wantSPEnvVars), "System Probe envvars \ndiff = %s", cmp.Diff(systemProbeEnvVars, wantSPEnvVars)) + + // check system-probe container command override + for _, c := range mgr.PodTemplateSpec().Spec.Containers { + if c.Name == string(apicommon.SystemProbeContainerName) { + if useSPL { + assert.Equal(t, []string{"/bin/sh", "-c"}, c.Command, "System Probe command should be overridden for system-probe-lite") + assert.Equal(t, []string{systemProbeLiteCommand(common.DefaultSystemProbeSocketPath, userOptedIn)}, c.Args, "System Probe args mismatch") + } else { + assert.Empty(t, c.Command, "System Probe command should not be overridden") + assert.Empty(t, c.Args, "System Probe args should not be overridden") + } + break + } + } } }