Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New environment variable to expose informers details in json format #456

Merged
merged 7 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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": {
"*": {
adrianchiris marked this conversation as resolved.
Show resolved Hide resolved
"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