Skip to content

Commit

Permalink
Merge pull request #456 from SchSeba/token_support
Browse files Browse the repository at this point in the history
New environment variable to expose informers details in json format
  • Loading branch information
adrianchiris authored Feb 28, 2023
2 parents fe8f2a7 + ffb8e3e commit 5f8442e
Show file tree
Hide file tree
Showing 51 changed files with 967 additions and 291 deletions.
80 changes: 78 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,20 @@ This plugin creates device plugin endpoints based on the configurations given in
"pfNames": ["p0#1-5"],
"auxTypes": ["sf"]
}
},
{
"resourceName": "intel_sriov_netdevice_additional_env",
"selectors": {
"vendors": ["8086"],
"devices": ["154c", "10ed", "1889"],
"drivers": ["i40evf", "ixgbevf", "iavf"]
},
"additionalInfo": {
"*": {
"token": "3e49019f-412f-4f02-824e-4cd195944205"
}
}
}

]
}
```
Expand All @@ -256,7 +268,7 @@ This plugin creates device plugin endpoints based on the configurations given in
| "deviceType" | N | Device Type for a resource pool. | string value of supported types. Default: "netDevice" | Currently supported values: "accelerator", "netDevice", "auxNetDevice" |
| "excludeTopology" | N | Exclude advertising of device's NUMA topology | bool Default: "false" | "excludeTopology": true |
| "selectors" | N | A map of device selectors. The "deviceType" value determines the "selectors" options. | json object as string Default: null | Example: "selectors": {"vendors": ["8086"],"devices": ["154c"]} |

| "additionalInfo" | N | A map of map to add additional information to the pod via environment variables to devices | json object as string Default: null | Example: "additionalInfo": {"*": {"token": "3e49019f-412f-4f02-824e-4cd195944205"}} |

Note: "resourceName" must be unique only in the scope of a given prefix, including the one specified globally in the CLI params, e.g. "example.com/10G", "acme.com/10G" and "acme.com/40G" are perfectly valid names.

Expand Down Expand Up @@ -310,6 +322,59 @@ This selector is applicable when "deviceType" is "auxNetDevice".

[//]: # (The tables above generated using: https://ozh.github.io/ascii-tables/)

#### AdditionalInfo field

This field defines a method to add information as part of the environment variable the sriov-network-device-plugin injects to the container.

Examples:
```
"additionalInfo": {
"*": {
"token": "3e49019f-412f-4f02-824e-4cd195944205"
}
}
```
The '*' is a special key telling the device plugin to inject this info to all the devices matching the selector.
you can also specify a specific pci address if you want to override or add more information to a specific device

```
"additionalInfo": {
"*": {
"token": "3e49019f-412f-4f02-824e-4cd195944205"
},
"0000:86:00.0": {
"additional-token": "6e7dc135-7a1c-456f-a008-c2cfb37997be"
}
}
output for pod allocating a different deviceID:
{"0000:3b:02.6":{"extraInfo":{"token":"3e49019f-412f-4f02-824e-4cd195944205"}
output for pod allocating the specific deviceID:
{"0000:86:00.0":{"extraInfo":{"token":"3e49019f-412f-4f02-824e-4cd195944205","additional-token": "6e7dc135-7a1c-456f-a008-c2cfb37997be"}
```

When having the same key for both the "*" and spefic deviceID variable the specific one will be taken

```
"additionalInfo": {
"*": {
"token": "original"
},
"0000:86:00.0": {
"token": "specific"
}
}
output for pod allocating a different deviceID:
{"0000:3b:02.6":{"extraInfo":{"token":"original"}
output for pod allocating the specific deviceID:
{"0000:86:00.0":{"extraInfo":{"token":"specific"}
```

### Command line arguments

This plugin accepts the following optional run-time command line arguments:
Expand Down Expand Up @@ -577,6 +642,17 @@ The allocated device information is exported in Container's environment variable
For example, if 2 devices are allocated from `intel.com/sriov` extended resource then the allocated device information will be found in following env variable:
`PCIDEVICE_INTEL_COM_SRIOV=0000:03:02.1,0000:03:04.3`

There is also another environment variable that expose in json format more information about the device that was allocated like mount and addition variables if requested.
The variable name is `PCIDEVICE_<RESOUCE_NAME>_INFO` appended with full extended resource name (e.g. intel.com/sriov etc.) which is capitailzed and any special characters (".", "/") are replaced with underscore ("_")

vfio device example:
```
PCIDEVICE_INTEL_COM_DPDK_NIC_1_INFO={"0000:3b:02.6":{"vfio":{"vfio-dev-mount":"/dev/vfio/169","vfio-mount":"/dev/vfio/vfio"},"vhost":{"net-mount":"/dev/vhost-net","tun-mount":"/dev/net/tun"}}}
# Adding additionalInfo field to the resource definition will add additional information for every device allocated. e.g:
PCIDEVICE_INTEL_COM_DPDK_NIC_1_INFO={"0000:3b:02.6":{"extraInfo":{"token":"3e49019f-412f-4f02-824e-4cd195944205"},"vfio":{"vfio-dev-mount":"/dev/vfio/169","vfio-mount":"/dev/vfio/vfio"},"vhost":{"net-mount":"/dev/vhost-net","tun-mount":"/dev/net/tun"}}}
```

## Virtual Deployments Support

### Configure Device Plugin extended selectors in virtual environments
Expand Down
30 changes: 28 additions & 2 deletions pkg/accelerator/accelDevice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,26 @@ var _ = Describe("Accelerator", func() {

// TODO: assert other fields once implemented
Expect(out.GetDriver()).To(Equal("vfio-pci"))
Expect(out.GetEnvVal()).To(Equal(pciAddr))
Expect(out.GetDeviceSpecs()).To(HaveLen(2)) // /dev/vfio/vfio0 and default /dev/vfio/vfio
envs := out.GetEnvVal()
Expect(len(envs)).To(Equal(2))

vfioMap, exist := envs["vfio"]
Expect(exist).To(BeTrue())
Expect(len(vfioMap)).To(Equal(2))
vfio, exist := envs["vfio"]["mount"]
Expect(exist).To(BeTrue())
Expect(vfio).To(Equal("/dev/vfio/vfio"))
vfio, exist = envs["vfio"]["dev-mount"]
Expect(exist).To(BeTrue())
Expect(vfio).To(Equal("/dev/vfio/0"))
genericMap, exist := envs["generic"]
Expect(exist).To(BeTrue())
Expect(len(genericMap)).To(Equal(1))
generic, exist := envs["generic"]["deviceID"]
Expect(exist).To(BeTrue())
Expect(generic).To(Equal("0000:00:00.1"))

Expect(out.GetAPIDevice().Topology.Nodes[0].ID).To(Equal(int64(0)))
Expect(err).NotTo(HaveOccurred())
})
Expand Down Expand Up @@ -174,7 +192,15 @@ var _ = Describe("Accelerator", func() {
dev, err := accelerator.NewAccelDevice(in, f, config)
Expect(err).NotTo(HaveOccurred())
Expect(dev).NotTo(BeNil())
Expect(dev.GetEnvVal()).To(Equal(pciAddr))

envs := dev.GetEnvVal()
Expect(len(envs)).To(Equal(2))
genericMap, exist := envs["generic"]
Expect(exist).To(BeTrue())
Expect(len(genericMap)).To(Equal(1))
generic, exist := envs["generic"]["deviceID"]
Expect(exist).To(BeTrue())
Expect(generic).To(Equal("0000:00:00.1"))
})
})
})
Expand Down
3 changes: 1 addition & 2 deletions pkg/auxnetdevice/auxNetDevice.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ func NewAuxNetDevice(dev *ghw.PCIDevice, deviceID string, rFactory types.Resourc
return nil, err
}

infoProviders := make([]types.DeviceInfoProvider, 0)
infoProviders = append(infoProviders, rFactory.GetDefaultInfoProvider(deviceID, driverName))
infoProviders := rFactory.GetDefaultInfoProvider(deviceID, driverName)
isRdma := false
nf, ok := rc.SelectorObj.(*types.AuxNetDeviceSelectors)
if ok {
Expand Down
36 changes: 29 additions & 7 deletions pkg/auxnetdevice/auxNetDevice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ var _ = Describe("AuxNetDevice", func() {
Expect(dev).NotTo(BeNil())
Expect(dev.GetDriver()).To(Equal("mlx5_core"))
Expect(dev.GetNetName()).To(Equal("eth0"))
Expect(dev.GetEnvVal()).To(Equal(auxDevID))
envs := dev.GetEnvVal()
Expect(len(envs)).To(Equal(1))
pci, exist := envs["generic"]["deviceID"]
Expect(exist).To(BeTrue())
Expect(pci).To(Equal("mlx5_core.sf.0"))
Expect(dev.GetDeviceSpecs()).To(HaveLen(0))
Expect(dev.IsRdma()).To(BeFalse())
Expect(dev.GetLinkType()).To(Equal("fakeLinkType"))
Expand Down Expand Up @@ -131,15 +135,19 @@ var _ = Describe("AuxNetDevice", func() {
auxDevName1 := "mlx5_core.eth.1"
auxDevName2 := "mlx5_core.eth-rep.2"
mockInfo1 := &tmocks.DeviceInfoProvider{}
mockInfo1.On("GetEnvVal").Return(auxDevName1)
mockEnv1 := types.AdditionalInfo{"deviceID": auxDevName1}
mockInfo1.On("GetName").Return("generic")
mockInfo1.On("GetEnvVal").Return(mockEnv1)
mockInfo1.On("GetDeviceSpecs").Return(nil)
mockInfo1.On("GetMounts").Return(nil)
mockInfo2 := &tmocks.DeviceInfoProvider{}
mockInfo2.On("GetEnvVal").Return(auxDevName2)
mockEnv2 := types.AdditionalInfo{"deviceID": auxDevName2}
mockInfo2.On("GetName").Return("generic")
mockInfo2.On("GetEnvVal").Return(mockEnv2)
mockInfo2.On("GetDeviceSpecs").Return(nil)
mockInfo2.On("GetMounts").Return(nil)
f.On("GetDefaultInfoProvider", auxDevName1, "mlx5_core").Return(mockInfo1).
On("GetDefaultInfoProvider", auxDevName2, "mlx5_core").Return(mockInfo2).
f.On("GetDefaultInfoProvider", auxDevName1, "mlx5_core").Return([]types.DeviceInfoProvider{mockInfo1}).
On("GetDefaultInfoProvider", auxDevName2, "mlx5_core").Return([]types.DeviceInfoProvider{mockInfo2}).
On("GetRdmaSpec", types.AuxNetDeviceType, auxDevName1).Return(rdma1).
On("GetRdmaSpec", types.AuxNetDeviceType, auxDevName2).Return(rdma2)

Expand All @@ -164,8 +172,15 @@ var _ = Describe("AuxNetDevice", func() {
Expect(err).NotTo(HaveOccurred())
Expect(dev.GetDriver()).To(Equal("mlx5_core"))
Expect(dev.IsRdma()).To(BeTrue())
Expect(dev.GetEnvVal()).To(Equal(auxDevName1))
Expect(dev.GetDeviceSpecs()).To(HaveLen(2)) // 2x Rdma devs
envs := dev.GetEnvVal()
Expect(len(envs)).To(Equal(2))
_, exist := envs["generic"]
Expect(exist).To(BeTrue())
pci, exist := envs["generic"]["deviceID"]
Expect(exist).To(BeTrue())
Expect(pci).To(Equal(auxDevName1))
Expect(exist).To(BeTrue())
Expect(dev.GetMounts()).To(HaveLen(0))
Expect(dev.GetAuxType()).To(Equal("eth"))
mockInfo1.AssertExpectations(t)
Expand All @@ -178,7 +193,14 @@ var _ = Describe("AuxNetDevice", func() {

Expect(err).NotTo(HaveOccurred())
Expect(dev.GetDriver()).To(Equal("mlx5_core"))
Expect(dev.GetEnvVal()).To(Equal(auxDevName2))
envs := dev.GetEnvVal()
Expect(len(envs)).To(Equal(1))
_, exist := envs["generic"]
Expect(exist).To(BeTrue())
pci, exist := envs["generic"]["deviceID"]
Expect(exist).To(BeTrue())
Expect(pci).To(Equal(auxDevName2))
Expect(exist).To(BeTrue())
Expect(dev.IsRdma()).To(BeFalse())
Expect(dev.GetDeviceSpecs()).To(HaveLen(0))
Expect(dev.GetMounts()).To(HaveLen(0))
Expand Down
12 changes: 7 additions & 5 deletions pkg/devices/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ func (ad *APIDeviceImpl) GetDeviceSpecs() []*pluginapi.DeviceSpec {
return dSpecs
}

// GetEnvVal returns device environment variable
func (ad *APIDeviceImpl) GetEnvVal() string {
// Currently Device Plugin does not support returning multiple Env Vars
// so we use the value provided by the first InfoProvider.
return ad.infoProviders[0].GetEnvVal()
// GetEnvVal returns device environment variables
func (ad *APIDeviceImpl) GetEnvVal() map[string]types.AdditionalInfo {
envValMap := make(map[string]types.AdditionalInfo, 0)
for _, provider := range ad.infoProviders {
envValMap[provider.GetName()] = provider.GetEnvVal()
}
return envValMap
}

// GetMounts returns list of device host mounts
Expand Down
15 changes: 13 additions & 2 deletions pkg/devices/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,31 @@ var _ = Describe("ApiDevice", func() {
mockSpec1 := []*v1beta1.DeviceSpec{
{HostPath: "/mock/spec/1"},
}
mockInfo1.On("GetEnvVal").Return("0000:00:00.1")
mockEnv := types.AdditionalInfo{"deviceID": "0000:00:00.1"}
mockInfo1.On("GetName").Return("generic")
mockInfo1.On("GetEnvVal").Return(mockEnv)
mockInfo1.On("GetDeviceSpecs").Return(mockSpec1)
mockInfo1.On("GetMounts").Return(nil)
mockInfo2 := &mocks.DeviceInfoProvider{}
mockSpec2 := []*v1beta1.DeviceSpec{
{HostPath: "/mock/spec/2"},
}
mockInfo2.On("GetName").Return("generic")
mockInfo2.On("GetEnvVal").Return(mockEnv)
mockInfo2.On("GetDeviceSpecs").Return(mockSpec2)
mockInfo2.On("GetMounts").Return(nil)

infoProviders := []types.DeviceInfoProvider{mockInfo1, mockInfo2}
dev := devices.NewAPIDeviceImpl("0000:00:00.1", infoProviders, -1)

Expect(dev.GetEnvVal()).To(Equal("0000:00:00.1"))
envs := dev.GetEnvVal()
Expect(len(envs)).To(Equal(1))
_, exist := envs["generic"]
Expect(exist).To(BeTrue())
pci, exist := envs["generic"]["deviceID"]
Expect(exist).To(BeTrue())
Expect(pci).To(Equal("0000:00:00.1"))

Expect(dev.GetDeviceSpecs()).To(HaveLen(2))
Expect(dev.GetMounts()).To(HaveLen(0))
Expect(dev.GetAPIDevice()).NotTo(BeNil())
Expand Down
6 changes: 5 additions & 1 deletion pkg/devices/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package devices
import (
"github.com/jaypipes/ghw"

"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/infoprovider"
"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types"
"github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/utils"
)
Expand All @@ -45,7 +46,10 @@ func NewHostDeviceImpl(dev *ghw.PCIDevice, deviceID string, rFactory types.Resou

// Use the default Information Provided if not
if len(infoProviders) == 0 {
infoProviders = append(infoProviders, rFactory.GetDefaultInfoProvider(deviceID, driverName))
infoProviders = rFactory.GetDefaultInfoProvider(deviceID, driverName)
if rc.AdditionalInfo != nil {
infoProviders = append(infoProviders, infoprovider.NewExtraInfoProvider(dev.Address, rc.AdditionalInfo))
}
}

nodeNum := -1
Expand Down
28 changes: 22 additions & 6 deletions pkg/devices/host_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,18 +188,22 @@ var _ = Describe("HostDevice", func() {
mockSpec1 := []*v1beta1.DeviceSpec{
{HostPath: "/mock/spec/1"},
}
mockInfo1.On("GetEnvVal").Return(pciAddr1)
mockEnv1 := types.AdditionalInfo{"deviceID": pciAddr1}
mockInfo1.On("GetName").Return("generic")
mockInfo1.On("GetEnvVal").Return(mockEnv1)
mockInfo1.On("GetDeviceSpecs").Return(mockSpec1)
mockInfo1.On("GetMounts").Return(nil)
mockInfo2 := &mocks.DeviceInfoProvider{}
mockSpec2 := []*v1beta1.DeviceSpec{
{HostPath: "/mock/spec/2"},
}
mockInfo2.On("GetEnvVal").Return(pciAddr2)
mockEnv2 := types.AdditionalInfo{"deviceID": pciAddr2}
mockInfo2.On("GetName").Return("generic")
mockInfo2.On("GetEnvVal").Return(mockEnv2)
mockInfo2.On("GetDeviceSpecs").Return(mockSpec2)
mockInfo2.On("GetMounts").Return(nil)
f.On("GetDefaultInfoProvider", pciAddr1, "mlx5_core").Return(mockInfo1).
On("GetDefaultInfoProvider", pciAddr2, "mlx5_core").Return(mockInfo2)
f.On("GetDefaultInfoProvider", pciAddr1, "mlx5_core").Return([]types.DeviceInfoProvider{mockInfo1}).
On("GetDefaultInfoProvider", pciAddr2, "mlx5_core").Return([]types.DeviceInfoProvider{mockInfo2})

in1 := newPciDeviceFn(pciAddr1)
in2 := newPciDeviceFn(pciAddr2)
Expand All @@ -211,7 +215,13 @@ var _ = Describe("HostDevice", func() {
dev, err := devices.NewHostDeviceImpl(in1, pciAddr1, f, rc, infoProviders)

Expect(dev.GetDriver()).To(Equal("mlx5_core"))
Expect(dev.GetEnvVal()).To(Equal(pciAddr1))
envs := dev.GetEnvVal()
Expect(len(envs)).To(Equal(1))
_, exist := envs["generic"]
Expect(exist).To(BeTrue())
pci, exist := envs["generic"]["deviceID"]
Expect(exist).To(BeTrue())
Expect(pci).To(Equal(pciAddr1))
Expect(dev.GetDeviceSpecs()).To(Equal(mockSpec1))
Expect(dev.GetMounts()).To(HaveLen(0))
Expect(err).NotTo(HaveOccurred())
Expand All @@ -224,7 +234,13 @@ var _ = Describe("HostDevice", func() {
dev, err := devices.NewHostDeviceImpl(in2, pciAddr2, f, rc, infoProviders)

Expect(dev.GetDriver()).To(Equal("mlx5_core"))
Expect(dev.GetEnvVal()).To(Equal(pciAddr2))
envs := dev.GetEnvVal()
Expect(len(envs)).To(Equal(1))
_, exist := envs["generic"]
Expect(exist).To(BeTrue())
pci, exist := envs["generic"]["deviceID"]
Expect(exist).To(BeTrue())
Expect(pci).To(Equal(pciAddr2))
Expect(dev.GetDeviceSpecs()).To(Equal(mockSpec2))
Expect(dev.GetMounts()).To(HaveLen(0))
Expect(err).NotTo(HaveOccurred())
Expand Down
11 changes: 6 additions & 5 deletions pkg/factory/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,16 @@ func (rf *resourceFactory) GetResourceServer(rp types.ResourcePool) (types.Resou
}

// GetDefaultInfoProvider returns an instance of DeviceInfoProvider using name as string
func (rf *resourceFactory) GetDefaultInfoProvider(pciAddr, name string) types.DeviceInfoProvider {
func (rf *resourceFactory) GetDefaultInfoProvider(pciAddr, name string) []types.DeviceInfoProvider {
deviceInfoProvidersList := []types.DeviceInfoProvider{infoprovider.NewGenericInfoProvider(pciAddr)}

switch name {
case "vfio-pci":
return infoprovider.NewVfioInfoProvider(pciAddr)
deviceInfoProvidersList = append(deviceInfoProvidersList, infoprovider.NewVfioInfoProvider(pciAddr))
case "uio", "igb_uio":
return infoprovider.NewUioInfoProvider(pciAddr)
default:
return infoprovider.NewGenericInfoProvider(pciAddr)
deviceInfoProvidersList = append(deviceInfoProvidersList, infoprovider.NewUioInfoProvider(pciAddr))
}
return deviceInfoProvidersList
}

// GetSelector returns an instance of DeviceSelector using selector attribute string and its associated values
Expand Down
Loading

0 comments on commit 5f8442e

Please sign in to comment.