Skip to content

feat: add affinity and nodeSelector to common daemonset config - #2645

Open
amarkdotdev wants to merge 5 commits into
NVIDIA:mainfrom
amarkdotdev:feat/daemonset-affinity-nodeselector-2626
Open

feat: add affinity and nodeSelector to common daemonset config#2645
amarkdotdev wants to merge 5 commits into
NVIDIA:mainfrom
amarkdotdev:feat/daemonset-affinity-nodeselector-2626

Conversation

@amarkdotdev

@amarkdotdev amarkdotdev commented Jul 16, 2026

Copy link
Copy Markdown

Fixes #2626

ClusterPolicy already exposes common tolerations for operand daemonsets but there was no matching knob for affinity or nodeSelector. This adds both under spec.daemonsets and surfaces them in Helm as daemonsets.affinity and daemonsets.nodeSelector.

User nodeSelector labels are merged into the operand nodeSelector, so the existing nvidia.com/gpu.deploy.* labels stay put.

The affinity CRD field is schemaless so we accept a normal Kubernetes affinity object without inlining the full OpenAPI schema into the ClusterPolicy CRD.

Testing

  • go test ./controllers/... -run TestApplyCommonDaemonSetConfig

@copy-pr-bot

copy-pr-bot Bot commented Jul 16, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@amarkdotdev
amarkdotdev force-pushed the feat/daemonset-affinity-nodeselector-2626 branch 3 times, most recently from f0aa669 to 530835d Compare July 21, 2026 19:23
@amarkdotdev
amarkdotdev force-pushed the feat/daemonset-affinity-nodeselector-2626 branch from 530835d to be752b6 Compare July 27, 2026 20:29
@amarkdotdev

Copy link
Copy Markdown
Author

Hey, this is waiting on CI workflow approval / first-time contributor vetting. Could a maintainer kick that off when convenient? Thanks!

@rajathagasthya

Copy link
Copy Markdown
Contributor

/ok-to-test be752b6

@amarkdotdev
amarkdotdev force-pushed the feat/daemonset-affinity-nodeselector-2626 branch from be752b6 to 9efb8b7 Compare July 28, 2026 18:25
@amarkdotdev

Copy link
Copy Markdown
Author

@rajathagasthya Fixed the generated GPUCluster CRDs and rebased the branch onto upstream/main. make check’s generated-assets validation is now clean.

@rajathagasthya

Copy link
Copy Markdown
Contributor

Thanks @amarkdotdev! We are in a bit of a code freeze right now for an upcoming release, so we're only taking release-critical PRs. You can expect this PR to get attention once the release is done.

@amarkdotdev

Copy link
Copy Markdown
Author

@rajathagasthya ok no problem:)

Expose spec.daemonsets.affinity and spec.daemonsets.nodeSelector on
ClusterPolicy and wire them through Helm. User nodeSelector labels are
merged with existing operand nodeSelector entries.

Use a schemaless CRD field for affinity so we do not embed the full
corev1.Affinity OpenAPI schema in the ClusterPolicy CRD.

Signed-off-by: amarkdotdev <amarkdotdev@users.noreply.github.com>


# Conflicts:
#	controllers/transforms_test.go

Signed-off-by: Aaron <amark@g.jct.ac.il>

Signed-off-by: Aaron <amark@g.jct.ac.il>
Regenerate published GPUCluster CRDs for the common daemonset affinity
and nodeSelector API fields.

Signed-off-by: amarkdotdev <amarkdotdev@users.noreply.github.com>

Signed-off-by: Aaron <amark@g.jct.ac.il>
@amarkdotdev
amarkdotdev force-pushed the feat/daemonset-affinity-nodeselector-2626 branch from 9efb8b7 to aebd56c Compare August 29, 2026 18:34
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

ClusterPolicy.spec.daemonsets now supports optional nodeSelector and affinity settings. Helm values provide empty defaults and render configured fields. Common DaemonSet configuration merges node selectors with existing pod selectors and applies configured affinity. Tests cover selector preservation, selector merging, and affinity application.

Merge Risk: 🟡 Moderate · up to aebd5

User-provided nodeSelector values can currently overwrite protected GPU Operator selectors, potentially placing daemonset operands on unsuitable nodes or preventing expected GPU/NFD targeting. Merge should wait until those protected selectors remain authoritative.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: QUIET

