DRA kubelet: adapt to v1alpha3 API

This adds the ability to select specific requests inside a claim for a
container.

NodePrepareResources is always called, even if the claim is not used by any
container. This could be useful for drivers where that call has some effect
other than injecting CDI device IDs into containers. It also ensures that
drivers can validate configs.

The pod resource API can no longer report a class for each claim because there
is no such 1:1 relationship anymore. Instead, that API reports claim,
API devices (with driver/pool/device as ID) and CDI device IDs. The kubelet
itself doesn't extract that information from the claim. Instead, it relies on
drivers to report this information when the claim gets prepared. This isolates
the kubelet from API changes.

Because of a faulty E2E test, kubelet was told to contact the wrong driver for
a claim. This was not visible in the kubelet log output. Now changes to the
claim info cache are getting logged. While at it, naming of variables and some
existing log output gets harmonized.

Co-authored-by: Oksana Baranova <oksana.baranova@intel.com>
Co-authored-by: Ed Bartosh <eduard.bartosh@intel.com>
This commit is contained in:
Patrick Ohly
2024-07-17 15:09:02 +02:00
parent 20f98f3a2f
commit 877829aeaa
19 changed files with 1515 additions and 1842 deletions

View File

@@ -85,12 +85,14 @@ func TestListPodResourcesV1(t *testing.T) {
} }
pluginCDIDevices := []*podresourcesapi.CDIDevice{{Name: "dra-dev0"}, {Name: "dra-dev1"}} pluginCDIDevices := []*podresourcesapi.CDIDevice{{Name: "dra-dev0"}, {Name: "dra-dev1"}}
draDriverName := "dra.example.com"
poolName := "worker-1-pool"
deviceName := "gpu-1"
draDevs := []*podresourcesapi.DynamicResource{ draDevs := []*podresourcesapi.DynamicResource{
{ {
ClassName: "resource-class",
ClaimName: "claim-name", ClaimName: "claim-name",
ClaimNamespace: "default", ClaimNamespace: "default",
ClaimResources: []*podresourcesapi.ClaimResource{{CDIDevices: pluginCDIDevices}}, ClaimResources: []*podresourcesapi.ClaimResource{{CDIDevices: pluginCDIDevices, DriverName: draDriverName, PoolName: poolName, DeviceName: deviceName}},
}, },
} }
@@ -893,7 +895,6 @@ func TestGetPodResourcesV1(t *testing.T) {
pluginCDIDevices := []*podresourcesapi.CDIDevice{{Name: "dra-dev0"}, {Name: "dra-dev1"}} pluginCDIDevices := []*podresourcesapi.CDIDevice{{Name: "dra-dev0"}, {Name: "dra-dev1"}}
draDevs := []*podresourcesapi.DynamicResource{ draDevs := []*podresourcesapi.DynamicResource{
{ {
ClassName: "resource-class",
ClaimName: "claim-name", ClaimName: "claim-name",
ClaimNamespace: "default", ClaimNamespace: "default",
ClaimResources: []*podresourcesapi.ClaimResource{{CDIDevices: pluginCDIDevices}}, ClaimResources: []*podresourcesapi.ClaimResource{{CDIDevices: pluginCDIDevices}},

View File

@@ -661,10 +661,6 @@ func (cm *containerManagerImpl) GetResources(pod *v1.Pod, container *v1.Containe
if err != nil { if err != nil {
return nil, err return nil, err
} }
// NOTE: Passing CDI device names as annotations is a temporary solution
// It will be removed after all runtimes are updated
// to get CDI device names from the ContainerConfig.CDIDevices field
opts.Annotations = append(opts.Annotations, resOpts.Annotations...)
opts.CDIDevices = append(opts.CDIDevices, resOpts.CDIDevices...) opts.CDIDevices = append(opts.CDIDevices, resOpts.CDIDevices...)
} }
// Allocate should already be called during predicateAdmitHandler.Admit(), // Allocate should already be called during predicateAdmitHandler.Admit(),
@@ -965,19 +961,22 @@ func (cm *containerManagerImpl) GetDynamicResources(pod *v1.Pod, container *v1.C
} }
for _, containerClaimInfo := range containerClaimInfos { for _, containerClaimInfo := range containerClaimInfos {
var claimResources []*podresourcesapi.ClaimResource var claimResources []*podresourcesapi.ClaimResource
// TODO: Currently we maintain a list of ClaimResources, each of which contains for driverName, driverState := range containerClaimInfo.DriverState {
// a set of CDIDevices from a different kubelet plugin. In the future we may want to
// include the name of the kubelet plugin and/or other types of resources that are
// not CDIDevices (assuming the DRAmanager supports this).
for _, klPluginCdiDevices := range containerClaimInfo.CDIDevices {
var cdiDevices []*podresourcesapi.CDIDevice var cdiDevices []*podresourcesapi.CDIDevice
for _, cdiDevice := range klPluginCdiDevices { for _, device := range driverState.Devices {
cdiDevices = append(cdiDevices, &podresourcesapi.CDIDevice{Name: cdiDevice}) for _, cdiDeviceID := range device.CDIDeviceIDs {
cdiDevices = append(cdiDevices, &podresourcesapi.CDIDevice{Name: cdiDeviceID})
}
resources := &podresourcesapi.ClaimResource{
CDIDevices: cdiDevices,
DriverName: driverName,
PoolName: device.PoolName,
DeviceName: device.DeviceName,
}
claimResources = append(claimResources, resources)
} }
claimResources = append(claimResources, &podresourcesapi.ClaimResource{CDIDevices: cdiDevices})
} }
containerDynamicResource := podresourcesapi.DynamicResource{ containerDynamicResource := podresourcesapi.DynamicResource{
ClassName: containerClaimInfo.ClassName,
ClaimName: containerClaimInfo.ClaimName, ClaimName: containerClaimInfo.ClaimName,
ClaimNamespace: containerClaimInfo.Namespace, ClaimNamespace: containerClaimInfo.Namespace,
ClaimResources: claimResources, ClaimResources: claimResources,

View File

@@ -17,14 +17,15 @@ limitations under the License.
package dra package dra
import ( import (
"errors"
"fmt" "fmt"
"slices"
"sync" "sync"
resourceapi "k8s.io/api/resource/v1alpha3" resourceapi "k8s.io/api/resource/v1alpha3"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/kubelet/cm/dra/state" "k8s.io/kubernetes/pkg/kubelet/cm/dra/state"
"k8s.io/kubernetes/pkg/kubelet/cm/util/cdi"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
) )
@@ -33,10 +34,7 @@ import (
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
type ClaimInfo struct { type ClaimInfo struct {
state.ClaimInfoState state.ClaimInfoState
// annotations is a mapping of container annotations per DRA plugin associated with prepared bool
// a prepared resource
annotations map[string][]kubecontainer.Annotation
prepared bool
} }
// claimInfoCache is a cache of processed resource claims keyed by namespace/claimname. // claimInfoCache is a cache of processed resource claims keyed by namespace/claimname.
@@ -47,89 +45,45 @@ type claimInfoCache struct {
} }
// newClaimInfoFromClaim creates a new claim info from a resource claim. // newClaimInfoFromClaim creates a new claim info from a resource claim.
func newClaimInfoFromClaim(claim *resourceapi.ResourceClaim) *ClaimInfo { // It verifies that the kubelet can handle the claim.
// Grab the allocation.resourceHandles. If there are no func newClaimInfoFromClaim(claim *resourceapi.ResourceClaim) (*ClaimInfo, error) {
// allocation.resourceHandles, create a single resourceHandle with no
// content. This will trigger processing of this claim by a single
// kubelet plugin whose name matches resourceClaim.Status.DriverName.
resourceHandles := claim.Status.Allocation.ResourceHandles
if len(resourceHandles) == 0 {
resourceHandles = make([]resourceapi.ResourceHandle, 1)
}
claimInfoState := state.ClaimInfoState{ claimInfoState := state.ClaimInfoState{
DriverName: claim.Status.DriverName, ClaimUID: claim.UID,
ClassName: claim.Spec.ResourceClassName, ClaimName: claim.Name,
ClaimUID: claim.UID, Namespace: claim.Namespace,
ClaimName: claim.Name, PodUIDs: sets.New[string](),
Namespace: claim.Namespace, DriverState: make(map[string]state.DriverState),
PodUIDs: sets.New[string](), }
ResourceHandles: resourceHandles, if claim.Status.Allocation == nil {
CDIDevices: make(map[string][]string), return nil, errors.New("not allocated")
}
for _, result := range claim.Status.Allocation.Devices.Results {
claimInfoState.DriverState[result.Driver] = state.DriverState{}
} }
info := &ClaimInfo{ info := &ClaimInfo{
ClaimInfoState: claimInfoState, ClaimInfoState: claimInfoState,
annotations: make(map[string][]kubecontainer.Annotation),
prepared: false, prepared: false,
} }
return info return info, nil
} }
// newClaimInfoFromClaim creates a new claim info from a checkpointed claim info state object. // newClaimInfoFromClaim creates a new claim info from a checkpointed claim info state object.
func newClaimInfoFromState(state *state.ClaimInfoState) *ClaimInfo { func newClaimInfoFromState(state *state.ClaimInfoState) *ClaimInfo {
info := &ClaimInfo{ info := &ClaimInfo{
ClaimInfoState: *state.DeepCopy(), ClaimInfoState: *state.DeepCopy(),
annotations: make(map[string][]kubecontainer.Annotation),
prepared: false, prepared: false,
} }
for pluginName, devices := range info.CDIDevices {
annotations, _ := cdi.GenerateAnnotations(info.ClaimUID, info.DriverName, devices)
info.annotations[pluginName] = append(info.annotations[pluginName], annotations...)
}
return info return info
} }
// setCDIDevices adds a set of CDI devices to the claim info. // setCDIDevices adds a set of CDI devices to the claim info.
func (info *ClaimInfo) setCDIDevices(pluginName string, cdiDevices []string) error { func (info *ClaimInfo) addDevice(driverName string, device state.Device) {
// NOTE: Passing CDI device names as annotations is a temporary solution if info.DriverState == nil {
// It will be removed after all runtimes are updated info.DriverState = make(map[string]state.DriverState)
// to get CDI device names from the ContainerConfig.CDIDevices field
annotations, err := cdi.GenerateAnnotations(info.ClaimUID, info.DriverName, cdiDevices)
if err != nil {
return fmt.Errorf("failed to generate container annotations, err: %+v", err)
} }
driverState := info.DriverState[driverName]
if info.CDIDevices == nil { driverState.Devices = append(driverState.Devices, device)
info.CDIDevices = make(map[string][]string) info.DriverState[driverName] = driverState
}
if info.annotations == nil {
info.annotations = make(map[string][]kubecontainer.Annotation)
}
info.CDIDevices[pluginName] = cdiDevices
info.annotations[pluginName] = annotations
return nil
}
// annotationsAsList returns container annotations as a single list.
func (info *ClaimInfo) annotationsAsList() []kubecontainer.Annotation {
var lst []kubecontainer.Annotation
for _, v := range info.annotations {
lst = append(lst, v...)
}
return lst
}
// cdiDevicesAsList returns a list of CDIDevices from the provided claim info.
func (info *ClaimInfo) cdiDevicesAsList() []kubecontainer.CDIDevice {
var cdiDevices []kubecontainer.CDIDevice
for _, devices := range info.CDIDevices {
for _, device := range devices {
cdiDevices = append(cdiDevices, kubecontainer.CDIDevice{Name: device})
}
}
return cdiDevices
} }
// addPodReference adds a pod reference to the claim info. // addPodReference adds a pod reference to the claim info.
@@ -240,3 +194,20 @@ func (cache *claimInfoCache) syncToCheckpoint() error {
} }
return cache.state.Store(claimInfoStateList) return cache.state.Store(claimInfoStateList)
} }
// cdiDevicesAsList returns a list of CDIDevices from the provided claim info.
// When the request name is non-empty, only devices relevant for that request
// are returned.
func (info *ClaimInfo) cdiDevicesAsList(requestName string) []kubecontainer.CDIDevice {
var cdiDevices []kubecontainer.CDIDevice
for _, driverData := range info.DriverState {
for _, device := range driverData.Devices {
if requestName == "" || len(device.RequestNames) == 0 || slices.Contains(device.RequestNames, requestName) {
for _, cdiDeviceID := range device.CDIDeviceIDs {
cdiDevices = append(cdiDevices, kubecontainer.CDIDevice{Name: cdiDeviceID})
}
}
}
}
return cdiDevices
}

View File

@@ -18,30 +18,46 @@ package dra
import ( import (
"errors" "errors"
"fmt"
"path" "path"
"reflect" "reflect"
"sort"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
resourceapi "k8s.io/api/resource/v1alpha3" resourceapi "k8s.io/api/resource/v1alpha3"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/kubelet/cm/dra/state" "k8s.io/kubernetes/pkg/kubelet/cm/dra/state"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
) )
// ClaimInfo test cases // ClaimInfo test cases
func TestNewClaimInfoFromClaim(t *testing.T) { const (
namespace := "test-namespace" namespace = "test-namespace"
className := "test-class" className = "test-class"
driverName := "test-plugin" driverName = "test-driver"
claimUID := types.UID("claim-uid") deviceName = "test-device" // name inside ResourceSlice
claimName := "test-claim" cdiDeviceName = "cdi-test-device" // name inside CDI spec
cdiID = "test-driver/test=cdi-test-device" // CDI device ID
poolName = "test-pool"
requestName = "test-request"
claimName = "test-claim"
claimUID = types.UID(claimName + "-uid")
podUID = "test-pod-uid"
)
var (
device = state.Device{
PoolName: poolName,
DeviceName: deviceName,
RequestNames: []string{requestName},
CDIDeviceIDs: []string{cdiID},
}
devices = []state.Device{device}
)
func TestNewClaimInfoFromClaim(t *testing.T) {
for _, test := range []struct { for _, test := range []struct {
description string description string
claim *resourceapi.ResourceClaim claim *resourceapi.ResourceClaim
@@ -56,28 +72,41 @@ func TestNewClaimInfoFromClaim(t *testing.T) {
Namespace: namespace, Namespace: namespace,
}, },
Status: resourceapi.ResourceClaimStatus{ Status: resourceapi.ResourceClaimStatus{
DriverName: driverName,
Allocation: &resourceapi.AllocationResult{ Allocation: &resourceapi.AllocationResult{
ResourceHandles: []resourceapi.ResourceHandle{}, Devices: resourceapi.DeviceAllocationResult{
Results: []resourceapi.DeviceRequestAllocationResult{
{
Request: requestName,
Pool: poolName,
Device: deviceName,
Driver: driverName,
},
},
},
}, },
}, },
Spec: resourceapi.ResourceClaimSpec{ Spec: resourceapi.ResourceClaimSpec{
ResourceClassName: className, Devices: resourceapi.DeviceClaim{
Requests: []resourceapi.DeviceRequest{
{
Name: requestName,
DeviceClassName: className,
},
},
},
}, },
}, },
expectedResult: &ClaimInfo{ expectedResult: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
DriverName: driverName, ClaimUID: claimUID,
ClassName: className, ClaimName: claimName,
ClaimUID: claimUID, Namespace: namespace,
ClaimName: claimName, PodUIDs: sets.New[string](),
Namespace: claimName, DriverState: map[string]state.DriverState{
PodUIDs: sets.New[string](), driverName: {},
ResourceHandles: []resourceapi.ResourceHandle{
{},
}, },
CDIDevices: make(map[string][]string),
}, },
prepared: false,
}, },
}, },
{ {
@@ -89,33 +118,29 @@ func TestNewClaimInfoFromClaim(t *testing.T) {
Namespace: namespace, Namespace: namespace,
}, },
Status: resourceapi.ResourceClaimStatus{ Status: resourceapi.ResourceClaimStatus{
DriverName: driverName,
Allocation: &resourceapi.AllocationResult{}, Allocation: &resourceapi.AllocationResult{},
}, },
Spec: resourceapi.ResourceClaimSpec{ Spec: resourceapi.ResourceClaimSpec{},
ResourceClassName: className,
},
}, },
expectedResult: &ClaimInfo{ expectedResult: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
DriverName: driverName, ClaimUID: claimUID,
ClassName: className, ClaimName: claimName,
ClaimUID: claimUID, Namespace: namespace,
ClaimName: claimName, PodUIDs: sets.New[string](),
Namespace: claimName, DriverState: map[string]state.DriverState{},
PodUIDs: sets.New[string](),
ResourceHandles: []resourceapi.ResourceHandle{
{},
},
CDIDevices: make(map[string][]string),
}, },
prepared: false,
}, },
}, },
} { } {
t.Run(test.description, func(t *testing.T) { t.Run(test.description, func(t *testing.T) {
result := newClaimInfoFromClaim(test.claim) result, err := newClaimInfoFromClaim(test.claim)
if reflect.DeepEqual(result, test.expectedResult) { if err != nil {
t.Errorf("Expected %v, but got %v", test.expectedResult, result) t.Errorf("Unexpected error: %v", err)
}
if !reflect.DeepEqual(test.expectedResult, result) {
t.Errorf("Expected %+v, but got %+v", test.expectedResult, result)
} }
}) })
} }
@@ -130,237 +155,95 @@ func TestNewClaimInfoFromState(t *testing.T) {
{ {
description: "successfully created object", description: "successfully created object",
state: &state.ClaimInfoState{ state: &state.ClaimInfoState{
DriverName: "test-driver", ClaimUID: claimUID,
ClassName: "test-class", ClaimName: claimName,
ClaimUID: "test-uid", Namespace: namespace,
ClaimName: "test-claim", PodUIDs: sets.New[string](podUID),
Namespace: "test-namespace", DriverState: map[string]state.DriverState{
PodUIDs: sets.New[string]("test-pod-uid"), driverName: {
ResourceHandles: []resourceapi.ResourceHandle{}, Devices: devices,
CDIDevices: map[string][]string{}, },
},
},
expectedResult: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{
ClaimUID: claimUID,
ClaimName: claimName,
Namespace: namespace,
PodUIDs: sets.New[string](podUID),
DriverState: map[string]state.DriverState{
driverName: {
Devices: devices,
},
},
},
prepared: false,
}, },
}, },
} { } {
t.Run(test.description, func(t *testing.T) { t.Run(test.description, func(t *testing.T) {
result := newClaimInfoFromState(test.state) result := newClaimInfoFromState(test.state)
if reflect.DeepEqual(result, test.expectedResult) { if !reflect.DeepEqual(result, test.expectedResult) {
t.Errorf("Expected %v, but got %v", test.expectedResult, result) t.Errorf("Expected %+v, but got %+v", test.expectedResult, result)
} }
}) })
} }
} }
func TestClaimInfoSetCDIDevices(t *testing.T) { func TestClaimInfoAddDevice(t *testing.T) {
claimUID := types.UID("claim-uid")
pluginName := "test-plugin"
device := "vendor.com/device=device1"
annotationName := fmt.Sprintf("cdi.k8s.io/%s_%s", pluginName, claimUID)
for _, test := range []struct { for _, test := range []struct {
description string description string
claimInfo *ClaimInfo claimInfo *ClaimInfo
devices []string device state.Device
expectedCDIDevices map[string][]string
expectedAnnotations map[string][]kubecontainer.Annotation
wantErr bool
}{ }{
{ {
description: "successfully add one device", description: "add new device",
claimInfo: &ClaimInfo{ claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
DriverName: pluginName, ClaimUID: claimUID,
ClaimUID: claimUID, ClaimName: claimName,
}, Namespace: namespace,
}, PodUIDs: sets.New[string](podUID),
devices: []string{device},
expectedCDIDevices: map[string][]string{
pluginName: {device},
},
expectedAnnotations: map[string][]kubecontainer.Annotation{
pluginName: {
{
Name: annotationName,
Value: device,
},
}, },
prepared: false,
}, },
device: device,
}, },
{ {
description: "empty list of devices", description: "other new device",
claimInfo: &ClaimInfo{ claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
DriverName: pluginName, ClaimUID: claimUID,
ClaimUID: claimUID, ClaimName: claimName,
Namespace: namespace,
PodUIDs: sets.New[string](podUID),
}, },
}, },
devices: []string{}, device: func() state.Device {
expectedCDIDevices: map[string][]string{pluginName: {}}, device := device
expectedAnnotations: map[string][]kubecontainer.Annotation{pluginName: nil}, device.PoolName += "-2"
}, device.DeviceName += "-2"
{ device.RequestNames = []string{device.RequestNames[0] + "-2"}
description: "incorrect device format", device.CDIDeviceIDs = []string{device.CDIDeviceIDs[0] + "-2"}
claimInfo: &ClaimInfo{ return device
ClaimInfoState: state.ClaimInfoState{ }(),
DriverName: pluginName,
ClaimUID: claimUID,
},
},
devices: []string{"incorrect"},
wantErr: true,
}, },
} { } {
t.Run(test.description, func(t *testing.T) { t.Run(test.description, func(t *testing.T) {
err := test.claimInfo.setCDIDevices(pluginName, test.devices) test.claimInfo.addDevice(driverName, test.device)
if test.wantErr { assert.Equal(t, []state.Device{test.device}, test.claimInfo.DriverState[driverName].Devices)
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.Equal(t, test.expectedCDIDevices, test.claimInfo.CDIDevices)
assert.Equal(t, test.expectedAnnotations, test.claimInfo.annotations)
}) })
} }
} }
func TestClaimInfoAnnotationsAsList(t *testing.T) {
for _, test := range []struct {
description string
claimInfo *ClaimInfo
expectedResult []kubecontainer.Annotation
}{
{
description: "empty annotations",
claimInfo: &ClaimInfo{
annotations: map[string][]kubecontainer.Annotation{},
},
},
{
description: "nil annotations",
claimInfo: &ClaimInfo{},
},
{
description: "valid annotations",
claimInfo: &ClaimInfo{
annotations: map[string][]kubecontainer.Annotation{
"test-plugin1": {
{
Name: "cdi.k8s.io/test-plugin1_claim-uid1",
Value: "vendor.com/device=device1",
},
{
Name: "cdi.k8s.io/test-plugin1_claim-uid2",
Value: "vendor.com/device=device2",
},
},
"test-plugin2": {
{
Name: "cdi.k8s.io/test-plugin2_claim-uid1",
Value: "vendor.com/device=device1",
},
{
Name: "cdi.k8s.io/test-plugin2_claim-uid2",
Value: "vendor.com/device=device2",
},
},
},
},
expectedResult: []kubecontainer.Annotation{
{
Name: "cdi.k8s.io/test-plugin1_claim-uid1",
Value: "vendor.com/device=device1",
},
{
Name: "cdi.k8s.io/test-plugin1_claim-uid2",
Value: "vendor.com/device=device2",
},
{
Name: "cdi.k8s.io/test-plugin2_claim-uid1",
Value: "vendor.com/device=device1",
},
{
Name: "cdi.k8s.io/test-plugin2_claim-uid2",
Value: "vendor.com/device=device2",
},
},
},
} {
t.Run(test.description, func(t *testing.T) {
result := test.claimInfo.annotationsAsList()
sort.Slice(result, func(i, j int) bool {
return result[i].Name < result[j].Name
})
assert.Equal(t, test.expectedResult, result)
})
}
}
func TestClaimInfoCDIdevicesAsList(t *testing.T) {
for _, test := range []struct {
description string
claimInfo *ClaimInfo
expectedResult []kubecontainer.CDIDevice
}{
{
description: "empty CDI devices",
claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{
CDIDevices: map[string][]string{},
},
},
},
{
description: "nil CDI devices",
claimInfo: &ClaimInfo{},
},
{
description: "valid CDI devices",
claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{
CDIDevices: map[string][]string{
"test-plugin1": {
"vendor.com/device=device1",
"vendor.com/device=device2",
},
"test-plugin2": {
"vendor.com/device=device1",
"vendor.com/device=device2",
},
},
},
},
expectedResult: []kubecontainer.CDIDevice{
{
Name: "vendor.com/device=device1",
},
{
Name: "vendor.com/device=device1",
},
{
Name: "vendor.com/device=device2",
},
{
Name: "vendor.com/device=device2",
},
},
},
} {
t.Run(test.description, func(t *testing.T) {
result := test.claimInfo.cdiDevicesAsList()
sort.Slice(result, func(i, j int) bool {
return result[i].Name < result[j].Name
})
assert.Equal(t, test.expectedResult, result)
})
}
}
func TestClaimInfoAddPodReference(t *testing.T) { func TestClaimInfoAddPodReference(t *testing.T) {
podUID := types.UID("pod-uid")
for _, test := range []struct { for _, test := range []struct {
description string description string
claimInfo *ClaimInfo claimInfo *ClaimInfo
expectedLen int expectedLen int
}{ }{
{ {
description: "successfully add pod reference", description: "empty PodUIDs list",
claimInfo: &ClaimInfo{ claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
PodUIDs: sets.New[string](), PodUIDs: sets.New[string](),
@@ -369,16 +252,16 @@ func TestClaimInfoAddPodReference(t *testing.T) {
expectedLen: 1, expectedLen: 1,
}, },
{ {
description: "duplicate pod reference", description: "first pod reference",
claimInfo: &ClaimInfo{ claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
PodUIDs: sets.New[string](string(podUID)), PodUIDs: sets.New[string](podUID),
}, },
}, },
expectedLen: 1, expectedLen: 1,
}, },
{ {
description: "duplicate pod reference", description: "second pod reference",
claimInfo: &ClaimInfo{ claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
PodUIDs: sets.New[string]("pod-uid1"), PodUIDs: sets.New[string]("pod-uid1"),
@@ -396,7 +279,6 @@ func TestClaimInfoAddPodReference(t *testing.T) {
} }
func TestClaimInfoHasPodReference(t *testing.T) { func TestClaimInfoHasPodReference(t *testing.T) {
podUID := types.UID("pod-uid")
for _, test := range []struct { for _, test := range []struct {
description string description string
claimInfo *ClaimInfo claimInfo *ClaimInfo
@@ -414,7 +296,7 @@ func TestClaimInfoHasPodReference(t *testing.T) {
description: "claim references pod", description: "claim references pod",
claimInfo: &ClaimInfo{ claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
PodUIDs: sets.New[string](string(podUID)), PodUIDs: sets.New[string](podUID),
}, },
}, },
expectedResult: true, expectedResult: true,
@@ -431,7 +313,6 @@ func TestClaimInfoHasPodReference(t *testing.T) {
} }
func TestClaimInfoDeletePodReference(t *testing.T) { func TestClaimInfoDeletePodReference(t *testing.T) {
podUID := types.UID("pod-uid")
for _, test := range []struct { for _, test := range []struct {
description string description string
claimInfo *ClaimInfo claimInfo *ClaimInfo
@@ -448,7 +329,7 @@ func TestClaimInfoDeletePodReference(t *testing.T) {
description: "claim references pod", description: "claim references pod",
claimInfo: &ClaimInfo{ claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
PodUIDs: sets.New[string](string(podUID)), PodUIDs: sets.New[string](podUID),
}, },
}, },
}, },
@@ -694,8 +575,8 @@ func TestClaimInfoCacheAdd(t *testing.T) {
description: "claimInfo successfully added", description: "claimInfo successfully added",
claimInfo: &ClaimInfo{ claimInfo: &ClaimInfo{
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
ClaimName: "test-claim", ClaimName: claimName,
Namespace: "test-namespace", Namespace: namespace,
}, },
}, },
}, },
@@ -711,8 +592,6 @@ func TestClaimInfoCacheAdd(t *testing.T) {
} }
func TestClaimInfoCacheContains(t *testing.T) { func TestClaimInfoCacheContains(t *testing.T) {
claimName := "test-claim"
namespace := "test-namespace"
for _, test := range []struct { for _, test := range []struct {
description string description string
claimInfo *ClaimInfo claimInfo *ClaimInfo
@@ -764,8 +643,6 @@ func TestClaimInfoCacheContains(t *testing.T) {
} }
func TestClaimInfoCacheGet(t *testing.T) { func TestClaimInfoCacheGet(t *testing.T) {
claimName := "test-claim"
namespace := "test-namespace"
for _, test := range []struct { for _, test := range []struct {
description string description string
claimInfoCache *claimInfoCache claimInfoCache *claimInfoCache
@@ -801,8 +678,6 @@ func TestClaimInfoCacheGet(t *testing.T) {
} }
func TestClaimInfoCacheDelete(t *testing.T) { func TestClaimInfoCacheDelete(t *testing.T) {
claimName := "test-claim"
namespace := "test-namespace"
for _, test := range []struct { for _, test := range []struct {
description string description string
claimInfoCache *claimInfoCache claimInfoCache *claimInfoCache
@@ -833,9 +708,6 @@ func TestClaimInfoCacheDelete(t *testing.T) {
} }
func TestClaimInfoCacheHasPodReference(t *testing.T) { func TestClaimInfoCacheHasPodReference(t *testing.T) {
claimName := "test-claim"
namespace := "test-namespace"
uid := types.UID("test-uid")
for _, test := range []struct { for _, test := range []struct {
description string description string
claimInfoCache *claimInfoCache claimInfoCache *claimInfoCache
@@ -849,7 +721,7 @@ func TestClaimInfoCacheHasPodReference(t *testing.T) {
ClaimInfoState: state.ClaimInfoState{ ClaimInfoState: state.ClaimInfoState{
ClaimName: claimName, ClaimName: claimName,
Namespace: namespace, Namespace: namespace,
PodUIDs: sets.New[string](string(uid)), PodUIDs: sets.New[string](podUID),
}, },
}, },
}, },
@@ -862,7 +734,7 @@ func TestClaimInfoCacheHasPodReference(t *testing.T) {
}, },
} { } {
t.Run(test.description, func(t *testing.T) { t.Run(test.description, func(t *testing.T) {
assert.Equal(t, test.expectedResult, test.claimInfoCache.hasPodReference(uid)) assert.Equal(t, test.expectedResult, test.claimInfoCache.hasPodReference(podUID))
}) })
} }
} }

View File

@@ -32,6 +32,7 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
drapb "k8s.io/kubelet/pkg/apis/dra/v1alpha4" drapb "k8s.io/kubelet/pkg/apis/dra/v1alpha4"
dra "k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin" dra "k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin"
"k8s.io/kubernetes/pkg/kubelet/cm/dra/state"
"k8s.io/kubernetes/pkg/kubelet/config" "k8s.io/kubernetes/pkg/kubelet/config"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
) )
@@ -45,7 +46,7 @@ const defaultReconcilePeriod = 60 * time.Second
// ActivePodsFunc is a function that returns a list of pods to reconcile. // ActivePodsFunc is a function that returns a list of pods to reconcile.
type ActivePodsFunc func() []*v1.Pod type ActivePodsFunc func() []*v1.Pod
// ManagerImpl is the structure in charge of managing DRA resource Plugins. // ManagerImpl is the structure in charge of managing DRA drivers.
type ManagerImpl struct { type ManagerImpl struct {
// cache contains cached claim info // cache contains cached claim info
cache *claimInfoCache cache *claimInfoCache
@@ -145,8 +146,8 @@ func (m *ManagerImpl) reconcileLoop() {
} }
} }
// PrepareResources attempts to prepare all of the required resource // PrepareResources attempts to prepare all of the required resources
// plugin resources for the input container, issue NodePrepareResources rpc requests // for the input container, issue NodePrepareResources rpc requests
// for each new resource requirement, process their responses and update the cached // for each new resource requirement, process their responses and update the cached
// containerResources on success. // containerResources on success.
func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error { func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
@@ -154,7 +155,7 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
resourceClaims := make(map[types.UID]*resourceapi.ResourceClaim) resourceClaims := make(map[types.UID]*resourceapi.ResourceClaim)
for i := range pod.Spec.ResourceClaims { for i := range pod.Spec.ResourceClaims {
podClaim := &pod.Spec.ResourceClaims[i] podClaim := &pod.Spec.ResourceClaims[i]
klog.V(3).InfoS("Processing resource", "podClaim", podClaim.Name, "pod", pod.Name) klog.V(3).InfoS("Processing resource", "pod", klog.KObj(pod), "podClaim", podClaim.Name)
claimName, mustCheckOwner, err := resourceclaim.Name(pod, podClaim) claimName, mustCheckOwner, err := resourceclaim.Name(pod, podClaim)
if err != nil { if err != nil {
return fmt.Errorf("prepare resource claim: %v", err) return fmt.Errorf("prepare resource claim: %v", err)
@@ -162,6 +163,7 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
if claimName == nil { if claimName == nil {
// Nothing to do. // Nothing to do.
klog.V(5).InfoS("No need to prepare resources, no claim generated", "pod", klog.KObj(pod), "podClaim", podClaim.Name)
continue continue
} }
// Query claim object from the API server // Query claim object from the API server
@@ -185,20 +187,20 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
pod.Name, pod.UID, *claimName, resourceClaim.UID) pod.Name, pod.UID, *claimName, resourceClaim.UID)
} }
// If no container actually uses the claim, then we don't need
// to prepare it.
if !claimIsUsedByPod(podClaim, pod) {
klog.V(5).InfoS("Skipping unused resource", "claim", claimName, "pod", pod.Name)
continue
}
// Atomically perform some operations on the claimInfo cache. // Atomically perform some operations on the claimInfo cache.
err = m.cache.withLock(func() error { err = m.cache.withLock(func() error {
// Get a reference to the claim info for this claim from the cache. // Get a reference to the claim info for this claim from the cache.
// If there isn't one yet, then add it to the cache. // If there isn't one yet, then add it to the cache.
claimInfo, exists := m.cache.get(resourceClaim.Name, resourceClaim.Namespace) claimInfo, exists := m.cache.get(resourceClaim.Name, resourceClaim.Namespace)
if !exists { if !exists {
claimInfo = m.cache.add(newClaimInfoFromClaim(resourceClaim)) ci, err := newClaimInfoFromClaim(resourceClaim)
if err != nil {
return fmt.Errorf("claim %s: %w", klog.KObj(resourceClaim), err)
}
claimInfo = m.cache.add(ci)
klog.V(6).InfoS("Created new claim info cache entry", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim), "claimInfoEntry", claimInfo)
} else {
klog.V(6).InfoS("Found existing claim info cache entry", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim), "claimInfoEntry", claimInfo)
} }
// Add a reference to the current pod in the claim info. // Add a reference to the current pod in the claim info.
@@ -214,6 +216,7 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
// If this claim is already prepared, there is no need to prepare it again. // If this claim is already prepared, there is no need to prepare it again.
if claimInfo.isPrepared() { if claimInfo.isPrepared() {
klog.V(5).InfoS("Resources already prepared", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim))
return nil return nil
} }
@@ -221,15 +224,14 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
// after NodePrepareResources GRPC succeeds // after NodePrepareResources GRPC succeeds
resourceClaims[claimInfo.ClaimUID] = resourceClaim resourceClaims[claimInfo.ClaimUID] = resourceClaim
// Loop through all plugins and prepare for calling NodePrepareResources. // Loop through all drivers and prepare for calling NodePrepareResources.
for _, resourceHandle := range claimInfo.ResourceHandles { claim := &drapb.Claim{
claim := &drapb.Claim{ Namespace: claimInfo.Namespace,
Namespace: claimInfo.Namespace, UID: string(claimInfo.ClaimUID),
Uid: string(claimInfo.ClaimUID), Name: claimInfo.ClaimName,
Name: claimInfo.ClaimName, }
} for driverName := range claimInfo.DriverState {
pluginName := resourceHandle.DriverName batches[driverName] = append(batches[driverName], claim)
batches[pluginName] = append(batches[pluginName], claim)
} }
return nil return nil
@@ -242,16 +244,16 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
// Call NodePrepareResources for all claims in each batch. // Call NodePrepareResources for all claims in each batch.
// If there is any error, processing gets aborted. // If there is any error, processing gets aborted.
// We could try to continue, but that would make the code more complex. // We could try to continue, but that would make the code more complex.
for pluginName, claims := range batches { for driverName, claims := range batches {
// Call NodePrepareResources RPC for all resource handles. // Call NodePrepareResources RPC for all resource handles.
client, err := dra.NewDRAPluginClient(pluginName) client, err := dra.NewDRAPluginClient(driverName)
if err != nil { if err != nil {
return fmt.Errorf("failed to get DRA Plugin client for plugin name %s: %v", pluginName, err) return fmt.Errorf("failed to get gRPC client for driver %s: %w", driverName, err)
} }
response, err := client.NodePrepareResources(context.Background(), &drapb.NodePrepareResourcesRequest{Claims: claims}) response, err := client.NodePrepareResources(context.Background(), &drapb.NodePrepareResourcesRequest{Claims: claims})
if err != nil { if err != nil {
// General error unrelated to any particular claim. // General error unrelated to any particular claim.
return fmt.Errorf("NodePrepareResources failed: %v", err) return fmt.Errorf("NodePrepareResources failed: %w", err)
} }
for claimUID, result := range response.Claims { for claimUID, result := range response.Claims {
reqClaim := lookupClaimRequest(claims, claimUID) reqClaim := lookupClaimRequest(claims, claimUID)
@@ -270,8 +272,8 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
if !exists { if !exists {
return fmt.Errorf("unable to get claim info for claim %s in namespace %s", claim.Name, claim.Namespace) return fmt.Errorf("unable to get claim info for claim %s in namespace %s", claim.Name, claim.Namespace)
} }
if err := info.setCDIDevices(pluginName, result.GetCDIDevices()); err != nil { for _, device := range result.GetDevices() {
return fmt.Errorf("unable to add CDI devices for plugin %s of claim %s in namespace %s", pluginName, claim.Name, claim.Namespace) info.addDevice(driverName, state.Device{PoolName: device.PoolName, DeviceName: device.DeviceName, RequestNames: device.RequestNames, CDIDeviceIDs: device.CDIDeviceIDs})
} }
return nil return nil
}) })
@@ -314,60 +316,33 @@ func (m *ManagerImpl) PrepareResources(pod *v1.Pod) error {
func lookupClaimRequest(claims []*drapb.Claim, claimUID string) *drapb.Claim { func lookupClaimRequest(claims []*drapb.Claim, claimUID string) *drapb.Claim {
for _, claim := range claims { for _, claim := range claims {
if claim.Uid == claimUID { if claim.UID == claimUID {
return claim return claim
} }
} }
return nil return nil
} }
func claimIsUsedByPod(podClaim *v1.PodResourceClaim, pod *v1.Pod) bool {
if claimIsUsedByContainers(podClaim, pod.Spec.InitContainers) {
return true
}
if claimIsUsedByContainers(podClaim, pod.Spec.Containers) {
return true
}
return false
}
func claimIsUsedByContainers(podClaim *v1.PodResourceClaim, containers []v1.Container) bool {
for i := range containers {
if claimIsUsedByContainer(podClaim, &containers[i]) {
return true
}
}
return false
}
func claimIsUsedByContainer(podClaim *v1.PodResourceClaim, container *v1.Container) bool {
for _, c := range container.Resources.Claims {
if c.Name == podClaim.Name {
return true
}
}
return false
}
// GetResources gets a ContainerInfo object from the claimInfo cache. // GetResources gets a ContainerInfo object from the claimInfo cache.
// This information is used by the caller to update a container config. // This information is used by the caller to update a container config.
func (m *ManagerImpl) GetResources(pod *v1.Pod, container *v1.Container) (*ContainerInfo, error) { func (m *ManagerImpl) GetResources(pod *v1.Pod, container *v1.Container) (*ContainerInfo, error) {
annotations := []kubecontainer.Annotation{}
cdiDevices := []kubecontainer.CDIDevice{} cdiDevices := []kubecontainer.CDIDevice{}
for i, podResourceClaim := range pod.Spec.ResourceClaims { for i := range pod.Spec.ResourceClaims {
claimName, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i]) podClaim := &pod.Spec.ResourceClaims[i]
claimName, _, err := resourceclaim.Name(pod, podClaim)
if err != nil { if err != nil {
return nil, fmt.Errorf("list resource claims: %v", err) return nil, fmt.Errorf("list resource claims: %w", err)
} }
// The claim name might be nil if no underlying resource claim // The claim name might be nil if no underlying resource claim
// was generated for the referenced claim. There are valid use // was generated for the referenced claim. There are valid use
// cases when this might happen, so we simply skip it. // cases when this might happen, so we simply skip it.
if claimName == nil { if claimName == nil {
klog.V(5).InfoS("No CDI devices, no claim generated", "pod", klog.KObj(pod), "podClaimName", podClaim.Name)
continue continue
} }
for _, claim := range container.Resources.Claims { for _, claim := range container.Resources.Claims {
if podResourceClaim.Name != claim.Name { if podClaim.Name != claim.Name {
continue continue
} }
@@ -377,13 +352,8 @@ func (m *ManagerImpl) GetResources(pod *v1.Pod, container *v1.Container) (*Conta
return fmt.Errorf("unable to get claim info for claim %s in namespace %s", *claimName, pod.Namespace) return fmt.Errorf("unable to get claim info for claim %s in namespace %s", *claimName, pod.Namespace)
} }
claimAnnotations := claimInfo.annotationsAsList() // As of Kubernetes 1.31, CDI device IDs are not passed via annotations anymore.
klog.V(3).InfoS("Add resource annotations", "claim", *claimName, "annotations", claimAnnotations) cdiDevices = append(cdiDevices, claimInfo.cdiDevicesAsList(claim.Request)...)
annotations = append(annotations, claimAnnotations...)
devices := claimInfo.cdiDevicesAsList()
klog.V(3).InfoS("Add CDI devices", "claim", *claimName, "CDI devices", devices)
cdiDevices = append(cdiDevices, devices...)
return nil return nil
}) })
@@ -393,10 +363,11 @@ func (m *ManagerImpl) GetResources(pod *v1.Pod, container *v1.Container) (*Conta
} }
} }
return &ContainerInfo{Annotations: annotations, CDIDevices: cdiDevices}, nil klog.V(5).InfoS("Determined CDI devices for pod", "pod", klog.KObj(pod), "cdiDevices", cdiDevices)
return &ContainerInfo{CDIDevices: cdiDevices}, nil
} }
// UnprepareResources calls a plugin's NodeUnprepareResource API for each resource claim owned by a pod. // UnprepareResources calls a driver's NodeUnprepareResource API for each resource claim owned by a pod.
// This function is idempotent and may be called multiple times against the same pod. // This function is idempotent and may be called multiple times against the same pod.
// As such, calls to the underlying NodeUnprepareResource API are skipped for claims that have // As such, calls to the underlying NodeUnprepareResource API are skipped for claims that have
// already been successfully unprepared. // already been successfully unprepared.
@@ -405,7 +376,7 @@ func (m *ManagerImpl) UnprepareResources(pod *v1.Pod) error {
for i := range pod.Spec.ResourceClaims { for i := range pod.Spec.ResourceClaims {
claimName, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i]) claimName, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i])
if err != nil { if err != nil {
return fmt.Errorf("unprepare resource claim: %v", err) return fmt.Errorf("unprepare resource claim: %w", err)
} }
// The claim name might be nil if no underlying resource claim // The claim name might be nil if no underlying resource claim
// was generated for the referenced claim. There are valid use // was generated for the referenced claim. There are valid use
@@ -448,15 +419,14 @@ func (m *ManagerImpl) unprepareResources(podUID types.UID, namespace string, cla
// after NodeUnprepareResources GRPC succeeds // after NodeUnprepareResources GRPC succeeds
claimNamesMap[claimInfo.ClaimUID] = claimInfo.ClaimName claimNamesMap[claimInfo.ClaimUID] = claimInfo.ClaimName
// Loop through all plugins and prepare for calling NodeUnprepareResources. // Loop through all drivers and prepare for calling NodeUnprepareResources.
for _, resourceHandle := range claimInfo.ResourceHandles { claim := &drapb.Claim{
claim := &drapb.Claim{ Namespace: claimInfo.Namespace,
Namespace: claimInfo.Namespace, UID: string(claimInfo.ClaimUID),
Uid: string(claimInfo.ClaimUID), Name: claimInfo.ClaimName,
Name: claimInfo.ClaimName, }
} for driverName := range claimInfo.DriverState {
pluginName := resourceHandle.DriverName batches[driverName] = append(batches[driverName], claim)
batches[pluginName] = append(batches[pluginName], claim)
} }
return nil return nil
@@ -469,16 +439,16 @@ func (m *ManagerImpl) unprepareResources(podUID types.UID, namespace string, cla
// Call NodeUnprepareResources for all claims in each batch. // Call NodeUnprepareResources for all claims in each batch.
// If there is any error, processing gets aborted. // If there is any error, processing gets aborted.
// We could try to continue, but that would make the code more complex. // We could try to continue, but that would make the code more complex.
for pluginName, claims := range batches { for driverName, claims := range batches {
// Call NodeUnprepareResources RPC for all resource handles. // Call NodeUnprepareResources RPC for all resource handles.
client, err := dra.NewDRAPluginClient(pluginName) client, err := dra.NewDRAPluginClient(driverName)
if err != nil { if err != nil {
return fmt.Errorf("failed to get DRA Plugin client for plugin name %s: %v", pluginName, err) return fmt.Errorf("get gRPC client for DRA driver %s: %w", driverName, err)
} }
response, err := client.NodeUnprepareResources(context.Background(), &drapb.NodeUnprepareResourcesRequest{Claims: claims}) response, err := client.NodeUnprepareResources(context.Background(), &drapb.NodeUnprepareResourcesRequest{Claims: claims})
if err != nil { if err != nil {
// General error unrelated to any particular claim. // General error unrelated to any particular claim.
return fmt.Errorf("NodeUnprepareResources failed: %v", err) return fmt.Errorf("NodeUnprepareResources failed: %w", err)
} }
for claimUID, result := range response.Claims { for claimUID, result := range response.Claims {
@@ -501,7 +471,9 @@ func (m *ManagerImpl) unprepareResources(podUID types.UID, namespace string, cla
err := m.cache.withLock(func() error { err := m.cache.withLock(func() error {
// Delete all claimInfos from the cache that have just been unprepared. // Delete all claimInfos from the cache that have just been unprepared.
for _, claimName := range claimNamesMap { for _, claimName := range claimNamesMap {
claimInfo, _ := m.cache.get(claimName, namespace)
m.cache.delete(claimName, namespace) m.cache.delete(claimName, namespace)
klog.V(6).InfoS("Deleted claim info cache entry", "claim", klog.KRef(namespace, claimName), "claimInfoEntry", claimInfo)
} }
// Atomically sync the cache back to the checkpoint. // Atomically sync the cache back to the checkpoint.
@@ -532,7 +504,7 @@ func (m *ManagerImpl) GetContainerClaimInfos(pod *v1.Pod, container *v1.Containe
for i, podResourceClaim := range pod.Spec.ResourceClaims { for i, podResourceClaim := range pod.Spec.ResourceClaims {
claimName, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i]) claimName, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i])
if err != nil { if err != nil {
return nil, fmt.Errorf("determine resource claim information: %v", err) return nil, fmt.Errorf("determine resource claim information: %w", err)
} }
for _, claim := range container.Resources.Claims { for _, claim := range container.Resources.Claims {

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,14 @@ type fakeV1alpha4GRPCServer struct {
var _ drapb.NodeServer = &fakeV1alpha4GRPCServer{} var _ drapb.NodeServer = &fakeV1alpha4GRPCServer{}
func (f *fakeV1alpha4GRPCServer) NodePrepareResources(ctx context.Context, in *drapb.NodePrepareResourcesRequest) (*drapb.NodePrepareResourcesResponse, error) { func (f *fakeV1alpha4GRPCServer) NodePrepareResources(ctx context.Context, in *drapb.NodePrepareResourcesRequest) (*drapb.NodePrepareResourcesResponse, error) {
return &drapb.NodePrepareResourcesResponse{Claims: map[string]*drapb.NodePrepareResourceResponse{"dummy": {CDIDevices: []string{"dummy"}}}}, nil return &drapb.NodePrepareResourcesResponse{Claims: map[string]*drapb.NodePrepareResourceResponse{"claim-uid": {
Devices: []*drapb.Device{
{
RequestNames: []string{"test-request"},
CDIDeviceIDs: []string{"test-cdi-id"},
},
},
}}}, nil
} }
func (f *fakeV1alpha4GRPCServer) NodeUnprepareResources(ctx context.Context, in *drapb.NodeUnprepareResourcesRequest) (*drapb.NodeUnprepareResourcesResponse, error) { func (f *fakeV1alpha4GRPCServer) NodeUnprepareResources(ctx context.Context, in *drapb.NodeUnprepareResourcesRequest) (*drapb.NodeUnprepareResourcesResponse, error) {
@@ -136,7 +143,7 @@ func TestGRPCConnIsReused(t *testing.T) {
Claims: []*drapb.Claim{ Claims: []*drapb.Claim{
{ {
Namespace: "dummy-namespace", Namespace: "dummy-namespace",
Uid: "dummy-uid", UID: "dummy-uid",
Name: "dummy-claim", Name: "dummy-claim",
}, },
}, },

View File

@@ -24,6 +24,7 @@ import (
"time" "time"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
resourceapi "k8s.io/api/resource/v1alpha3"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/fields"
@@ -72,7 +73,7 @@ func NewRegistrationHandler(kubeClient kubernetes.Interface, getNode func() (*v1
} }
// wipeResourceSlices deletes ResourceSlices of the node, optionally just for a specific driver. // wipeResourceSlices deletes ResourceSlices of the node, optionally just for a specific driver.
func (h *RegistrationHandler) wipeResourceSlices(pluginName string) { func (h *RegistrationHandler) wipeResourceSlices(driver string) {
if h.kubeClient == nil { if h.kubeClient == nil {
return return
} }
@@ -97,9 +98,9 @@ func (h *RegistrationHandler) wipeResourceSlices(pluginName string) {
logger.Error(err, "Unexpected error checking for node") logger.Error(err, "Unexpected error checking for node")
return false, nil return false, nil
} }
fieldSelector := fields.Set{"nodeName": node.Name} fieldSelector := fields.Set{resourceapi.ResourceSliceSelectorNodeName: node.Name}
if pluginName != "" { if driver != "" {
fieldSelector["driverName"] = pluginName fieldSelector[resourceapi.ResourceSliceSelectorDriver] = driver
} }
err = h.kubeClient.ResourceV1alpha3().ResourceSlices().DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{FieldSelector: fieldSelector.String()}) err = h.kubeClient.ResourceV1alpha3().ResourceSlices().DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{FieldSelector: fieldSelector.String()})

View File

@@ -18,15 +18,9 @@ package state
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt"
"hash/fnv"
"strings"
"k8s.io/apimachinery/pkg/util/dump"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum"
cmerrors "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors"
) )
var _ checkpointmanager.Checkpoint = &DRAManagerCheckpoint{} var _ checkpointmanager.Checkpoint = &DRAManagerCheckpoint{}
@@ -40,20 +34,9 @@ type DRAManagerCheckpoint struct {
Checksum checksum.Checksum `json:"checksum"` Checksum checksum.Checksum `json:"checksum"`
} }
// DraManagerCheckpoint struct is an old implementation of the DraManagerCheckpoint
type DRAManagerCheckpointWithoutResourceHandles struct {
Version string `json:"version"`
Entries ClaimInfoStateListWithoutResourceHandles `json:"entries,omitempty"`
Checksum checksum.Checksum `json:"checksum"`
}
// List of claim info to store in checkpoint // List of claim info to store in checkpoint
type ClaimInfoStateList []ClaimInfoState type ClaimInfoStateList []ClaimInfoState
// List of claim info to store in checkpoint
// TODO: remove in Beta
type ClaimInfoStateListWithoutResourceHandles []ClaimInfoStateWithoutResourceHandles
// NewDRAManagerCheckpoint returns an instance of Checkpoint // NewDRAManagerCheckpoint returns an instance of Checkpoint
func NewDRAManagerCheckpoint() *DRAManagerCheckpoint { func NewDRAManagerCheckpoint() *DRAManagerCheckpoint {
return &DRAManagerCheckpoint{ return &DRAManagerCheckpoint{
@@ -80,48 +63,6 @@ func (dc *DRAManagerCheckpoint) VerifyChecksum() error {
ck := dc.Checksum ck := dc.Checksum
dc.Checksum = 0 dc.Checksum = 0
err := ck.Verify(dc) err := ck.Verify(dc)
if errors.Is(err, cmerrors.CorruptCheckpointError{}) {
// Verify with old structs without ResourceHandles field
// TODO: remove in Beta
err = verifyChecksumWithoutResourceHandles(dc, ck)
}
dc.Checksum = ck dc.Checksum = ck
return err return err
} }
// verifyChecksumWithoutResourceHandles is a helper function that verifies checksum of the
// checkpoint in the old format, without ResourceHandles field.
// TODO: remove in Beta.
func verifyChecksumWithoutResourceHandles(dc *DRAManagerCheckpoint, checkSum checksum.Checksum) error {
entries := ClaimInfoStateListWithoutResourceHandles{}
for _, entry := range dc.Entries {
entries = append(entries, ClaimInfoStateWithoutResourceHandles{
DriverName: entry.DriverName,
ClassName: entry.ClassName,
ClaimUID: entry.ClaimUID,
ClaimName: entry.ClaimName,
Namespace: entry.Namespace,
PodUIDs: entry.PodUIDs,
CDIDevices: entry.CDIDevices,
})
}
oldcheckpoint := &DRAManagerCheckpointWithoutResourceHandles{
Version: checkpointVersion,
Entries: entries,
Checksum: 0,
}
// Calculate checksum for old checkpoint
object := dump.ForHash(oldcheckpoint)
object = strings.Replace(object, "DRAManagerCheckpointWithoutResourceHandles", "DRAManagerCheckpoint", 1)
object = strings.Replace(object, "ClaimInfoStateListWithoutResourceHandles", "ClaimInfoStateList", 1)
hash := fnv.New32a()
fmt.Fprintf(hash, "%v", object)
actualCS := checksum.Checksum(hash.Sum32())
if checkSum != actualCS {
return &cmerrors.CorruptCheckpointError{
ActualCS: uint64(actualCS),
ExpectedCS: uint64(checkSum),
}
}
return nil
}

View File

@@ -37,12 +37,6 @@ type CheckpointState interface {
// ClaimInfoState is used to store claim info state in a checkpoint // ClaimInfoState is used to store claim info state in a checkpoint
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
type ClaimInfoState struct { type ClaimInfoState struct {
// Name of the DRA driver
DriverName string
// ClassName is a resource class of the claim
ClassName string
// ClaimUID is an UID of the resource claim // ClaimUID is an UID of the resource claim
ClaimUID types.UID ClaimUID types.UID
@@ -55,35 +49,25 @@ type ClaimInfoState struct {
// PodUIDs is a set of pod UIDs that reference a resource // PodUIDs is a set of pod UIDs that reference a resource
PodUIDs sets.Set[string] PodUIDs sets.Set[string]
// CDIDevices is a map of DriverName --> CDI devices returned by the // DriverState contains information about all drivers which have allocation
// GRPC API call NodePrepareResource // results in the claim, even if they don't provide devices for their results.
CDIDevices map[string][]string DriverState map[string]DriverState
} }
// ClaimInfoStateWithoutResourceHandles is an old implementation of the ClaimInfoState // DriverState is used to store per-device claim info state in a checkpoint
// TODO: remove in Beta // +k8s:deepcopy-gen=true
type ClaimInfoStateWithoutResourceHandles struct { type DriverState struct {
// Name of the DRA driver Devices []Device
DriverName string }
// ClassName is a resource class of the claim // Device is how a DRA driver described an allocated device in a claim
ClassName string // to kubelet. RequestName and CDI device IDs are optional.
// +k8s:deepcopy-gen=true
// ClaimUID is an UID of the resource claim type Device struct {
ClaimUID types.UID PoolName string
DeviceName string
// ClaimName is a name of the resource claim RequestNames []string
ClaimName string CDIDeviceIDs []string
// Namespace is a claim namespace
Namespace string
// PodUIDs is a set of pod UIDs that reference a resource
PodUIDs sets.Set[string]
// CDIDevices is a map of DriverName --> CDI devices returned by the
// GRPC API call NodePrepareResource
CDIDevices map[string][]string
} }
type stateCheckpoint struct { type stateCheckpoint struct {

View File

@@ -19,14 +19,12 @@ package state
import ( import (
"errors" "errors"
"os" "os"
"path"
"strings" "strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
resourceapi "k8s.io/api/resource/v1alpha3"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager" "k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
cmerrors "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" cmerrors "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors"
@@ -55,116 +53,120 @@ func TestCheckpointGetOrCreate(t *testing.T) {
expectedState ClaimInfoStateList expectedState ClaimInfoStateList
}{ }{
{ {
"Create non-existing checkpoint", description: "Create non-existing checkpoint",
"", checkpointContent: "",
"", expectedError: "",
[]ClaimInfoState{}, expectedState: []ClaimInfoState{},
}, },
{ {
"Restore checkpoint - single claim", description: "Restore checkpoint - single claim",
`{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":113577689}`, checkpointContent: `{"version":"v1","entries":[{"ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"DriverState":{"test-driver.cdi.k8s.io":{"Devices":[{"PoolName":"worker-1","DeviceName":"dev-1","RequestNames":["test request"],"CDIDeviceIDs":["example.com/example=cdi-example"]}]}}}],"checksum":1925941526}`,
"", expectedState: []ClaimInfoState{
[]ClaimInfoState{
{ {
DriverName: "test-driver.cdi.k8s.io", DriverState: map[string]DriverState{
ClassName: "class-name", "test-driver.cdi.k8s.io": {
ClaimUID: "067798be-454e-4be4-9047-1aa06aea63f7", Devices: []Device{
ClaimName: "example", {
Namespace: "default", PoolName: "worker-1",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"), DeviceName: "dev-1",
ResourceHandles: []resourceapi.ResourceHandle{ RequestNames: []string{"test request"},
{ CDIDeviceIDs: []string{"example.com/example=cdi-example"},
DriverName: "test-driver.cdi.k8s.io", },
Data: `{"a": "b"}`, },
}, },
}, },
CDIDevices: map[string][]string{ ClaimUID: "067798be-454e-4be4-9047-1aa06aea63f7",
"test-driver.cdi.k8s.io": {"example.com/example=cdi-example"}, ClaimName: "example",
}, Namespace: "default",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"),
}, },
}, },
}, },
{ {
"Restore checkpoint - single claim - multiple devices", description: "Restore checkpoint - single claim - multiple devices",
`{"version":"v1","entries":[{"DriverName":"meta-test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver-1.cdi.k8s.io","data":"{\"a\": \"b\"}"},{"driverName":"test-driver-2.cdi.k8s.io","data":"{\"c\": \"d\"}"}],"CDIDevices":{"test-driver-1.cdi.k8s.io":["example-1.com/example-1=cdi-example-1"],"test-driver-2.cdi.k8s.io":["example-2.com/example-2=cdi-example-2"]}}],"checksum":1466990255}`, checkpointContent: `{"version":"v1","entries":[{"ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"DriverState":{"test-driver.cdi.k8s.io":{"Devices":[{"PoolName":"worker-1","DeviceName":"dev-1","RequestNames":["test request"],"CDIDeviceIDs":["example.com/example=cdi-example"]},{"PoolName":"worker-1","DeviceName":"dev-2","RequestNames":["test request2"],"CDIDeviceIDs":["example.com/example=cdi-example2"]}]}}}],"checksum":3560752542}`,
"", expectedError: "",
[]ClaimInfoState{ expectedState: []ClaimInfoState{
{ {
DriverName: "meta-test-driver.cdi.k8s.io", DriverState: map[string]DriverState{
ClassName: "class-name", "test-driver.cdi.k8s.io": {
ClaimUID: "067798be-454e-4be4-9047-1aa06aea63f7", Devices: []Device{
ClaimName: "example", {
Namespace: "default", PoolName: "worker-1",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"), DeviceName: "dev-1",
ResourceHandles: []resourceapi.ResourceHandle{ RequestNames: []string{"test request"},
{ CDIDeviceIDs: []string{"example.com/example=cdi-example"},
DriverName: "test-driver-1.cdi.k8s.io", },
Data: `{"a": "b"}`, {
}, PoolName: "worker-1",
{ DeviceName: "dev-2",
DriverName: "test-driver-2.cdi.k8s.io", RequestNames: []string{"test request2"},
Data: `{"c": "d"}`, CDIDeviceIDs: []string{"example.com/example=cdi-example2"},
},
},
}, },
}, },
CDIDevices: map[string][]string{ ClaimUID: "067798be-454e-4be4-9047-1aa06aea63f7",
"test-driver-1.cdi.k8s.io": {"example-1.com/example-1=cdi-example-1"}, ClaimName: "example",
"test-driver-2.cdi.k8s.io": {"example-2.com/example-2=cdi-example-2"}, Namespace: "default",
}, PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"),
}, },
}, },
}, },
{ {
"Restore checkpoint - multiple claims", description: "Restore checkpoint - multiple claims",
`{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name-1","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example-1","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example-1"]}},{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name-2","ClaimUID":"4cf8db2d-06c0-7d70-1a51-e59b25b2c16c","ClaimName":"example-2","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"c\": \"d\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example-2"]}}],"checksum":471181742}`, checkpointContent: `{"version":"v1","entries":[{"ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example-1","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"DriverState":{"test-driver.cdi.k8s.io":{"Devices":[{"PoolName":"worker-1","DeviceName":"dev-1","RequestNames":["test request"],"CDIDeviceIDs":["example.com/example=cdi-example"]}]}}},{"ClaimUID":"4cf8db2d-06c0-7d70-1a51-e59b25b2c16c","ClaimName":"example-2","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"DriverState":{"test-driver.cdi.k8s.io":{"Devices":[{"PoolName":"worker-1","DeviceName":"dev-1","RequestNames":["test request"],"CDIDeviceIDs":["example.com/example=cdi-example"]}]}}}],"checksum":351581974}`,
"", expectedError: "",
[]ClaimInfoState{ expectedState: []ClaimInfoState{
{ {
DriverName: "test-driver.cdi.k8s.io", DriverState: map[string]DriverState{
ClassName: "class-name-1", "test-driver.cdi.k8s.io": {
ClaimUID: "067798be-454e-4be4-9047-1aa06aea63f7", Devices: []Device{
ClaimName: "example-1", {
Namespace: "default", PoolName: "worker-1",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"), DeviceName: "dev-1",
ResourceHandles: []resourceapi.ResourceHandle{ RequestNames: []string{"test request"},
{ CDIDeviceIDs: []string{"example.com/example=cdi-example"},
DriverName: "test-driver.cdi.k8s.io", },
Data: `{"a": "b"}`, },
}, },
}, },
CDIDevices: map[string][]string{ ClaimUID: "067798be-454e-4be4-9047-1aa06aea63f7",
"test-driver.cdi.k8s.io": {"example.com/example=cdi-example-1"}, ClaimName: "example-1",
}, Namespace: "default",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"),
}, },
{ {
DriverName: "test-driver.cdi.k8s.io", DriverState: map[string]DriverState{
ClassName: "class-name-2", "test-driver.cdi.k8s.io": {
ClaimUID: "4cf8db2d-06c0-7d70-1a51-e59b25b2c16c", Devices: []Device{
ClaimName: "example-2", {
Namespace: "default", PoolName: "worker-1",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"), DeviceName: "dev-1",
ResourceHandles: []resourceapi.ResourceHandle{ RequestNames: []string{"test request"},
{ CDIDeviceIDs: []string{"example.com/example=cdi-example"},
DriverName: "test-driver.cdi.k8s.io", },
Data: `{"c": "d"}`, },
}, },
}, },
CDIDevices: map[string][]string{ ClaimUID: "4cf8db2d-06c0-7d70-1a51-e59b25b2c16c",
"test-driver.cdi.k8s.io": {"example.com/example=cdi-example-2"}, ClaimName: "example-2",
}, Namespace: "default",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"),
}, },
}, },
}, },
{ {
"Restore checkpoint - invalid checksum", description: "Restore checkpoint - invalid checksum",
`{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":1988120168}`, checkpointContent: `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":1988120168}`,
"checkpoint is corrupted", expectedError: "checkpoint is corrupted",
[]ClaimInfoState{}, expectedState: []ClaimInfoState{},
}, },
{ {
"Restore checkpoint with invalid JSON", description: "Restore checkpoint with invalid JSON",
`{`, checkpointContent: `{`,
"unexpected end of JSON input", expectedError: "unexpected end of JSON input",
[]ClaimInfoState{}, expectedState: []ClaimInfoState{},
}, },
} }
@@ -198,8 +200,7 @@ func TestCheckpointGetOrCreate(t *testing.T) {
state, err = checkpointState.GetOrCreate() state, err = checkpointState.GetOrCreate()
} }
if strings.TrimSpace(tc.expectedError) != "" { if strings.TrimSpace(tc.expectedError) != "" {
assert.Error(t, err) assert.ErrorContains(t, err, tc.expectedError)
assert.Contains(t, err.Error(), tc.expectedError)
} else { } else {
requireNoCheckpointError(t, err) requireNoCheckpointError(t, err)
// compare state after restoration with the one expected // compare state after restoration with the one expected
@@ -210,25 +211,40 @@ func TestCheckpointGetOrCreate(t *testing.T) {
} }
func TestCheckpointStateStore(t *testing.T) { func TestCheckpointStateStore(t *testing.T) {
claimInfoState := ClaimInfoState{ claimInfoStateList := ClaimInfoStateList{
DriverName: "test-driver.cdi.k8s.io", {
ClassName: "class-name", DriverState: map[string]DriverState{
ClaimUID: "067798be-454e-4be4-9047-1aa06aea63f7", "test-driver.cdi.k8s.io": {
ClaimName: "example", Devices: []Device{{
Namespace: "default", PoolName: "worker-1",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"), DeviceName: "dev-1",
ResourceHandles: []resourceapi.ResourceHandle{ RequestNames: []string{"test request"},
{ CDIDeviceIDs: []string{"example.com/example=cdi-example"},
DriverName: "test-driver.cdi.k8s.io", }},
Data: `{"a": "b"}`, },
}, },
ClaimUID: "067798be-454e-4be4-9047-1aa06aea63f7",
ClaimName: "example-1",
Namespace: "default",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"),
}, },
CDIDevices: map[string][]string{ {
"test-driver.cdi.k8s.io": {"example.com/example=cdi-example"}, DriverState: map[string]DriverState{
"test-driver.cdi.k8s.io": {
Devices: []Device{{
PoolName: "worker-1",
DeviceName: "dev-2",
}},
},
},
ClaimUID: "4cf8db2d-06c0-7d70-1a51-e59b25b2c16c",
ClaimName: "example-2",
Namespace: "default",
PodUIDs: sets.New("139cdb46-f989-4f17-9561-ca10cfb509a6"),
}, },
} }
expectedCheckpoint := `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":[{"driverName":"test-driver.cdi.k8s.io","data":"{\"a\": \"b\"}"}],"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":113577689}` expectedCheckpoint := `{"version":"v1","entries":[{"ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example-1","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"DriverState":{"test-driver.cdi.k8s.io":{"Devices":[{"PoolName":"worker-1","DeviceName":"dev-1","RequestNames":["test request"],"CDIDeviceIDs":["example.com/example=cdi-example"]}]}}},{"ClaimUID":"4cf8db2d-06c0-7d70-1a51-e59b25b2c16c","ClaimName":"example-2","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"DriverState":{"test-driver.cdi.k8s.io":{"Devices":[{"PoolName":"worker-1","DeviceName":"dev-2","RequestNames":null,"CDIDeviceIDs":null}]}}}],"checksum":1191151426}`
// Should return an error, stateDir cannot be an empty string // Should return an error, stateDir cannot be an empty string
if _, err := NewCheckpointState("", testingCheckpoint); err == nil { if _, err := NewCheckpointState("", testingCheckpoint); err == nil {
@@ -248,7 +264,7 @@ func TestCheckpointStateStore(t *testing.T) {
cs, err := NewCheckpointState(testingDir, testingCheckpoint) cs, err := NewCheckpointState(testingDir, testingCheckpoint)
assert.NoError(t, err, "could not create testing checkpointState instance") assert.NoError(t, err, "could not create testing checkpointState instance")
err = cs.Store(ClaimInfoStateList{claimInfoState}) err = cs.Store(claimInfoStateList)
assert.NoError(t, err, "could not store ClaimInfoState") assert.NoError(t, err, "could not store ClaimInfoState")
checkpoint := NewDRAManagerCheckpoint() checkpoint := NewDRAManagerCheckpoint()
cpm.GetCheckpoint(testingCheckpoint, checkpoint) cpm.GetCheckpoint(testingCheckpoint, checkpoint)
@@ -262,26 +278,6 @@ func TestCheckpointStateStore(t *testing.T) {
} }
} }
func TestOldCheckpointRestore(t *testing.T) {
testingDir := t.TempDir()
cpm, err := checkpointmanager.NewCheckpointManager(testingDir)
assert.NoError(t, err, "could not create testing checkpoint manager")
oldCheckpointData := `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":153446146}`
err = os.WriteFile(path.Join(testingDir, testingCheckpoint), []byte(oldCheckpointData), 0644)
assert.NoError(t, err, "could not store checkpoint data")
checkpoint := NewDRAManagerCheckpoint()
err = cpm.GetCheckpoint(testingCheckpoint, checkpoint)
requireNoCheckpointError(t, err)
checkpointData, err := checkpoint.MarshalCheckpoint()
assert.NoError(t, err, "could not Marshal Checkpoint")
expectedData := `{"version":"v1","entries":[{"DriverName":"test-driver.cdi.k8s.io","ClassName":"class-name","ClaimUID":"067798be-454e-4be4-9047-1aa06aea63f7","ClaimName":"example","Namespace":"default","PodUIDs":{"139cdb46-f989-4f17-9561-ca10cfb509a6":{}},"ResourceHandles":null,"CDIDevices":{"test-driver.cdi.k8s.io":["example.com/example=cdi-example"]}}],"checksum":453625682}`
assert.Equal(t, expectedData, string(checkpointData), "expected ClaimInfoState does not equal to restored one")
}
func requireNoCheckpointError(t *testing.T, err error) { func requireNoCheckpointError(t *testing.T, err error) {
t.Helper() t.Helper()
var cksumErr *cmerrors.CorruptCheckpointError var cksumErr *cmerrors.CorruptCheckpointError

View File

@@ -35,19 +35,11 @@ func (in *ClaimInfoState) DeepCopyInto(out *ClaimInfoState) {
(*out)[key] = val (*out)[key] = val
} }
} }
if in.CDIDevices != nil { if in.DriverState != nil {
in, out := &in.CDIDevices, &out.CDIDevices in, out := &in.DriverState, &out.DriverState
*out = make(map[string][]string, len(*in)) *out = make(map[string]DriverState, len(*in))
for key, val := range *in { for key, val := range *in {
var outVal []string (*out)[key] = *val.DeepCopy()
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = make([]string, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
} }
} }
return return
@@ -62,3 +54,52 @@ func (in *ClaimInfoState) DeepCopy() *ClaimInfoState {
in.DeepCopyInto(out) in.DeepCopyInto(out)
return out return out
} }
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Device) DeepCopyInto(out *Device) {
*out = *in
if in.RequestNames != nil {
in, out := &in.RequestNames, &out.RequestNames
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.CDIDeviceIDs != nil {
in, out := &in.CDIDeviceIDs, &out.CDIDeviceIDs
*out = make([]string, len(*in))
copy(*out, *in)
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Device.
func (in *Device) DeepCopy() *Device {
if in == nil {
return nil
}
out := new(Device)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *DriverState) DeepCopyInto(out *DriverState) {
*out = *in
if in.Devices != nil {
in, out := &in.Devices, &out.Devices
*out = make([]Device, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DriverState.
func (in *DriverState) DeepCopy() *DriverState {
if in == nil {
return nil
}
out := new(DriverState)
in.DeepCopyInto(out)
return out
}

View File

@@ -50,8 +50,6 @@ type Manager interface {
// ContainerInfo contains information required by the runtime to consume prepared resources. // ContainerInfo contains information required by the runtime to consume prepared resources.
type ContainerInfo struct { type ContainerInfo struct {
// The Annotations for the container
Annotations []kubecontainer.Annotation
// CDI Devices for the container // CDI Devices for the container
CDIDevices []kubecontainer.CDIDevice CDIDevices []kubecontainer.CDIDevice
} }

View File

@@ -21,29 +21,10 @@ limitations under the License.
package dra package dra
import (
container "k8s.io/kubernetes/pkg/kubelet/container"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ClaimInfo) DeepCopyInto(out *ClaimInfo) { func (in *ClaimInfo) DeepCopyInto(out *ClaimInfo) {
*out = *in *out = *in
in.ClaimInfoState.DeepCopyInto(&out.ClaimInfoState) in.ClaimInfoState.DeepCopyInto(&out.ClaimInfoState)
if in.annotations != nil {
in, out := &in.annotations, &out.annotations
*out = make(map[string][]container.Annotation, len(*in))
for key, val := range *in {
var outVal []container.Annotation
if val == nil {
(*out)[key] = nil
} else {
in, out := &val, &outVal
*out = make([]container.Annotation, len(*in))
copy(*out, *in)
}
(*out)[key] = outVal
}
}
return return
} }

View File

@@ -492,7 +492,8 @@ type DeviceInfo struct {
// CDIDevice contains information about CDI device // CDIDevice contains information about CDI device
type CDIDevice struct { type CDIDevice struct {
// Name is a fully qualified device name // Name is a fully qualified device name according to
// https://github.com/cncf-tags/container-device-interface/blob/e66544063aa7760c4ea6330ce9e6c757f8e61df2/README.md?plain=1#L9-L15
Name string Name string
} }

View File

@@ -145,9 +145,10 @@ func (m *NodePrepareResourcesResponse) GetClaims() map[string]*NodePrepareResour
type NodePrepareResourceResponse struct { type NodePrepareResourceResponse struct {
// These are the additional devices that kubelet must // These are the additional devices that kubelet must
// make available via the container runtime. A resource // make available via the container runtime. A claim
// may have zero or more requests and each request
// may have zero or more devices. // may have zero or more devices.
CDIDevices []string `protobuf:"bytes,1,rep,name=cdi_devices,json=cdiDevices,proto3" json:"cdi_devices,omitempty"` Devices []*Device `protobuf:"bytes,1,rep,name=devices,proto3" json:"devices,omitempty"`
// If non-empty, preparing the ResourceClaim failed. // If non-empty, preparing the ResourceClaim failed.
// cdi_devices is ignored in that case. // cdi_devices is ignored in that case.
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
@@ -187,9 +188,9 @@ func (m *NodePrepareResourceResponse) XXX_DiscardUnknown() {
var xxx_messageInfo_NodePrepareResourceResponse proto.InternalMessageInfo var xxx_messageInfo_NodePrepareResourceResponse proto.InternalMessageInfo
func (m *NodePrepareResourceResponse) GetCDIDevices() []string { func (m *NodePrepareResourceResponse) GetDevices() []*Device {
if m != nil { if m != nil {
return m.CDIDevices return m.Devices
} }
return nil return nil
} }
@@ -201,6 +202,81 @@ func (m *NodePrepareResourceResponse) GetError() string {
return "" return ""
} }
type Device struct {
// The requests in the claim that this device is associated with.
// Optional. If empty, the device is associated with all requests.
RequestNames []string `protobuf:"bytes,1,rep,name=request_names,json=requestNames,proto3" json:"request_names,omitempty"`
// The pool which contains the device. Required.
PoolName string `protobuf:"bytes,2,opt,name=pool_name,json=poolName,proto3" json:"pool_name,omitempty"`
// The device itself. Required.
DeviceName string `protobuf:"bytes,3,opt,name=device_name,json=deviceName,proto3" json:"device_name,omitempty"`
// A single device instance may map to several CDI device IDs.
// None is also valid.
CDIDeviceIDs []string `protobuf:"bytes,4,rep,name=cdi_device_ids,json=cdiDeviceIds,proto3" json:"cdi_device_ids,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Device) Reset() { *m = Device{} }
func (*Device) ProtoMessage() {}
func (*Device) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{3}
}
func (m *Device) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Device) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Device.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Device) XXX_Merge(src proto.Message) {
xxx_messageInfo_Device.Merge(m, src)
}
func (m *Device) XXX_Size() int {
return m.Size()
}
func (m *Device) XXX_DiscardUnknown() {
xxx_messageInfo_Device.DiscardUnknown(m)
}
var xxx_messageInfo_Device proto.InternalMessageInfo
func (m *Device) GetRequestNames() []string {
if m != nil {
return m.RequestNames
}
return nil
}
func (m *Device) GetPoolName() string {
if m != nil {
return m.PoolName
}
return ""
}
func (m *Device) GetDeviceName() string {
if m != nil {
return m.DeviceName
}
return ""
}
func (m *Device) GetCDIDeviceIDs() []string {
if m != nil {
return m.CDIDeviceIDs
}
return nil
}
type NodeUnprepareResourcesRequest struct { type NodeUnprepareResourcesRequest struct {
// The list of ResourceClaims that are to be unprepared. // The list of ResourceClaims that are to be unprepared.
Claims []*Claim `protobuf:"bytes,1,rep,name=claims,proto3" json:"claims,omitempty"` Claims []*Claim `protobuf:"bytes,1,rep,name=claims,proto3" json:"claims,omitempty"`
@@ -211,7 +287,7 @@ type NodeUnprepareResourcesRequest struct {
func (m *NodeUnprepareResourcesRequest) Reset() { *m = NodeUnprepareResourcesRequest{} } func (m *NodeUnprepareResourcesRequest) Reset() { *m = NodeUnprepareResourcesRequest{} }
func (*NodeUnprepareResourcesRequest) ProtoMessage() {} func (*NodeUnprepareResourcesRequest) ProtoMessage() {}
func (*NodeUnprepareResourcesRequest) Descriptor() ([]byte, []int) { func (*NodeUnprepareResourcesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{3} return fileDescriptor_00212fb1f9d3bf1c, []int{4}
} }
func (m *NodeUnprepareResourcesRequest) XXX_Unmarshal(b []byte) error { func (m *NodeUnprepareResourcesRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@@ -259,7 +335,7 @@ type NodeUnprepareResourcesResponse struct {
func (m *NodeUnprepareResourcesResponse) Reset() { *m = NodeUnprepareResourcesResponse{} } func (m *NodeUnprepareResourcesResponse) Reset() { *m = NodeUnprepareResourcesResponse{} }
func (*NodeUnprepareResourcesResponse) ProtoMessage() {} func (*NodeUnprepareResourcesResponse) ProtoMessage() {}
func (*NodeUnprepareResourcesResponse) Descriptor() ([]byte, []int) { func (*NodeUnprepareResourcesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{4} return fileDescriptor_00212fb1f9d3bf1c, []int{5}
} }
func (m *NodeUnprepareResourcesResponse) XXX_Unmarshal(b []byte) error { func (m *NodeUnprepareResourcesResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@@ -305,7 +381,7 @@ type NodeUnprepareResourceResponse struct {
func (m *NodeUnprepareResourceResponse) Reset() { *m = NodeUnprepareResourceResponse{} } func (m *NodeUnprepareResourceResponse) Reset() { *m = NodeUnprepareResourceResponse{} }
func (*NodeUnprepareResourceResponse) ProtoMessage() {} func (*NodeUnprepareResourceResponse) ProtoMessage() {}
func (*NodeUnprepareResourceResponse) Descriptor() ([]byte, []int) { func (*NodeUnprepareResourceResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{5} return fileDescriptor_00212fb1f9d3bf1c, []int{6}
} }
func (m *NodeUnprepareResourceResponse) XXX_Unmarshal(b []byte) error { func (m *NodeUnprepareResourceResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@@ -347,7 +423,7 @@ type Claim struct {
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
// The UID of the Resource claim (ResourceClaim.meta.UUID). // The UID of the Resource claim (ResourceClaim.meta.UUID).
// This field is REQUIRED. // This field is REQUIRED.
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` UID string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`
// The name of the Resource claim (ResourceClaim.meta.Name) // The name of the Resource claim (ResourceClaim.meta.Name)
// This field is REQUIRED. // This field is REQUIRED.
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
@@ -358,7 +434,7 @@ type Claim struct {
func (m *Claim) Reset() { *m = Claim{} } func (m *Claim) Reset() { *m = Claim{} }
func (*Claim) ProtoMessage() {} func (*Claim) ProtoMessage() {}
func (*Claim) Descriptor() ([]byte, []int) { func (*Claim) Descriptor() ([]byte, []int) {
return fileDescriptor_00212fb1f9d3bf1c, []int{6} return fileDescriptor_00212fb1f9d3bf1c, []int{7}
} }
func (m *Claim) XXX_Unmarshal(b []byte) error { func (m *Claim) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@@ -394,9 +470,9 @@ func (m *Claim) GetNamespace() string {
return "" return ""
} }
func (m *Claim) GetUid() string { func (m *Claim) GetUID() string {
if m != nil { if m != nil {
return m.Uid return m.UID
} }
return "" return ""
} }
@@ -413,6 +489,7 @@ func init() {
proto.RegisterType((*NodePrepareResourcesResponse)(nil), "v1alpha3.NodePrepareResourcesResponse") proto.RegisterType((*NodePrepareResourcesResponse)(nil), "v1alpha3.NodePrepareResourcesResponse")
proto.RegisterMapType((map[string]*NodePrepareResourceResponse)(nil), "v1alpha3.NodePrepareResourcesResponse.ClaimsEntry") proto.RegisterMapType((map[string]*NodePrepareResourceResponse)(nil), "v1alpha3.NodePrepareResourcesResponse.ClaimsEntry")
proto.RegisterType((*NodePrepareResourceResponse)(nil), "v1alpha3.NodePrepareResourceResponse") proto.RegisterType((*NodePrepareResourceResponse)(nil), "v1alpha3.NodePrepareResourceResponse")
proto.RegisterType((*Device)(nil), "v1alpha3.Device")
proto.RegisterType((*NodeUnprepareResourcesRequest)(nil), "v1alpha3.NodeUnprepareResourcesRequest") proto.RegisterType((*NodeUnprepareResourcesRequest)(nil), "v1alpha3.NodeUnprepareResourcesRequest")
proto.RegisterType((*NodeUnprepareResourcesResponse)(nil), "v1alpha3.NodeUnprepareResourcesResponse") proto.RegisterType((*NodeUnprepareResourcesResponse)(nil), "v1alpha3.NodeUnprepareResourcesResponse")
proto.RegisterMapType((map[string]*NodeUnprepareResourceResponse)(nil), "v1alpha3.NodeUnprepareResourcesResponse.ClaimsEntry") proto.RegisterMapType((map[string]*NodeUnprepareResourceResponse)(nil), "v1alpha3.NodeUnprepareResourcesResponse.ClaimsEntry")
@@ -423,38 +500,43 @@ func init() {
func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) }
var fileDescriptor_00212fb1f9d3bf1c = []byte{ var fileDescriptor_00212fb1f9d3bf1c = []byte{
// 481 bytes of a gzipped FileDescriptorProto // 566 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0x4d, 0x6f, 0xd3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcb, 0x6e, 0xd3, 0x4c,
0x10, 0xcd, 0x36, 0x4d, 0x85, 0x27, 0x12, 0xa0, 0x55, 0x85, 0xa2, 0x50, 0x4c, 0x64, 0x51, 0x92, 0x14, 0xce, 0x34, 0x97, 0xd6, 0x27, 0xf9, 0x7f, 0xa2, 0x51, 0x85, 0x42, 0x5a, 0x9c, 0xc8, 0x50,
0x0b, 0xb6, 0x48, 0x8b, 0x54, 0x81, 0xb8, 0xa4, 0x05, 0xf1, 0x25, 0x84, 0x2c, 0x71, 0xe1, 0x02, 0x12, 0x21, 0x11, 0x8b, 0xb4, 0xa0, 0x0a, 0xc4, 0x26, 0x0d, 0x88, 0x20, 0x54, 0x21, 0x8b, 0x6e,
0x6b, 0x7b, 0x70, 0x57, 0xf9, 0xd8, 0x65, 0xd7, 0x8e, 0xd4, 0x1b, 0x3f, 0x81, 0x9f, 0xd5, 0x03, 0xd8, 0x04, 0xc7, 0x1e, 0x52, 0x2b, 0x97, 0x19, 0x66, 0xe2, 0x48, 0xdd, 0xf1, 0x08, 0xbc, 0x03,
0x07, 0xc4, 0x89, 0x53, 0x45, 0xcd, 0x1f, 0x41, 0x5e, 0x3b, 0xe9, 0x87, 0x9c, 0x26, 0x52, 0x6f, 0x2f, 0xd3, 0x05, 0x0b, 0xc4, 0x8a, 0x55, 0x44, 0xcd, 0x8b, 0x20, 0xcf, 0xd8, 0x49, 0x5a, 0x39,
0x33, 0xe3, 0x9d, 0x79, 0x6f, 0xde, 0x1b, 0x19, 0x2c, 0x26, 0xb9, 0x2b, 0x95, 0x48, 0x04, 0xbd, 0x4d, 0x25, 0x76, 0x73, 0xbe, 0x73, 0xf9, 0xce, 0x9c, 0xef, 0xcc, 0x80, 0x66, 0x33, 0xaf, 0xc1,
0x31, 0x7d, 0xcc, 0x46, 0xf2, 0x90, 0xed, 0xb4, 0x1f, 0xc5, 0x3c, 0x39, 0x4c, 0x03, 0x37, 0x14, 0x38, 0x9d, 0x50, 0xbc, 0x35, 0x7d, 0x6c, 0x0f, 0xd9, 0xa9, 0xbd, 0x5f, 0x7e, 0xd4, 0xf7, 0x26,
0x63, 0x2f, 0x16, 0xb1, 0xf0, 0xcc, 0x83, 0x20, 0xfd, 0x6a, 0x32, 0x93, 0x98, 0xa8, 0x68, 0x74, 0xa7, 0x7e, 0xaf, 0xe1, 0xd0, 0x91, 0xd9, 0xa7, 0x7d, 0x6a, 0xca, 0x80, 0x9e, 0xff, 0x49, 0x5a,
0x5e, 0xc2, 0xdd, 0xf7, 0x22, 0xc2, 0x0f, 0x0a, 0x25, 0x53, 0xe8, 0xa3, 0x16, 0xa9, 0x0a, 0x51, 0xd2, 0x90, 0x27, 0x95, 0x68, 0xbc, 0x82, 0x9d, 0x63, 0xea, 0x92, 0x77, 0x9c, 0x30, 0x9b, 0x13,
0xfb, 0xf8, 0x2d, 0x45, 0x9d, 0xd0, 0x2e, 0x6c, 0x84, 0x23, 0xc6, 0xc7, 0xba, 0x45, 0x3a, 0xf5, 0x8b, 0x08, 0xea, 0x73, 0x87, 0x08, 0x8b, 0x7c, 0xf6, 0x89, 0x98, 0xe0, 0x1a, 0xe4, 0x9c, 0xa1,
0x5e, 0xb3, 0x7f, 0xcb, 0x9d, 0x01, 0xb9, 0xfb, 0x79, 0xdd, 0x2f, 0x3f, 0x3b, 0x3f, 0x09, 0x6c, 0xed, 0x8d, 0x44, 0x09, 0x55, 0xd3, 0xf5, 0x7c, 0xf3, 0x56, 0x23, 0x26, 0x6a, 0x1c, 0x85, 0xb8,
0x55, 0x0f, 0xd2, 0x52, 0x4c, 0x34, 0xd2, 0x37, 0x97, 0x26, 0xf5, 0xcf, 0x26, 0x5d, 0xd5, 0x57, 0x15, 0xb9, 0x8d, 0xef, 0x08, 0x76, 0x93, 0x0b, 0x09, 0x46, 0xc7, 0x82, 0xe0, 0x37, 0x57, 0x2a,
0xc0, 0xe8, 0x17, 0x93, 0x44, 0x1d, 0xcd, 0xc0, 0xda, 0x5f, 0xa0, 0x79, 0xae, 0x4c, 0x6f, 0x43, 0x35, 0x17, 0x95, 0xae, 0xcb, 0x53, 0x34, 0xe2, 0xe5, 0x78, 0xc2, 0xcf, 0x62, 0xb2, 0xf2, 0x47,
0x7d, 0x88, 0x47, 0x2d, 0xd2, 0x21, 0x3d, 0xcb, 0xcf, 0x43, 0xfa, 0x0c, 0x1a, 0x53, 0x36, 0x4a, 0xc8, 0x2f, 0xc1, 0xb8, 0x08, 0xe9, 0x01, 0x39, 0x2b, 0xa1, 0x2a, 0xaa, 0x6b, 0x56, 0x78, 0xc4,
0xb1, 0xb5, 0xd6, 0x21, 0xbd, 0x66, 0x7f, 0xfb, 0x4a, 0xac, 0x19, 0x94, 0x5f, 0xf4, 0x3c, 0x5d, 0xcf, 0x21, 0x3b, 0xb5, 0x87, 0x3e, 0x29, 0x6d, 0x54, 0x51, 0x3d, 0xdf, 0xdc, 0xbb, 0x96, 0x2b,
0xdb, 0x23, 0x4e, 0x54, 0x29, 0xcb, 0x7c, 0x19, 0x0f, 0x9a, 0x61, 0xc4, 0x3f, 0x47, 0x38, 0xe5, 0xa6, 0xb2, 0x54, 0xce, 0xb3, 0x8d, 0x43, 0x64, 0x74, 0x13, 0xc7, 0x32, 0xbf, 0xcc, 0x43, 0xd8,
0x21, 0x16, 0x1b, 0x59, 0x83, 0x9b, 0xd9, 0xc9, 0x7d, 0xd8, 0x3f, 0x78, 0x7d, 0x50, 0x54, 0x7d, 0x74, 0xc9, 0xd4, 0x73, 0x48, 0x7c, 0x9b, 0xe2, 0x82, 0xa1, 0x2d, 0x1d, 0x56, 0x1c, 0x80, 0xb7,
0x08, 0x23, 0x5e, 0xc6, 0x74, 0x13, 0x1a, 0xa8, 0x94, 0x50, 0x86, 0x90, 0xe5, 0x17, 0x89, 0xf3, 0x21, 0x4b, 0x38, 0xa7, 0x5c, 0xf6, 0xa2, 0x59, 0xca, 0x30, 0xbe, 0x21, 0xc8, 0xa9, 0x48, 0x7c,
0x0a, 0xee, 0xe5, 0x28, 0x1f, 0x27, 0xf2, 0xba, 0xf2, 0xff, 0x26, 0x60, 0x2f, 0x1a, 0x55, 0x72, 0x0f, 0xfe, 0xe3, 0x6a, 0xdc, 0xdd, 0xb1, 0x3d, 0x8a, 0x4a, 0x6a, 0x56, 0x21, 0x02, 0x8f, 0x43,
0x7e, 0x77, 0x69, 0xd6, 0xee, 0x45, 0x51, 0x16, 0x77, 0x56, 0x5a, 0x10, 0x2c, 0xb3, 0xe0, 0xf9, 0x0c, 0xef, 0x80, 0xc6, 0x28, 0x1d, 0xca, 0x88, 0xa8, 0xd2, 0x56, 0x08, 0x84, 0x5e, 0x5c, 0x81,
0x45, 0x0b, 0xba, 0x4b, 0xd0, 0xaa, 0x4c, 0x78, 0xb2, 0x40, 0x9e, 0xf9, 0x4a, 0x73, 0x55, 0xc9, 0xbc, 0x62, 0x53, 0xee, 0xb4, 0x74, 0x83, 0x82, 0x64, 0xc0, 0x53, 0xf8, 0xdf, 0x71, 0xbd, 0x6e,
0x79, 0x55, 0xdf, 0x42, 0xc3, 0x50, 0xa3, 0x5b, 0x60, 0x4d, 0xd8, 0x18, 0xb5, 0x64, 0x21, 0x96, 0x14, 0xe4, 0xb9, 0xa2, 0x94, 0x09, 0x39, 0x5a, 0xc5, 0x60, 0x56, 0x29, 0x1c, 0xb5, 0x3b, 0xaa,
0x4f, 0xce, 0x0a, 0x39, 0xe5, 0x94, 0x47, 0xa5, 0x21, 0x79, 0x48, 0x29, 0xac, 0xe7, 0x9f, 0x5b, 0x93, 0x4e, 0x5b, 0x58, 0x05, 0xc7, 0xf5, 0x22, 0xcb, 0x15, 0xc6, 0x6b, 0xb8, 0x1b, 0x8e, 0xe1,
0x75, 0x53, 0x32, 0x71, 0xff, 0x84, 0xc0, 0x7a, 0x4e, 0x82, 0xc6, 0xb0, 0x59, 0x75, 0xa7, 0x74, 0x64, 0xcc, 0xfe, 0x75, 0x3f, 0x7e, 0x22, 0xd0, 0x57, 0x95, 0x8a, 0x86, 0xfa, 0xf6, 0x4a, 0xad,
0x7b, 0xd9, 0x1d, 0x1b, 0x27, 0xdb, 0x0f, 0x57, 0x3b, 0x77, 0xa7, 0x46, 0xc7, 0x70, 0xa7, 0xda, 0x83, 0xcb, 0xaa, 0xad, 0xce, 0x4c, 0xdc, 0x91, 0xde, 0xba, 0x1d, 0x79, 0x71, 0x79, 0x47, 0x6a,
0x0f, 0xda, 0x5d, 0xee, 0x58, 0x01, 0xd6, 0x5b, 0xd5, 0x5a, 0xa7, 0x36, 0x18, 0x1c, 0x9f, 0xda, 0x6b, 0xd8, 0x92, 0xb6, 0xe4, 0xc9, 0x8a, 0xf1, 0xcc, 0xaf, 0x34, 0xd7, 0x1e, 0x2d, 0x6b, 0xff,
0xe4, 0xcf, 0xa9, 0x5d, 0xfb, 0x9e, 0xd9, 0xe4, 0x38, 0xb3, 0xc9, 0xaf, 0xcc, 0x26, 0x7f, 0x33, 0x1e, 0xb2, 0xb2, 0x35, 0xbc, 0x0b, 0x9a, 0x54, 0x9c, 0xd9, 0x0e, 0x89, 0x42, 0x16, 0x00, 0xbe,
0x9b, 0xfc, 0xf8, 0x67, 0xd7, 0x3e, 0x3d, 0x18, 0xee, 0x69, 0x97, 0x0b, 0x6f, 0x98, 0x06, 0x38, 0x03, 0x69, 0xdf, 0x73, 0x95, 0xd8, 0xad, 0xcd, 0x60, 0x56, 0x49, 0x9f, 0x74, 0xda, 0x56, 0x88,
0xc2, 0xc4, 0x93, 0xc3, 0xd8, 0x63, 0x92, 0x6b, 0x2f, 0x52, 0xcc, 0x2b, 0x41, 0x76, 0x83, 0x0d, 0x61, 0x0c, 0x99, 0x25, 0xa5, 0xe5, 0xb9, 0x39, 0x43, 0x90, 0x09, 0xbb, 0xc1, 0x7d, 0xd8, 0x4e,
0xf3, 0x2f, 0xd9, 0xf9, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x65, 0xc5, 0xc2, 0x0e, 0x91, 0x04, 0x00, 0x7a, 0x51, 0x78, 0x6f, 0xdd, 0x8b, 0x93, 0x92, 0x96, 0x1f, 0xdc, 0xec, 0x61, 0x1a, 0x29, 0x3c,
0x00, 0x82, 0xdb, 0xc9, 0xc2, 0xe0, 0xda, 0x7a, 0xe9, 0x14, 0x59, 0xfd, 0xa6, 0x1a, 0x1b, 0xa9, 0x56,
0xeb, 0xfc, 0x42, 0x47, 0xbf, 0x2e, 0xf4, 0xd4, 0x97, 0x40, 0x47, 0xe7, 0x81, 0x8e, 0x7e, 0x04,
0x3a, 0xfa, 0x1d, 0xe8, 0xe8, 0xeb, 0x1f, 0x3d, 0xf5, 0xe1, 0xfe, 0xe0, 0x50, 0x34, 0x3c, 0x6a,
0x0e, 0xfc, 0x1e, 0x19, 0x92, 0x89, 0xc9, 0x06, 0x7d, 0xd3, 0x66, 0x9e, 0x30, 0x5d, 0x6e, 0x9b,
0x11, 0xc9, 0x41, 0x2f, 0x27, 0x7f, 0xbd, 0xfd, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x91, 0xf3,
0x7a, 0xa9, 0x3b, 0x05, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@@ -698,11 +780,71 @@ func (m *NodePrepareResourceResponse) MarshalToSizedBuffer(dAtA []byte) (int, er
i-- i--
dAtA[i] = 0x12 dAtA[i] = 0x12
} }
if len(m.CDIDevices) > 0 { if len(m.Devices) > 0 {
for iNdEx := len(m.CDIDevices) - 1; iNdEx >= 0; iNdEx-- { for iNdEx := len(m.Devices) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.CDIDevices[iNdEx]) {
copy(dAtA[i:], m.CDIDevices[iNdEx]) size, err := m.Devices[iNdEx].MarshalToSizedBuffer(dAtA[:i])
i = encodeVarintApi(dAtA, i, uint64(len(m.CDIDevices[iNdEx]))) if err != nil {
return 0, err
}
i -= size
i = encodeVarintApi(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func (m *Device) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Device) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Device) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if len(m.CDIDeviceIDs) > 0 {
for iNdEx := len(m.CDIDeviceIDs) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.CDIDeviceIDs[iNdEx])
copy(dAtA[i:], m.CDIDeviceIDs[iNdEx])
i = encodeVarintApi(dAtA, i, uint64(len(m.CDIDeviceIDs[iNdEx])))
i--
dAtA[i] = 0x22
}
}
if len(m.DeviceName) > 0 {
i -= len(m.DeviceName)
copy(dAtA[i:], m.DeviceName)
i = encodeVarintApi(dAtA, i, uint64(len(m.DeviceName)))
i--
dAtA[i] = 0x1a
}
if len(m.PoolName) > 0 {
i -= len(m.PoolName)
copy(dAtA[i:], m.PoolName)
i = encodeVarintApi(dAtA, i, uint64(len(m.PoolName)))
i--
dAtA[i] = 0x12
}
if len(m.RequestNames) > 0 {
for iNdEx := len(m.RequestNames) - 1; iNdEx >= 0; iNdEx-- {
i -= len(m.RequestNames[iNdEx])
copy(dAtA[i:], m.RequestNames[iNdEx])
i = encodeVarintApi(dAtA, i, uint64(len(m.RequestNames[iNdEx])))
i-- i--
dAtA[i] = 0xa dAtA[i] = 0xa
} }
@@ -853,10 +995,10 @@ func (m *Claim) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i-- i--
dAtA[i] = 0x1a dAtA[i] = 0x1a
} }
if len(m.Uid) > 0 { if len(m.UID) > 0 {
i -= len(m.Uid) i -= len(m.UID)
copy(dAtA[i:], m.Uid) copy(dAtA[i:], m.UID)
i = encodeVarintApi(dAtA, i, uint64(len(m.Uid))) i = encodeVarintApi(dAtA, i, uint64(len(m.UID)))
i-- i--
dAtA[i] = 0x12 dAtA[i] = 0x12
} }
@@ -924,9 +1066,9 @@ func (m *NodePrepareResourceResponse) Size() (n int) {
} }
var l int var l int
_ = l _ = l
if len(m.CDIDevices) > 0 { if len(m.Devices) > 0 {
for _, s := range m.CDIDevices { for _, e := range m.Devices {
l = len(s) l = e.Size()
n += 1 + l + sovApi(uint64(l)) n += 1 + l + sovApi(uint64(l))
} }
} }
@@ -937,6 +1079,35 @@ func (m *NodePrepareResourceResponse) Size() (n int) {
return n return n
} }
func (m *Device) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.RequestNames) > 0 {
for _, s := range m.RequestNames {
l = len(s)
n += 1 + l + sovApi(uint64(l))
}
}
l = len(m.PoolName)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
l = len(m.DeviceName)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
if len(m.CDIDeviceIDs) > 0 {
for _, s := range m.CDIDeviceIDs {
l = len(s)
n += 1 + l + sovApi(uint64(l))
}
}
return n
}
func (m *NodeUnprepareResourcesRequest) Size() (n int) { func (m *NodeUnprepareResourcesRequest) Size() (n int) {
if m == nil { if m == nil {
return 0 return 0
@@ -997,7 +1168,7 @@ func (m *Claim) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovApi(uint64(l)) n += 1 + l + sovApi(uint64(l))
} }
l = len(m.Uid) l = len(m.UID)
if l > 0 { if l > 0 {
n += 1 + l + sovApi(uint64(l)) n += 1 + l + sovApi(uint64(l))
} }
@@ -1053,13 +1224,31 @@ func (this *NodePrepareResourceResponse) String() string {
if this == nil { if this == nil {
return "nil" return "nil"
} }
repeatedStringForDevices := "[]*Device{"
for _, f := range this.Devices {
repeatedStringForDevices += strings.Replace(f.String(), "Device", "Device", 1) + ","
}
repeatedStringForDevices += "}"
s := strings.Join([]string{`&NodePrepareResourceResponse{`, s := strings.Join([]string{`&NodePrepareResourceResponse{`,
`CDIDevices:` + fmt.Sprintf("%v", this.CDIDevices) + `,`, `Devices:` + repeatedStringForDevices + `,`,
`Error:` + fmt.Sprintf("%v", this.Error) + `,`, `Error:` + fmt.Sprintf("%v", this.Error) + `,`,
`}`, `}`,
}, "") }, "")
return s return s
} }
func (this *Device) String() string {
if this == nil {
return "nil"
}
s := strings.Join([]string{`&Device{`,
`RequestNames:` + fmt.Sprintf("%v", this.RequestNames) + `,`,
`PoolName:` + fmt.Sprintf("%v", this.PoolName) + `,`,
`DeviceName:` + fmt.Sprintf("%v", this.DeviceName) + `,`,
`CDIDeviceIDs:` + fmt.Sprintf("%v", this.CDIDeviceIDs) + `,`,
`}`,
}, "")
return s
}
func (this *NodeUnprepareResourcesRequest) String() string { func (this *NodeUnprepareResourcesRequest) String() string {
if this == nil { if this == nil {
return "nil" return "nil"
@@ -1111,7 +1300,7 @@ func (this *Claim) String() string {
} }
s := strings.Join([]string{`&Claim{`, s := strings.Join([]string{`&Claim{`,
`Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`, `Namespace:` + fmt.Sprintf("%v", this.Namespace) + `,`,
`Uid:` + fmt.Sprintf("%v", this.Uid) + `,`, `UID:` + fmt.Sprintf("%v", this.UID) + `,`,
`Name:` + fmt.Sprintf("%v", this.Name) + `,`, `Name:` + fmt.Sprintf("%v", this.Name) + `,`,
`}`, `}`,
}, "") }, "")
@@ -1419,9 +1608,9 @@ func (m *NodePrepareResourceResponse) Unmarshal(dAtA []byte) error {
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CDIDevices", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Devices", wireType)
} }
var stringLen uint64 var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflowApi return ErrIntOverflowApi
@@ -1431,23 +1620,25 @@ func (m *NodePrepareResourceResponse) Unmarshal(dAtA []byte) error {
} }
b := dAtA[iNdEx] b := dAtA[iNdEx]
iNdEx++ iNdEx++
stringLen |= uint64(b&0x7F) << shift msglen |= int(b&0x7F) << shift
if b < 0x80 { if b < 0x80 {
break break
} }
} }
intStringLen := int(stringLen) if msglen < 0 {
if intStringLen < 0 {
return ErrInvalidLengthApi return ErrInvalidLengthApi
} }
postIndex := iNdEx + intStringLen postIndex := iNdEx + msglen
if postIndex < 0 { if postIndex < 0 {
return ErrInvalidLengthApi return ErrInvalidLengthApi
} }
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.CDIDevices = append(m.CDIDevices, string(dAtA[iNdEx:postIndex])) m.Devices = append(m.Devices, &Device{})
if err := m.Devices[len(m.Devices)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex iNdEx = postIndex
case 2: case 2:
if wireType != 2 { if wireType != 2 {
@@ -1502,6 +1693,184 @@ func (m *NodePrepareResourceResponse) Unmarshal(dAtA []byte) error {
} }
return nil return nil
} }
func (m *Device) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Device: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Device: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field RequestNames", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApi
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.RequestNames = append(m.RequestNames, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PoolName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApi
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.PoolName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field DeviceName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApi
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.DeviceName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field CDIDeviceIDs", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApi
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.CDIDeviceIDs = append(m.CDIDeviceIDs, string(dAtA[iNdEx:postIndex]))
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipApi(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthApi
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *NodeUnprepareResourcesRequest) Unmarshal(dAtA []byte) error { func (m *NodeUnprepareResourcesRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA) l := len(dAtA)
iNdEx := 0 iNdEx := 0
@@ -1910,7 +2279,7 @@ func (m *Claim) Unmarshal(dAtA []byte) error {
iNdEx = postIndex iNdEx = postIndex
case 2: case 2:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Uid", wireType) return fmt.Errorf("proto: wrong wireType = %d for field UID", wireType)
} }
var stringLen uint64 var stringLen uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@@ -1938,7 +2307,7 @@ func (m *Claim) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Uid = string(dAtA[iNdEx:postIndex]) m.UID = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 3: case 3:
if wireType != 2 { if wireType != 2 {

View File

@@ -62,14 +62,31 @@ message NodePrepareResourcesResponse {
message NodePrepareResourceResponse { message NodePrepareResourceResponse {
// These are the additional devices that kubelet must // These are the additional devices that kubelet must
// make available via the container runtime. A resource // make available via the container runtime. A claim
// may have zero or more requests and each request
// may have zero or more devices. // may have zero or more devices.
repeated string cdi_devices = 1 [(gogoproto.customname) = "CDIDevices"]; repeated Device devices = 1;
// If non-empty, preparing the ResourceClaim failed. // If non-empty, preparing the ResourceClaim failed.
// cdi_devices is ignored in that case. // cdi_devices is ignored in that case.
string error = 2; string error = 2;
} }
message Device {
// The requests in the claim that this device is associated with.
// Optional. If empty, the device is associated with all requests.
repeated string request_names = 1;
// The pool which contains the device. Required.
string pool_name = 2;
// The device itself. Required.
string device_name = 3;
// A single device instance may map to several CDI device IDs.
// None is also valid.
repeated string cdi_device_ids = 4 [(gogoproto.customname) = "CDIDeviceIDs"];
}
message NodeUnprepareResourcesRequest { message NodeUnprepareResourcesRequest {
// The list of ResourceClaims that are to be unprepared. // The list of ResourceClaims that are to be unprepared.
repeated Claim claims = 1; repeated Claim claims = 1;
@@ -93,7 +110,7 @@ message Claim {
string namespace = 1; string namespace = 1;
// The UID of the Resource claim (ResourceClaim.meta.UUID). // The UID of the Resource claim (ResourceClaim.meta.UUID).
// This field is REQUIRED. // This field is REQUIRED.
string uid = 2; string uid = 2 [(gogoproto.customname) = "UID"];
// The name of the Resource claim (ResourceClaim.meta.Name) // The name of the Resource claim (ResourceClaim.meta.Name)
// This field is REQUIRED. // This field is REQUIRED.
string name = 3; string name = 3;

View File

@@ -586,7 +586,8 @@ func (m *NUMANode) GetID() int64 {
// DynamicResource contains information about the devices assigned to a container by DRA // DynamicResource contains information about the devices assigned to a container by DRA
type DynamicResource struct { type DynamicResource struct {
ClassName string `protobuf:"bytes,1,opt,name=class_name,json=className,proto3" json:"class_name,omitempty"` // tombstone: removed in 1.31 because claims are no longer associated with one class
// string class_name = 1;
ClaimName string `protobuf:"bytes,2,opt,name=claim_name,json=claimName,proto3" json:"claim_name,omitempty"` ClaimName string `protobuf:"bytes,2,opt,name=claim_name,json=claimName,proto3" json:"claim_name,omitempty"`
ClaimNamespace string `protobuf:"bytes,3,opt,name=claim_namespace,json=claimNamespace,proto3" json:"claim_namespace,omitempty"` ClaimNamespace string `protobuf:"bytes,3,opt,name=claim_namespace,json=claimNamespace,proto3" json:"claim_namespace,omitempty"`
ClaimResources []*ClaimResource `protobuf:"bytes,4,rep,name=claim_resources,json=claimResources,proto3" json:"claim_resources,omitempty"` ClaimResources []*ClaimResource `protobuf:"bytes,4,rep,name=claim_resources,json=claimResources,proto3" json:"claim_resources,omitempty"`
@@ -626,13 +627,6 @@ func (m *DynamicResource) XXX_DiscardUnknown() {
var xxx_messageInfo_DynamicResource proto.InternalMessageInfo var xxx_messageInfo_DynamicResource proto.InternalMessageInfo
func (m *DynamicResource) GetClassName() string {
if m != nil {
return m.ClassName
}
return ""
}
func (m *DynamicResource) GetClaimName() string { func (m *DynamicResource) GetClaimName() string {
if m != nil { if m != nil {
return m.ClaimName return m.ClaimName
@@ -654,9 +648,15 @@ func (m *DynamicResource) GetClaimResources() []*ClaimResource {
return nil return nil
} }
// ClaimResource contains per plugin resource information // ClaimResource contains resource information. The driver name/pool name/device name
// triplet uniquely identifies the device. Should DRA get extended to other kinds
// of resources, then device_name will be empty and other fields will get added.
// Each device at the DRA API level may map to zero or more CDI devices.
type ClaimResource struct { type ClaimResource struct {
CDIDevices []*CDIDevice `protobuf:"bytes,1,rep,name=cdi_devices,json=cdiDevices,proto3" json:"cdi_devices,omitempty"` CDIDevices []*CDIDevice `protobuf:"bytes,1,rep,name=cdi_devices,json=cdiDevices,proto3" json:"cdi_devices,omitempty"`
DriverName string `protobuf:"bytes,2,opt,name=driver_name,json=driverName,proto3" json:"driver_name,omitempty"`
PoolName string `protobuf:"bytes,3,opt,name=pool_name,json=poolName,proto3" json:"pool_name,omitempty"`
DeviceName string `protobuf:"bytes,4,opt,name=device_name,json=deviceName,proto3" json:"device_name,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
} }
@@ -700,6 +700,27 @@ func (m *ClaimResource) GetCDIDevices() []*CDIDevice {
return nil return nil
} }
func (m *ClaimResource) GetDriverName() string {
if m != nil {
return m.DriverName
}
return ""
}
func (m *ClaimResource) GetPoolName() string {
if m != nil {
return m.PoolName
}
return ""
}
func (m *ClaimResource) GetDeviceName() string {
if m != nil {
return m.DeviceName
}
return ""
}
// CDIDevice specifies a CDI device information // CDIDevice specifies a CDI device information
type CDIDevice struct { type CDIDevice struct {
// Fully qualified CDI device name // Fully qualified CDI device name
@@ -871,55 +892,57 @@ func init() {
func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) } func init() { proto.RegisterFile("api.proto", fileDescriptor_00212fb1f9d3bf1c) }
var fileDescriptor_00212fb1f9d3bf1c = []byte{ var fileDescriptor_00212fb1f9d3bf1c = []byte{
// 760 bytes of a gzipped FileDescriptorProto // 789 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x5d, 0x6f, 0x12, 0x4d, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0x4d, 0x6f, 0xda, 0x48,
0x14, 0xee, 0xb0, 0xf4, 0x83, 0x53, 0xe8, 0xc7, 0xbc, 0x6f, 0x5a, 0x4a, 0x5b, 0x20, 0xdb, 0x8b, 0x18, 0xce, 0x60, 0x92, 0xc0, 0x0b, 0xe4, 0x63, 0x76, 0x95, 0x10, 0x48, 0x00, 0x39, 0x87, 0x44,
0x36, 0x51, 0x21, 0xad, 0xd1, 0x18, 0x2f, 0x4c, 0x3f, 0x30, 0x0d, 0x89, 0xad, 0x75, 0x53, 0x13, 0xda, 0x5d, 0x50, 0xb2, 0xda, 0xd5, 0x6a, 0x0f, 0xab, 0x7c, 0xb0, 0x8a, 0x90, 0x36, 0x51, 0xd6,
0xe3, 0x85, 0x64, 0xd9, 0x9d, 0xe2, 0xa4, 0xc0, 0x8c, 0xcc, 0x42, 0xc4, 0x2b, 0x2f, 0xfc, 0x01, 0x4a, 0xa5, 0xaa, 0x87, 0x22, 0x63, 0x4f, 0xa8, 0x15, 0x60, 0xa6, 0x1e, 0x83, 0x4a, 0x4f, 0x3d,
0x5e, 0xf8, 0x53, 0xfc, 0x11, 0xbd, 0xf4, 0xd2, 0x2b, 0xd3, 0xe2, 0xcf, 0xf0, 0xc6, 0xcc, 0x0c, 0xf4, 0x07, 0xf4, 0xd0, 0xfe, 0x8d, 0xfe, 0x8e, 0x1c, 0x7b, 0xec, 0xa9, 0x4a, 0xe8, 0xcf, 0xe8,
0xbb, 0x2c, 0xb0, 0xd8, 0xf4, 0x8a, 0x99, 0xf3, 0x3c, 0xe7, 0x70, 0xce, 0x73, 0xce, 0x9c, 0x85, 0xa5, 0x9a, 0x19, 0xdb, 0x18, 0x30, 0x8d, 0x72, 0x62, 0xe6, 0x79, 0x9e, 0xf7, 0x9d, 0xf7, 0x8b,
0x84, 0xcd, 0x69, 0x81, 0xb7, 0x98, 0xc7, 0x70, 0xac, 0xb3, 0x9b, 0x79, 0x50, 0xa3, 0xde, 0xfb, 0xd7, 0x90, 0x36, 0x99, 0x53, 0x65, 0x2e, 0xf5, 0x28, 0x4e, 0x0c, 0x0e, 0x0a, 0xbf, 0xb5, 0x1d,
0x76, 0xb5, 0xe0, 0xb0, 0x46, 0xb1, 0xc6, 0x6a, 0xac, 0xa8, 0xa0, 0x6a, 0xfb, 0x42, 0xdd, 0xd4, 0xef, 0x45, 0xbf, 0x55, 0xb5, 0x68, 0xb7, 0xd6, 0xa6, 0x6d, 0x5a, 0x93, 0x54, 0xab, 0x7f, 0x2d,
0x45, 0x9d, 0xb4, 0x8b, 0xb9, 0x09, 0xeb, 0x07, 0xf5, 0x3a, 0x73, 0x6c, 0xcf, 0xae, 0xd6, 0x89, 0x6f, 0xf2, 0x22, 0x4f, 0xca, 0x44, 0xdf, 0x81, 0xe2, 0x71, 0xa7, 0x43, 0x2d, 0xd3, 0x33, 0x5b,
0x45, 0x04, 0x6b, 0xb7, 0x1c, 0x22, 0x2c, 0xf2, 0xa1, 0x4d, 0x84, 0x67, 0x7e, 0x43, 0xb0, 0x11, 0x1d, 0x62, 0x10, 0x4e, 0xfb, 0xae, 0x45, 0xb8, 0x41, 0x5e, 0xf6, 0x09, 0xf7, 0xf4, 0xf7, 0x08,
0x8d, 0x0b, 0xce, 0x9a, 0x82, 0xe0, 0x02, 0xcc, 0xba, 0xa4, 0x43, 0x1d, 0x22, 0xd2, 0x28, 0x6f, 0xb6, 0xe3, 0x79, 0xce, 0x68, 0x8f, 0x13, 0x5c, 0x85, 0x65, 0x9b, 0x0c, 0x1c, 0x8b, 0xf0, 0x3c,
0xec, 0xcc, 0xef, 0xfd, 0x5f, 0xe8, 0xec, 0x16, 0x8e, 0x58, 0xd3, 0xb3, 0x69, 0x93, 0xb4, 0x4a, 0xaa, 0x68, 0xfb, 0x99, 0xc3, 0x9f, 0xab, 0x83, 0x83, 0xea, 0x29, 0xed, 0x79, 0xa6, 0xd3, 0x23,
0x1a, 0xb3, 0x7c, 0x12, 0x5e, 0x85, 0x59, 0x87, 0xb7, 0x2b, 0xd4, 0x15, 0xe9, 0x58, 0xde, 0xd8, 0x6e, 0x5d, 0x71, 0x46, 0x20, 0xc2, 0x9b, 0xb0, 0x6c, 0xb1, 0x7e, 0xd3, 0xb1, 0x79, 0x3e, 0x51,
0x31, 0xac, 0x19, 0x87, 0xb7, 0xcb, 0xae, 0xc0, 0xf7, 0x60, 0xa6, 0x41, 0x1a, 0xac, 0xd5, 0x4d, 0xd1, 0xf6, 0x35, 0x63, 0xc9, 0x62, 0xfd, 0x86, 0xcd, 0xf1, 0x2f, 0xb0, 0xd4, 0x25, 0x5d, 0xea,
0x1b, 0x2a, 0xce, 0x7f, 0x43, 0x71, 0x4e, 0x14, 0x64, 0xf5, 0x29, 0xe6, 0x1a, 0xac, 0xbe, 0xa0, 0x0e, 0xf3, 0x9a, 0xf4, 0xf3, 0xd3, 0x84, 0x9f, 0x73, 0x49, 0x19, 0xbe, 0x44, 0xdf, 0x82, 0xcd,
0xc2, 0x3b, 0x63, 0xee, 0x58, 0xc6, 0xaf, 0x20, 0x3d, 0x0e, 0xf5, 0x93, 0x7d, 0x04, 0x29, 0xce, 0xff, 0x1c, 0xee, 0x5d, 0x52, 0x7b, 0x26, 0xe2, 0xff, 0x21, 0x3f, 0x4b, 0xf9, 0xc1, 0xfe, 0x01,
0xdc, 0x4a, 0xcb, 0x07, 0xfa, 0x29, 0x2f, 0xc9, 0xbf, 0x1a, 0x72, 0x48, 0xf2, 0xd0, 0xcd, 0xfc, 0x39, 0x46, 0xed, 0xa6, 0x1b, 0x10, 0x7e, 0xc8, 0x6b, 0xe2, 0xa9, 0x09, 0x83, 0x2c, 0x8b, 0xdc,
0x08, 0xc9, 0x30, 0x8a, 0x31, 0xc4, 0x9b, 0x76, 0x83, 0xa4, 0x51, 0x1e, 0xed, 0x24, 0x2c, 0x75, 0xf4, 0x57, 0x90, 0x8d, 0xb2, 0x18, 0x43, 0xb2, 0x67, 0x76, 0x49, 0x1e, 0x55, 0xd0, 0x7e, 0xda,
0xc6, 0x1b, 0x90, 0x90, 0xbf, 0x82, 0xdb, 0x0e, 0x49, 0xc7, 0x14, 0x30, 0x30, 0xe0, 0xc7, 0x00, 0x90, 0x67, 0xbc, 0x0d, 0x69, 0xf1, 0xcb, 0x99, 0x69, 0x91, 0x7c, 0x42, 0x12, 0x63, 0x00, 0xff,
0x8e, 0x5f, 0x8a, 0xe8, 0x17, 0xb8, 0x32, 0x54, 0xe0, 0xe0, 0xbf, 0x43, 0x4c, 0xf3, 0x1a, 0x01, 0x09, 0x60, 0x05, 0xa9, 0x70, 0x3f, 0xc1, 0x8d, 0x89, 0x04, 0xc7, 0x6f, 0x47, 0x94, 0xfa, 0x1d,
0x1e, 0xa7, 0x44, 0x26, 0x10, 0x6a, 0x44, 0xec, 0x8e, 0x8d, 0x30, 0x26, 0x34, 0x22, 0x7e, 0x6b, 0x02, 0x3c, 0x2b, 0x89, 0x0d, 0x20, 0xd2, 0x88, 0xc4, 0x23, 0x1b, 0xa1, 0xcd, 0x69, 0x44, 0xf2,
0x23, 0xf0, 0x3e, 0x2c, 0xbb, 0xdd, 0xa6, 0xdd, 0xa0, 0x4e, 0x48, 0xd5, 0xe9, 0x81, 0x5f, 0x49, 0xc1, 0x46, 0xe0, 0x23, 0x58, 0xb7, 0x87, 0x3d, 0xb3, 0xeb, 0x58, 0x91, 0xaa, 0x2e, 0x8e, 0xed,
0x83, 0x7e, 0xea, 0xd6, 0x92, 0x3b, 0x6c, 0x10, 0xa6, 0x07, 0x8b, 0x23, 0xc1, 0x71, 0x0e, 0xe6, 0xea, 0x8a, 0x0c, 0x42, 0x37, 0xd6, 0xec, 0x49, 0x80, 0xeb, 0x1e, 0xac, 0x4e, 0x39, 0xc7, 0x65,
0x75, 0xf8, 0x8a, 0xd7, 0xe5, 0x7e, 0x95, 0xa0, 0x4d, 0xe7, 0x5d, 0x4e, 0x64, 0xfd, 0x82, 0x7e, 0xc8, 0x28, 0xf7, 0x4d, 0x6f, 0xc8, 0x82, 0x2c, 0x41, 0x41, 0x57, 0x43, 0x46, 0x44, 0xfe, 0xdc,
0xd2, 0x3a, 0xc7, 0x2d, 0x75, 0xc6, 0xf7, 0x61, 0xce, 0x63, 0x9c, 0xd5, 0x59, 0x4d, 0x4e, 0x10, 0x79, 0xad, 0xea, 0x9c, 0x34, 0xe4, 0x19, 0xff, 0x0a, 0x29, 0x8f, 0x32, 0xda, 0xa1, 0x6d, 0x31,
0xf2, 0xdb, 0x7a, 0xde, 0xb7, 0x95, 0x9b, 0x17, 0xcc, 0x0a, 0x18, 0xe6, 0x17, 0x04, 0x4b, 0xa3, 0x41, 0x28, 0x68, 0xeb, 0x95, 0x8f, 0x35, 0x7a, 0xd7, 0xd4, 0x08, 0x15, 0xfa, 0x5b, 0x04, 0x6b,
0xda, 0xe0, 0x2d, 0x48, 0xf9, 0x45, 0x54, 0x42, 0xfa, 0x26, 0x7d, 0xe3, 0xa9, 0xd4, 0x79, 0x13, 0xd3, 0xb5, 0xc1, 0xbb, 0x90, 0x0b, 0x92, 0x68, 0x46, 0xea, 0x9b, 0x0d, 0xc0, 0x0b, 0x51, 0xe7,
0x40, 0x4b, 0x18, 0xcc, 0x70, 0xc2, 0x4a, 0x68, 0x8b, 0x54, 0xef, 0x6e, 0x69, 0xec, 0x41, 0x32, 0x1d, 0x00, 0x55, 0xc2, 0x70, 0x86, 0xd3, 0x46, 0x5a, 0x21, 0xa2, 0x7a, 0x8f, 0x0b, 0xe3, 0x10,
0x8c, 0x60, 0x13, 0xa6, 0x9b, 0xcc, 0x0d, 0x06, 0x33, 0x29, 0x5d, 0x4f, 0x5f, 0x9f, 0x1c, 0x9c, 0xb2, 0x51, 0x06, 0xeb, 0xb0, 0xd8, 0xa3, 0x76, 0x38, 0x98, 0x59, 0x61, 0x7a, 0xf1, 0xe4, 0xfc,
0x32, 0x97, 0x58, 0x1a, 0x32, 0x33, 0x30, 0xe7, 0x9b, 0xf0, 0x02, 0xc4, 0xca, 0x25, 0x95, 0xa6, 0xf8, 0x82, 0xda, 0xc4, 0x50, 0x94, 0x5e, 0x80, 0x54, 0x00, 0xe1, 0x15, 0x48, 0x34, 0xea, 0x32,
0x61, 0xc5, 0xca, 0x25, 0xf3, 0x3b, 0x82, 0xc5, 0x11, 0xc9, 0x65, 0xc2, 0x4e, 0xdd, 0x16, 0x22, 0x4c, 0xcd, 0x48, 0x34, 0xea, 0xfa, 0x07, 0x04, 0xab, 0x53, 0x25, 0x17, 0x01, 0x5b, 0x1d, 0xd3,
0x5c, 0x52, 0x42, 0x59, 0xfc, 0x7a, 0x9c, 0xba, 0x4d, 0x1b, 0x1a, 0x8e, 0x05, 0x30, 0x6d, 0x28, 0xe9, 0xaa, 0x94, 0xfc, 0xd1, 0x94, 0x88, 0xcc, 0x67, 0x0f, 0x56, 0xc7, 0xb4, 0x1a, 0x5f, 0x4d,
0x78, 0x1b, 0x16, 0x07, 0xb0, 0x9e, 0x6e, 0x43, 0x71, 0x16, 0x02, 0x8e, 0x1e, 0xf1, 0xa7, 0x3e, 0x6a, 0x56, 0x42, 0x8d, 0x9a, 0xe1, 0xbf, 0x03, 0xe1, 0xb8, 0xd1, 0x6a, 0x40, 0xd6, 0xe5, 0x80,
0x71, 0x30, 0x07, 0x7a, 0x7e, 0x96, 0xd5, 0xfc, 0x48, 0x28, 0x98, 0x02, 0xed, 0x3b, 0x98, 0x81, 0x08, 0x2a, 0x6c, 0xb3, 0xb2, 0x1d, 0x37, 0xf9, 0x23, 0x82, 0xdc, 0x84, 0x02, 0xff, 0x03, 0x19,
0x97, 0x90, 0x1a, 0x22, 0xe0, 0x67, 0x30, 0xef, 0xb8, 0xb4, 0x32, 0xbc, 0x59, 0x52, 0x2a, 0x50, 0xcb, 0x76, 0x9a, 0x93, 0xbb, 0x23, 0x27, 0x3d, 0xd5, 0x1b, 0xaa, 0x21, 0x27, 0x2b, 0xa3, 0x2f,
0xa9, 0xac, 0xdb, 0x75, 0xb8, 0xd0, 0xfb, 0x95, 0x83, 0xe0, 0x2a, 0xdf, 0x8d, 0x4b, 0xfb, 0x67, 0x65, 0x08, 0xaf, 0xe2, 0x9f, 0x61, 0x3b, 0x41, 0xaf, 0xca, 0x90, 0xb1, 0x5d, 0x67, 0x40, 0xdc,
0x33, 0x07, 0x89, 0x00, 0x89, 0x7a, 0x2d, 0xe6, 0x1b, 0x58, 0x39, 0x26, 0x51, 0xfb, 0x03, 0xaf, 0x68, 0x5a, 0xa0, 0x20, 0x99, 0x57, 0x11, 0xd2, 0x8c, 0xd2, 0x8e, 0xa2, 0x55, 0x46, 0x29, 0x01,
0xc1, 0x9c, 0xdc, 0x11, 0x21, 0x8f, 0x59, 0xce, 0x5c, 0xa5, 0xc5, 0x96, 0x5e, 0x1f, 0xa3, 0xef, 0x48, 0x52, 0x58, 0xab, 0x26, 0x4a, 0x3a, 0xe9, 0x5b, 0x4b, 0x48, 0x08, 0xf4, 0x32, 0xa4, 0xc3,
0x3c, 0xd9, 0xc7, 0x95, 0xcd, 0x3c, 0x83, 0xd5, 0xb1, 0xc8, 0x93, 0xd7, 0x0f, 0xba, 0x7d, 0xfd, 0x87, 0xe3, 0xfe, 0x6e, 0xfa, 0x53, 0xd8, 0x38, 0x23, 0x71, 0x0b, 0x08, 0x6f, 0x41, 0x4a, 0x2c,
0xec, 0xfd, 0x41, 0x80, 0xc3, 0xb0, 0x5c, 0x6f, 0xa4, 0x85, 0x8f, 0x20, 0x2e, 0x4f, 0x78, 0x5d, 0x99, 0x88, 0xc5, 0x32, 0xa3, 0xb6, 0x7c, 0x76, 0x57, 0xed, 0x9f, 0xe9, 0x45, 0x91, 0xf5, 0x79,
0xba, 0x4f, 0xd8, 0x86, 0x99, 0x8d, 0x68, 0x50, 0x27, 0x64, 0x4e, 0xe1, 0x77, 0x2a, 0xdb, 0xa8, 0x89, 0xe9, 0x97, 0xb0, 0x39, 0xe3, 0x79, 0xfe, 0xfe, 0x42, 0x0f, 0xef, 0xaf, 0xc3, 0x6f, 0x08,
0x0d, 0x8f, 0x73, 0xd2, 0xf5, 0x1f, 0xdf, 0x86, 0x4c, 0x7e, 0x32, 0x21, 0x88, 0xbf, 0x0f, 0xc6, 0x70, 0x94, 0x16, 0xfb, 0x91, 0xb8, 0xf8, 0x14, 0x92, 0xe2, 0x84, 0x8b, 0xc2, 0x7c, 0xce, 0x3a,
0x31, 0xf1, 0x70, 0x46, 0x52, 0xa3, 0x05, 0xcf, 0xac, 0x47, 0x62, 0x7e, 0x84, 0xc3, 0xe7, 0x57, 0x2d, 0x6c, 0xc7, 0x93, 0x2a, 0x20, 0x7d, 0x01, 0x3f, 0x97, 0xd1, 0xc6, 0x7d, 0x22, 0x70, 0x59,
0x37, 0x59, 0xf4, 0xf3, 0x26, 0x3b, 0xf5, 0xb9, 0x97, 0x45, 0x57, 0xbd, 0x2c, 0xfa, 0xd1, 0xcb, 0x98, 0xfe, 0xe0, 0xe3, 0x52, 0xa8, 0xcc, 0x17, 0x84, 0xfe, 0x8f, 0x40, 0x3b, 0x23, 0x1e, 0x2e,
0xa2, 0xeb, 0x5e, 0x16, 0x7d, 0xfd, 0x9d, 0x9d, 0x7a, 0xbb, 0x7d, 0xf9, 0x44, 0x14, 0x28, 0x2b, 0x08, 0x69, 0x7c, 0xc1, 0x0b, 0xc5, 0x58, 0x2e, 0xf0, 0x70, 0xf2, 0xef, 0xed, 0x7d, 0x09, 0x7d,
0x5e, 0xb6, 0xab, 0xa4, 0x4e, 0xbc, 0x22, 0xbf, 0xac, 0x15, 0x6d, 0x4e, 0x45, 0x91, 0x33, 0x37, 0xbe, 0x2f, 0x2d, 0xbc, 0x19, 0x95, 0xd0, 0xed, 0xa8, 0x84, 0x3e, 0x8d, 0x4a, 0xe8, 0x6e, 0x54,
0xd0, 0xb9, 0xd8, 0xd9, 0xad, 0xce, 0xa8, 0xcf, 0xdd, 0xc3, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x42, 0xef, 0xbe, 0x96, 0x16, 0x9e, 0xed, 0xdd, 0xfc, 0xc5, 0xab, 0x0e, 0xad, 0xdd, 0xf4, 0x5b,
0x49, 0xac, 0x87, 0x00, 0x2e, 0x07, 0x00, 0x00, 0xa4, 0x43, 0xbc, 0x1a, 0xbb, 0x69, 0xd7, 0x4c, 0xe6, 0xf0, 0x1a, 0xa3, 0x76, 0x58, 0xe7, 0xda,
0xe0, 0xa0, 0xb5, 0x24, 0xbf, 0x97, 0xbf, 0x7f, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x8c, 0x1b, 0x18,
0xf9, 0x6f, 0x07, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@@ -1580,13 +1603,6 @@ func (m *DynamicResource) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i-- i--
dAtA[i] = 0x12 dAtA[i] = 0x12
} }
if len(m.ClassName) > 0 {
i -= len(m.ClassName)
copy(dAtA[i:], m.ClassName)
i = encodeVarintApi(dAtA, i, uint64(len(m.ClassName)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil return len(dAtA) - i, nil
} }
@@ -1610,6 +1626,27 @@ func (m *ClaimResource) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if len(m.DeviceName) > 0 {
i -= len(m.DeviceName)
copy(dAtA[i:], m.DeviceName)
i = encodeVarintApi(dAtA, i, uint64(len(m.DeviceName)))
i--
dAtA[i] = 0x22
}
if len(m.PoolName) > 0 {
i -= len(m.PoolName)
copy(dAtA[i:], m.PoolName)
i = encodeVarintApi(dAtA, i, uint64(len(m.PoolName)))
i--
dAtA[i] = 0x1a
}
if len(m.DriverName) > 0 {
i -= len(m.DriverName)
copy(dAtA[i:], m.DriverName)
i = encodeVarintApi(dAtA, i, uint64(len(m.DriverName)))
i--
dAtA[i] = 0x12
}
if len(m.CDIDevices) > 0 { if len(m.CDIDevices) > 0 {
for iNdEx := len(m.CDIDevices) - 1; iNdEx >= 0; iNdEx-- { for iNdEx := len(m.CDIDevices) - 1; iNdEx >= 0; iNdEx-- {
{ {
@@ -1938,10 +1975,6 @@ func (m *DynamicResource) Size() (n int) {
} }
var l int var l int
_ = l _ = l
l = len(m.ClassName)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
l = len(m.ClaimName) l = len(m.ClaimName)
if l > 0 { if l > 0 {
n += 1 + l + sovApi(uint64(l)) n += 1 + l + sovApi(uint64(l))
@@ -1971,6 +2004,18 @@ func (m *ClaimResource) Size() (n int) {
n += 1 + l + sovApi(uint64(l)) n += 1 + l + sovApi(uint64(l))
} }
} }
l = len(m.DriverName)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
l = len(m.PoolName)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
l = len(m.DeviceName)
if l > 0 {
n += 1 + l + sovApi(uint64(l))
}
return n return n
} }
@@ -2183,7 +2228,6 @@ func (this *DynamicResource) String() string {
} }
repeatedStringForClaimResources += "}" repeatedStringForClaimResources += "}"
s := strings.Join([]string{`&DynamicResource{`, s := strings.Join([]string{`&DynamicResource{`,
`ClassName:` + fmt.Sprintf("%v", this.ClassName) + `,`,
`ClaimName:` + fmt.Sprintf("%v", this.ClaimName) + `,`, `ClaimName:` + fmt.Sprintf("%v", this.ClaimName) + `,`,
`ClaimNamespace:` + fmt.Sprintf("%v", this.ClaimNamespace) + `,`, `ClaimNamespace:` + fmt.Sprintf("%v", this.ClaimNamespace) + `,`,
`ClaimResources:` + repeatedStringForClaimResources + `,`, `ClaimResources:` + repeatedStringForClaimResources + `,`,
@@ -2202,6 +2246,9 @@ func (this *ClaimResource) String() string {
repeatedStringForCDIDevices += "}" repeatedStringForCDIDevices += "}"
s := strings.Join([]string{`&ClaimResource{`, s := strings.Join([]string{`&ClaimResource{`,
`CDIDevices:` + repeatedStringForCDIDevices + `,`, `CDIDevices:` + repeatedStringForCDIDevices + `,`,
`DriverName:` + fmt.Sprintf("%v", this.DriverName) + `,`,
`PoolName:` + fmt.Sprintf("%v", this.PoolName) + `,`,
`DeviceName:` + fmt.Sprintf("%v", this.DeviceName) + `,`,
`}`, `}`,
}, "") }, "")
return s return s
@@ -3500,38 +3547,6 @@ func (m *DynamicResource) Unmarshal(dAtA []byte) error {
return fmt.Errorf("proto: DynamicResource: illegal tag %d (wire type %d)", fieldNum, wire) return fmt.Errorf("proto: DynamicResource: illegal tag %d (wire type %d)", fieldNum, wire)
} }
switch fieldNum { switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClassName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApi
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.ClassName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2: case 2:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ClaimName", wireType) return fmt.Errorf("proto: wrong wireType = %d for field ClaimName", wireType)
@@ -3714,6 +3729,102 @@ func (m *ClaimResource) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field DriverName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApi
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.DriverName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field PoolName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApi
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.PoolName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field DeviceName", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthApi
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthApi
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.DeviceName = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipApi(dAtA[iNdEx:]) skippy, err := skipApi(dAtA[iNdEx:])

View File

@@ -82,15 +82,22 @@ message NUMANode {
// DynamicResource contains information about the devices assigned to a container by DRA // DynamicResource contains information about the devices assigned to a container by DRA
message DynamicResource { message DynamicResource {
string class_name = 1; // tombstone: removed in 1.31 because claims are no longer associated with one class
// string class_name = 1;
string claim_name = 2; string claim_name = 2;
string claim_namespace = 3; string claim_namespace = 3;
repeated ClaimResource claim_resources = 4; repeated ClaimResource claim_resources = 4;
} }
// ClaimResource contains per plugin resource information // ClaimResource contains resource information. The driver name/pool name/device name
// triplet uniquely identifies the device. Should DRA get extended to other kinds
// of resources, then device_name will be empty and other fields will get added.
// Each device at the DRA API level may map to zero or more CDI devices.
message ClaimResource { message ClaimResource {
repeated CDIDevice cdi_devices = 1 [(gogoproto.customname) = "CDIDevices"]; repeated CDIDevice cdi_devices = 1 [(gogoproto.customname) = "CDIDevices"];
string driver_name = 2;
string pool_name = 3;
string device_name = 4;
} }
// CDIDevice specifies a CDI device information // CDIDevice specifies a CDI device information