Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cmd/gpu-operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ func gpuPodSpecFilter(ctx context.Context, c client.Reader) func(pod corev1.Pod)
return true
}
}
// Native sidecars (init containers with restartPolicy Always) run for the
// pod's lifetime, so their GPU resources must be considered. Regular init
// containers are not checked here.
for _, ctr := range pod.Spec.InitContainers {
if ctr.RestartPolicy != nil && *ctr.RestartPolicy == corev1.ContainerRestartPolicyAlways &&
(gpuInResourceList(ctr.Resources.Limits) || gpuInResourceList(ctr.Resources.Requests)) {
return true
}
}
return controllers.PodHasNVIDIAGPUClaim(ctx, c, &pod, false)
}
}
44 changes: 43 additions & 1 deletion cmd/gpu-operator/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,20 @@ func gpuContainer(limits, requests corev1.ResourceList) corev1.Container {
return corev1.Container{Resources: corev1.ResourceRequirements{Limits: limits, Requests: requests}}
}

func nativeSidecar(limits, requests corev1.ResourceList) corev1.Container {
ctr := gpuContainer(limits, requests)
ctr.RestartPolicy = new(corev1.ContainerRestartPolicyAlways)
return ctr
}

func podWithInitContainer(phase corev1.PodPhase, initContainer corev1.Container) corev1.Pod {
pod := resourcePod(phase, gpuContainer(corev1.ResourceList{"cpu": {}}, nil))
pod.Spec.InitContainers = []corev1.Container{initContainer}
return pod
}

// TestGPUPodSpecFilterResourceList covers the container resource-list branch of
// gpuPodSpecFilter (nvidia.com/gpu and nvidia.com/mig- in a container's
// gpuPodSpecFilter (nvidia.com/gpu and nvidia.com/mig- in app/native sidecar
// limits/requests, plus the Running/Pending phase gate). The sibling
// TestGPUPodSpecFilterResourceClaims only exercises the DRA/ResourceClaims
// branch, leaving this branch uncovered.
Expand Down Expand Up @@ -196,6 +208,36 @@ func TestGPUPodSpecFilterResourceList(t *testing.T) {
pod: resourcePod(corev1.PodSucceeded, gpuContainer(corev1.ResourceList{"nvidia.com/gpu": {}}, nil)),
wantGPUPod: false,
},
{
name: "running pod with GPU limit only in native sidecar -> GPU pod",
pod: podWithInitContainer(corev1.PodRunning, nativeSidecar(corev1.ResourceList{"nvidia.com/gpu": {}}, nil)),
wantGPUPod: true,
},
{
name: "pending pod with GPU request only in native sidecar -> GPU pod",
pod: podWithInitContainer(corev1.PodPending, nativeSidecar(nil, corev1.ResourceList{"nvidia.com/gpu": {}})),
wantGPUPod: true,
},
{
name: "running pod with MIG request only in native sidecar -> GPU pod",
pod: podWithInitContainer(corev1.PodRunning, nativeSidecar(nil, corev1.ResourceList{"nvidia.com/mig-1g.5gb": {}})),
wantGPUPod: true,
},
{
name: "running pod with GPU limit only in regular init container -> not a GPU pod",
pod: podWithInitContainer(corev1.PodRunning, gpuContainer(corev1.ResourceList{"nvidia.com/gpu": {}}, nil)),
wantGPUPod: false,
},
{
name: "running pod with CPU only in native sidecar -> not a GPU pod",
pod: podWithInitContainer(corev1.PodRunning, nativeSidecar(corev1.ResourceList{"cpu": {}}, nil)),
wantGPUPod: false,
},
{
name: "succeeded pod with GPU limit only in native sidecar -> not a GPU pod",
pod: podWithInitContainer(corev1.PodSucceeded, nativeSidecar(corev1.ResourceList{"nvidia.com/gpu": {}}, nil)),
wantGPUPod: false,
},
}

for _, tc := range testCases {
Expand Down
Loading