Skip to content

Commit 07e29e5

Browse files
authored
Merge pull request #82 from AutuSnow/fix/issue-80-inner_loop_of_preparedDevices
The inner loop of preparedDevices does not filter driver
2 parents 359bc3a + 736eb91 commit 07e29e5

4 files changed

Lines changed: 137 additions & 0 deletions

File tree

pkg/driver/dra_hooks.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,9 @@ func (cp *CPUDriver) prepareGroupedResourceClaim(ctx context.Context, claim *res
347347
klog.Infof("prepareResourceClaim CDIDeviceName:%s envVar:%s qualifiedName:%v", deviceName, envVar, qualifiedName)
348348
preparedDevices := []kubeletplugin.Device{}
349349
for _, allocResult := range claim.Status.Allocation.Devices.Results {
350+
if allocResult.Driver != cp.driverName {
351+
continue
352+
}
350353
preparedDevice := kubeletplugin.Device{
351354
PoolName: allocResult.Pool,
352355
DeviceName: allocResult.Device,
@@ -402,6 +405,9 @@ func (cp *CPUDriver) prepareResourceClaim(_ context.Context, claim *resourceapi.
402405
klog.Infof("prepareResourceClaim CDIDeviceName:%s envVar:%s qualifiedName:%v", deviceName, envVar, qualifiedName)
403406
preparedDevices := []kubeletplugin.Device{}
404407
for _, allocResult := range claim.Status.Allocation.Devices.Results {
408+
if allocResult.Driver != cp.driverName {
409+
continue
410+
}
405411
preparedDevice := kubeletplugin.Device{
406412
PoolName: allocResult.Pool,
407413
DeviceName: allocResult.Device,

pkg/driver/dra_hooks_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,33 @@ func TestPrepareResourceClaims(t *testing.T) {
540540
expectedResultsCount: 1,
541541
expectedError: true,
542542
},
543+
{
544+
name: "multi-driver claim - only our devices in preparedDevices",
545+
driver: baseCPUDriver(),
546+
claims: []*resourceapi.ResourceClaim{
547+
{
548+
ObjectMeta: metav1.ObjectMeta{UID: claimUID, Name: "my-claim"},
549+
Status: resourceapi.ResourceClaimStatus{
550+
Allocation: &resourceapi.AllocationResult{
551+
Devices: resourceapi.DeviceAllocationResult{
552+
Results: []resourceapi.DeviceRequestAllocationResult{
553+
{Driver: testDriverName, Pool: testNodeName, Device: "cpudev0"},
554+
{Driver: "other-driver", Pool: testNodeName, Device: "other-device"},
555+
},
556+
},
557+
},
558+
},
559+
},
560+
},
561+
expectedResultsCount: 1,
562+
expectedCdiDevicesCount: 1,
563+
expectedCdiDevice: cdiDeviceName,
564+
expectedCdiEnvVar: fmt.Sprintf("%s_%s=%s", cdiEnvVarPrefix, claimUID, "0"),
565+
// only our driver's device should appear in preparedDevices
566+
expectedPreparedDevices: []kubeletplugin.Device{
567+
{PoolName: testNodeName, DeviceName: "cpudev0", CDIDeviceIDs: []string{cdiQualifiedName}},
568+
},
569+
},
543570
}
544571

545572
for _, tc := range testCases {

test/e2e/cpu_assignment_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/onsi/gomega"
3232
v1 "k8s.io/api/core/v1"
3333
resourcev1 "k8s.io/api/resource/v1"
34+
"k8s.io/apimachinery/pkg/api/resource"
3435
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3536
"k8s.io/utils/cpuset"
3637
)
@@ -233,6 +234,65 @@ var _ = ginkgo.Describe("CPU Allocation", ginkgo.Serial, ginkgo.Ordered, ginkgo.
233234
verifySharedPoolMatches(ctx, fxt, shrPod1, availableCPUs)
234235
verifySharedPoolMatches(ctx, fxt, shrPod2, availableCPUs)
235236
})
237+
238+
ginkgo.It("should allocate non-overlapping CPUs for multiple requests in the same grouped claim", func(ctx context.Context) {
239+
if cpuDeviceMode != "grouped" {
240+
ginkgo.Skip("this test only applies to grouped CPU device mode")
241+
}
242+
if availableCPUs.Size() < 2 {
243+
ginkgo.Skip("need at least 2 available CPUs for this test")
244+
}
245+
246+
fixture.By("creating a ResourceClaim with two requests each asking for 1 CPU")
247+
cpuClaim := &resourcev1.ResourceClaim{
248+
ObjectMeta: metav1.ObjectMeta{
249+
Namespace: fxt.Namespace.Name,
250+
GenerateName: "claim-multi-request-",
251+
},
252+
Spec: resourcev1.ResourceClaimSpec{
253+
Devices: resourcev1.DeviceClaim{
254+
Requests: []resourcev1.DeviceRequest{
255+
{
256+
Name: "request-0",
257+
Exactly: &resourcev1.ExactDeviceRequest{
258+
DeviceClassName: "dra.cpu",
259+
Capacity: &resourcev1.CapacityRequirements{
260+
Requests: map[resourcev1.QualifiedName]resource.Quantity{
261+
"dra.cpu/cpu": *resource.NewQuantity(1, resource.DecimalSI),
262+
},
263+
},
264+
},
265+
},
266+
{
267+
Name: "request-1",
268+
Exactly: &resourcev1.ExactDeviceRequest{
269+
DeviceClassName: "dra.cpu",
270+
Capacity: &resourcev1.CapacityRequirements{
271+
Requests: map[resourcev1.QualifiedName]resource.Quantity{
272+
"dra.cpu/cpu": *resource.NewQuantity(1, resource.DecimalSI),
273+
},
274+
},
275+
},
276+
},
277+
},
278+
},
279+
},
280+
}
281+
createdClaim, err := fxt.K8SClientset.ResourceV1().ResourceClaims(fxt.Namespace.Name).Create(ctx, cpuClaim, metav1.CreateOptions{})
282+
gomega.Expect(err).ToNot(gomega.HaveOccurred())
283+
284+
fixture.By("creating a pod consuming the multi-request claim")
285+
pod := makeTesterPodWithNamedClaim(fxt.Namespace.Name, dracpuTesterImage, createdClaim.Name, targetNode.Name)
286+
createdPod, err := e2epod.CreateSync(ctx, fxt.K8SClientset, pod)
287+
gomega.Expect(err).ToNot(gomega.HaveOccurred())
288+
289+
fixture.By("verifying the pod got 2 distinct CPUs with no overlap")
290+
alloc := getTesterPodCPUAllocation(fxt.K8SClientset, ctx, createdPod)
291+
fxt.Log.Info("multi-request claim allocation", "cpuAssigned", alloc.CPUAssigned.String())
292+
gomega.Expect(alloc.CPUAssigned.Size()).To(gomega.Equal(2), "expected 2 distinct CPUs allocated")
293+
gomega.Expect(alloc.CPUAssigned.IsSubsetOf(availableCPUs)).To(gomega.BeTrue(), "allocated CPUs must be within available set")
294+
295+
})
236296
})
237297
})
238298
})