Plan: Enterprise

Run ID: 29c358f5-21e9-441c-8a35-005c6985e51e

📥 Commits

Reviewing files that changed from the base of the PR and between fa49ea6 and aebd56c.

⛔ Files ignored due to path filters (7)
  • api/nvidia/v1/zz_generated.deepcopy.go is excluded by !**/zz_generated.*.go
  • bundle/manifests/nvidia.com_clusterpolicies.yaml is excluded by !bundle/manifests/nvidia.com_*.yaml
  • bundle/manifests/nvidia.com_gpuclusters.yaml is excluded by !bundle/manifests/nvidia.com_*.yaml
  • config/crd/bases/nvidia.com_clusterpolicies.yaml is excluded by !config/crd/bases/**
  • config/crd/bases/nvidia.com_gpuclusters.yaml is excluded by !config/crd/bases/**
  • deployments/gpu-operator/crds/nvidia.com_clusterpolicies.yaml is excluded by !deployments/gpu-operator/crds/**
  • deployments/gpu-operator/crds/nvidia.com_gpuclusters.yaml is excluded by !deployments/gpu-operator/crds/**
📒 Files selected for processing (5)
  • api/nvidia/v1/clusterpolicy_types.go
  • controllers/object_controls.go
  • controllers/transforms_test.go
  • deployments/gpu-operator/templates/clusterpolicy.yaml
  • deployments/gpu-operator/values.yaml

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.

Comment thread controllers/object_controls.go
@amarkdotdev

Copy link
Copy Markdown
Author

rebased

Signed-off-by: Aaron <amark@g.jct.ac.il>

@kvalliyurnatt kvalliyurnatt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amarkdotdev Thanks for your contribution. Left a few comments

Comment thread controllers/transforms_test.go Outdated
},
},
},
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a comma missing here

Suggested change
})
}),

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the missing comma

Comment thread controllers/object_controls.go Outdated
obj.Spec.Template.Spec.NodeSelector = make(map[string]string)
}
for key, value := range config.Daemonsets.NodeSelector {
if strings.HasPrefix(key, "nvidia.com/gpu.deploy.") {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still have a few more selectors we want to protect. For example nvidia.com/mps.capable: "true" if overriden can end up placing MPS control daemon on unsuitable nodes. I think we should make sure we protect all operand selectors here. I think we don't want to overwrite any existing NodeSelectors probably right ? maybe we need to keep the user sent node selectors to strictly be additive

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nodeSelector is additive now, existing operand keys stay put

Comment thread controllers/object_controls.go Outdated
}

if config.Daemonsets.Affinity != nil {
obj.Spec.Template.Spec.Affinity = config.Daemonsets.Affinity

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also removes any existing affinity, I think affinity should be merged with existing operand defined affinity here.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

affinity merges with the operand now instead of replacing it

affinity:
description: 'Optional: Set affinity for all Daemonsets'
type: object
x-kubernetes-preserve-unknown-fields: true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand we want affinity to be schema less to prevent pulling in the entire affinity definition, but the way we have it now makes validation difficult, would it be so bad to inline the openAPI spec ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kept it schemaless for now to avoid dragging the full affinity openapi into the crd bundle

Only add nodeSelector keys that are not already set on the operand and merge
cluster policy affinity with existing daemonset affinity.

Signed-off-by: Aaron <amark@g.jct.ac.il>
Comment thread controllers/object_controls.go Outdated
if merged.RequiredDuringSchedulingIgnoredDuringExecution == nil {
merged.RequiredDuringSchedulingIgnoredDuringExecution = src.RequiredDuringSchedulingIgnoredDuringExecution.DeepCopy()
} else {
merged.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms = append(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NodeSelectorTerms are ORed by Kubernetes, so appending the source terms changes the result to existing OR user, which broadens scheduling, I think we want existing AND user to be additive in this case. We would need to do a cartesian product I believe of the existing terms with the new terms to make it additive.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cartesian product on the selector terms now

NodeSelectorTerms are ORed by Kubernetes. Merge existing operand
terms with user terms via cartesian product so constraints are
additive instead of broadening scheduling.

Signed-off-by: Aaron <amark@g.jct.ac.il>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Support affinity / nodeSelector for operand DaemonSets in ClusterPolicy spec.daemonsets

3 participants