test/e2e/e2e_suite_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,50 @@ func parseCPUDeviceModeArg(arg string) (string, bool) {
212212
return strings.TrimPrefix(arg, prefix), true
213213
}
214214

215+
func makeTesterPodWithNamedClaim(ns, image, claimName string, nodeName string) *v1.Pod {
216+
ginkgo.GinkgoHelper()
217+
cpuQty := resource.NewQuantity(2, resource.DecimalSI)
218+
memQty, err := resource.ParseQuantity("256Mi")
219+
gomega.Expect(err).ToNot(gomega.HaveOccurred())
220+
221+
pod := &v1.Pod{
222+
ObjectMeta: metav1.ObjectMeta{
223+
GenerateName: "tester-pod-named-claim-",
224+
Namespace: ns,
225+
},
226+
Spec: v1.PodSpec{
227+
Containers: []v1.Container{
228+
{
229+
Name: "tester-container-1",
230+
Image: image,
231+
Command: []string{"/dracputester"},
232+
Resources: v1.ResourceRequirements{
233+
Requests: v1.ResourceList{
234+
v1.ResourceCPU: *cpuQty,
235+
v1.ResourceMemory: memQty,
236+
},
237+
Limits: v1.ResourceList{
238+
v1.ResourceCPU: *cpuQty,
239+
v1.ResourceMemory: memQty,
240+
},
241+
Claims: []v1.ResourceClaim{
242+
{Name: "cpu-claim"},
243+
},
244+
},
245+
},
246+
},
247+
ResourceClaims: []v1.PodResourceClaim{
248+
{
249+
Name: "cpu-claim",
250+
ResourceClaimName: ptr.To(claimName),
251+
},
252+
},
253+
RestartPolicy: v1.RestartPolicyAlways,
254+
},
255+
}
256+
return e2epod.PinToNode(pod, nodeName)
257+
}
258+
215259
func makeResourceClaimSpec(cpus int, isConsumable bool) resourcev1.ResourceClaimSpec {
216260
if !isConsumable {
217261
return resourcev1.ResourceClaimSpec{

0 commit comments

Comments
 (0)