From 8a632b6e7c89e9cbf822bc864d7283a3548714d6 Mon Sep 17 00:00:00 2001 From: Sebastian Sch Date: Mon, 5 Dec 2022 16:34:14 +0200 Subject: [PATCH] add support for extra environment variables This commit add support for the sriov-device-plugin to inject extra env variables Signed-off-by: Sebastian Sch --- pkg/accelerator/accelDevice_test.go | 22 ++++- pkg/devices/api.go | 12 ++- pkg/devices/api_test.go | 13 ++- pkg/devices/host.go | 4 + pkg/devices/host_test.go | 22 ++++- pkg/infoprovider/envInfoProvider.go | 66 +++++++++++++ pkg/infoprovider/envInfoProvider_test.go | 95 ++++++++++++++++++ pkg/infoprovider/genericInfoProvider.go | 10 +- pkg/infoprovider/rdmaInfoProvider.go | 27 ++++- pkg/infoprovider/rdmaInfoProvider_test.go | 22 ++++- pkg/infoprovider/uioInfoProvider.go | 14 ++- pkg/infoprovider/uioInfoProvider_test.go | 30 +++++- pkg/infoprovider/vdpaInfoProvider.go | 18 +++- pkg/infoprovider/vdpaInfoProvider_test.go | 23 ++++- pkg/infoprovider/vfioInfoProvider.go | 19 +++- pkg/infoprovider/vfioInfoProvider_test.go | 36 ++++++- pkg/infoprovider/vhostNetInfoProvider.go | 10 +- pkg/infoprovider/vhostNetInfoProvider_test.go | 13 ++- pkg/netdevice/pciNetDevice.go | 4 + pkg/netdevice/pciNetDevice_test.go | 98 ++++++++++++++++--- pkg/resources/pool_stub.go | 41 ++++++-- pkg/resources/pool_stub_test.go | 22 ----- pkg/resources/server.go | 27 ++--- pkg/resources/server_test.go | 30 +----- pkg/types/mocks/APIDevice.go | 93 ++++++++++++++++++ pkg/types/mocks/AccelDevice.go | 32 ++---- pkg/types/mocks/DeviceInfoProvider.go | 18 ++-- pkg/types/mocks/DeviceProvider.go | 6 +- pkg/types/mocks/DeviceSelector.go | 6 +- pkg/types/mocks/HostDevice.go | 32 ++---- pkg/types/mocks/LinkWatcher.go | 6 +- pkg/types/mocks/NadUtils.go | 6 +- pkg/types/mocks/NetDevice.go | 18 ++-- pkg/types/mocks/PciDevice.go | 32 ++---- pkg/types/mocks/PciNetDevice.go | 24 ++--- pkg/types/mocks/RdmaSpec.go | 6 +- pkg/types/mocks/ResourceFactory.go | 6 +- pkg/types/mocks/ResourcePool.go | 29 +++--- pkg/types/mocks/ResourceServer.go | 6 +- pkg/types/mocks/VdpaDevice.go | 6 +- pkg/types/types.go | 22 +++-- pkg/utils/mocks/NetlinkProvider.go | 6 +- pkg/utils/mocks/RdmaProvider.go | 6 +- pkg/utils/mocks/SriovnetProvider.go | 6 +- pkg/utils/mocks/VdpaProvider.go | 6 +- 45 files changed, 776 insertions(+), 274 deletions(-) create mode 100644 pkg/infoprovider/envInfoProvider.go create mode 100644 pkg/infoprovider/envInfoProvider_test.go create mode 100644 pkg/types/mocks/APIDevice.go diff --git a/pkg/accelerator/accelDevice_test.go b/pkg/accelerator/accelDevice_test.go index a0ff7257c..527a5340e 100644 --- a/pkg/accelerator/accelDevice_test.go +++ b/pkg/accelerator/accelDevice_test.go @@ -61,7 +61,16 @@ var _ = Describe("Accelerator", func() { // TODO: assert other fields once implemented Expect(out.GetDriver()).To(Equal("vfio-pci")) - Expect(out.GetEnvVal()).To(Equal(pciAddr)) + envs := out.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + + _, exist := envs["vfio"] + Expect(exist).To(BeTrue()) + + pci, exist := envs["vfio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal(pciAddr)) + Expect(out.GetDeviceSpecs()).To(HaveLen(2)) // /dev/vfio/vfio0 and default /dev/vfio/vfio Expect(out.GetAPIDevice().Topology.Nodes[0].ID).To(Equal(int64(0))) Expect(err).NotTo(HaveOccurred()) @@ -174,7 +183,16 @@ 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(1)) + + _, exist := envs["vfio"] + Expect(exist).To(BeTrue()) + + pci, exist := envs["vfio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal(pciAddr)) }) }) }) diff --git a/pkg/devices/api.go b/pkg/devices/api.go index 029b2310c..b8c97ab14 100644 --- a/pkg/devices/api.go +++ b/pkg/devices/api.go @@ -60,10 +60,14 @@ func (ad *APIDeviceImpl) GetDeviceSpecs() []*pluginapi.DeviceSpec { } // 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() +func (ad *APIDeviceImpl) GetEnvVal() map[string]types.EnvironmentVariables { + envValList := make(map[string]types.EnvironmentVariables, 0) + for _, provider := range ad.infoProviders { + for k, v := range provider.GetEnvVal() { + envValList[k] = v + } + } + return envValList } // GetMounts returns list of device host mounts diff --git a/pkg/devices/api_test.go b/pkg/devices/api_test.go index 3483c477f..416cf02ca 100644 --- a/pkg/devices/api_test.go +++ b/pkg/devices/api_test.go @@ -35,20 +35,29 @@ var _ = Describe("ApiDevice", func() { mockSpec1 := []*v1beta1.DeviceSpec{ {HostPath: "/mock/spec/1"}, } - mockInfo1.On("GetEnvVal").Return("0000:00:00.1") + mockEnv := map[string]types.EnvironmentVariables{"netdevice": {"pci": "0000:00:00.1"}} + 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("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["netdevice"] + Expect(exist).To(BeTrue()) + pci, exist := envs["netdevice"]["pci"] + 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()) diff --git a/pkg/devices/host.go b/pkg/devices/host.go index 3e566ddc0..73d6d0b83 100644 --- a/pkg/devices/host.go +++ b/pkg/devices/host.go @@ -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" ) @@ -46,6 +47,9 @@ 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)) + if rc.ExtraEnvVariables != nil { + infoProviders = append(infoProviders, infoprovider.NewEnvInfoProvider(dev.Address, rc.ExtraEnvVariables)) + } } nodeNum := -1 diff --git a/pkg/devices/host_test.go b/pkg/devices/host_test.go index 7c5957b44..1dc8086ae 100644 --- a/pkg/devices/host_test.go +++ b/pkg/devices/host_test.go @@ -188,14 +188,16 @@ var _ = Describe("HostDevice", func() { mockSpec1 := []*v1beta1.DeviceSpec{ {HostPath: "/mock/spec/1"}, } - mockInfo1.On("GetEnvVal").Return(pciAddr1) + mockEnv1 := map[string]types.EnvironmentVariables{"netdevice": {"pci": pciAddr1}} + 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 := map[string]types.EnvironmentVariables{"netdevice": {"pci": pciAddr2}} + mockInfo2.On("GetEnvVal").Return(mockEnv2) mockInfo2.On("GetDeviceSpecs").Return(mockSpec2) mockInfo2.On("GetMounts").Return(nil) f.On("GetDefaultInfoProvider", pciAddr1, "mlx5_core").Return(mockInfo1). @@ -211,7 +213,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["netdevice"] + Expect(exist).To(BeTrue()) + pci, exist := envs["netdevice"]["pci"] + 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()) @@ -224,7 +232,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["netdevice"] + Expect(exist).To(BeTrue()) + pci, exist := envs["netdevice"]["pci"] + 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()) diff --git a/pkg/infoprovider/envInfoProvider.go b/pkg/infoprovider/envInfoProvider.go new file mode 100644 index 000000000..b4c7b8979 --- /dev/null +++ b/pkg/infoprovider/envInfoProvider.go @@ -0,0 +1,66 @@ +// Copyright 2018 Intel Corp. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package infoprovider + +import ( + "github.com/golang/glog" + + pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" + + "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" +) + +/* +envInfoProvider implements DeviceInfoProvider +*/ +type envInfoProvider struct { + pciAddr string + envs map[string]types.EnvironmentVariables +} + +// NewEnvInfoProvider create instance of Environment DeviceInfoProvider +func NewEnvInfoProvider(pciAddr string, envs map[string]types.EnvironmentVariables) types.DeviceInfoProvider { + return &envInfoProvider{ + pciAddr: pciAddr, + envs: envs, + } +} + +func (rp *envInfoProvider) GetDeviceSpecs() []*pluginapi.DeviceSpec { + devSpecs := make([]*pluginapi.DeviceSpec, 0) + return devSpecs +} + +func (rp *envInfoProvider) GetEnvVal() map[string]types.EnvironmentVariables { + envs := make(map[string]string, 0) + + // first we search for global configuration with the * then we check for specific one to override + for _, value := range []string{"*", rp.pciAddr} { + extraEnvDict, ok := rp.envs[value] + if ok { + for k, v := range extraEnvDict { + envs[k] = v + } + } + } + envMap := map[string]types.EnvironmentVariables{"envs": envs} + glog.Infof("Env GetEnvVal(): %v", envMap) + return envMap +} + +func (rp *envInfoProvider) GetMounts() []*pluginapi.Mount { + mounts := make([]*pluginapi.Mount, 0) + return mounts +} diff --git a/pkg/infoprovider/envInfoProvider_test.go b/pkg/infoprovider/envInfoProvider_test.go new file mode 100644 index 000000000..6ff2fc473 --- /dev/null +++ b/pkg/infoprovider/envInfoProvider_test.go @@ -0,0 +1,95 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package infoprovider_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/infoprovider" + "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" +) + +var _ = Describe("EnvInfoProvider", func() { + Describe("creating new rdmaInfoProvider", func() { + It("should return valid rdmaInfoProvider object", func() { + dip := infoprovider.NewEnvInfoProvider("fake01", map[string]types.EnvironmentVariables{}) + Expect(dip).NotTo(Equal(nil)) + }) + }) + Describe("GetEnvVal", func() { + It("should return an empty object if there are no environment variables", func() { + dip := infoprovider.NewEnvInfoProvider("fake", nil) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + envMap, exist := envs["envs"] + Expect(exist).To(BeTrue()) + Expect(len(envMap)).To(Equal(0)) + }) + It("should return an object with environment variables", func() { + dip := infoprovider.NewEnvInfoProvider("fake", map[string]types.EnvironmentVariables{"*": map[string]string{"test": "test"}}) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + envMap, exist := envs["envs"] + Expect(exist).To(BeTrue()) + Expect(len(envMap)).To(Equal(1)) + value, exist := envs["envs"]["test"] + Expect(exist).To(BeTrue()) + Expect(value).To(Equal("test")) + }) + It("should return an object with specific selector for environment variable", func() { + dip := infoprovider.NewEnvInfoProvider("0000:00:00.1", map[string]types.EnvironmentVariables{"*": map[string]string{"test": "test"}, "0000:00:00.1": map[string]string{"test": "test1"}}) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + envMap, exist := envs["envs"] + Expect(exist).To(BeTrue()) + Expect(len(envMap)).To(Equal(1)) + value, exist := envs["envs"]["test"] + Expect(exist).To(BeTrue()) + Expect(value).To(Equal("test1")) + }) + It("should return an object with specific selector for multiple environment variable", func() { + dip := infoprovider.NewEnvInfoProvider("0000:00:00.1", map[string]types.EnvironmentVariables{"*": map[string]string{"test": "test", "bla": "bla"}, "0000:00:00.1": map[string]string{"test": "test1"}}) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + envMap, exist := envs["envs"] + Expect(exist).To(BeTrue()) + Expect(len(envMap)).To(Equal(2)) + value, exist := envs["envs"]["test"] + Expect(exist).To(BeTrue()) + Expect(value).To(Equal("test1")) + value, exist = envs["envs"]["bla"] + Expect(exist).To(BeTrue()) + Expect(value).To(Equal("bla")) + }) + It("should return an object with multiple specific selector for environment variable", func() { + dip := infoprovider.NewEnvInfoProvider("0000:00:00.1", map[string]types.EnvironmentVariables{"*": map[string]string{"test": "test"}, "0000:00:00.1": map[string]string{"test": "test1", "bla": "bla"}}) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + envMap, exist := envs["envs"] + Expect(exist).To(BeTrue()) + Expect(len(envMap)).To(Equal(2)) + value, exist := envs["envs"]["test"] + Expect(exist).To(BeTrue()) + Expect(value).To(Equal("test1")) + value, exist = envs["envs"]["bla"] + Expect(exist).To(BeTrue()) + Expect(value).To(Equal("bla")) + }) + }) +}) diff --git a/pkg/infoprovider/genericInfoProvider.go b/pkg/infoprovider/genericInfoProvider.go index 62e728541..207b3cad5 100644 --- a/pkg/infoprovider/genericInfoProvider.go +++ b/pkg/infoprovider/genericInfoProvider.go @@ -15,6 +15,8 @@ package infoprovider import ( + "github.com/golang/glog" + pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" @@ -37,8 +39,12 @@ func (rp *genericInfoProvider) GetDeviceSpecs() []*pluginapi.DeviceSpec { return devSpecs } -func (rp *genericInfoProvider) GetEnvVal() string { - return rp.pciAddr +func (rp *genericInfoProvider) GetEnvVal() map[string]types.EnvironmentVariables { + envs := make(map[string]string, 0) + envs["pci"] = rp.pciAddr + genericMap := map[string]types.EnvironmentVariables{"netdevice": envs} + glog.Infof("Generic GetEnvVal(): %v", genericMap) + return genericMap } func (rp *genericInfoProvider) GetMounts() []*pluginapi.Mount { diff --git a/pkg/infoprovider/rdmaInfoProvider.go b/pkg/infoprovider/rdmaInfoProvider.go index b7da7cc43..4ab734de6 100644 --- a/pkg/infoprovider/rdmaInfoProvider.go +++ b/pkg/infoprovider/rdmaInfoProvider.go @@ -18,6 +18,8 @@ package infoprovider import ( + "strings" + "github.com/golang/glog" pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" @@ -30,6 +32,7 @@ import ( */ type rdmaInfoProvider struct { rdmaSpec types.RdmaSpec + mounts string } // NewRdmaInfoProvider returns a new Rdma Information Provider @@ -47,11 +50,29 @@ func (ip *rdmaInfoProvider) GetDeviceSpecs() []*pluginapi.DeviceSpec { glog.Errorf("GetDeviceSpecs(): rdma is required in the configuration but the device is not rdma device") return nil } - return ip.rdmaSpec.GetRdmaDeviceSpec() + + devsSpec := ip.rdmaSpec.GetRdmaDeviceSpec() + mounts := "" + for _, devSpec := range devsSpec { + mounts = mounts + devSpec.ContainerPath + "," + } + if mounts != "" { + mounts = strings.TrimSuffix(mounts, ",") + ip.mounts = mounts + } + + return devsSpec } -func (ip *rdmaInfoProvider) GetEnvVal() string { - return "" +func (ip *rdmaInfoProvider) GetEnvVal() map[string]types.EnvironmentVariables { + envs := make(map[string]string, 0) + if ip.mounts != "" { + envs["mounts"] = ip.mounts + } + + rdmaMap := map[string]types.EnvironmentVariables{"rdma": envs} + glog.Infof("RDMA GetEnvVal(): %v", rdmaMap) + return rdmaMap } func (ip *rdmaInfoProvider) GetMounts() []*pluginapi.Mount { diff --git a/pkg/infoprovider/rdmaInfoProvider_test.go b/pkg/infoprovider/rdmaInfoProvider_test.go index e4d0810ff..e18280d95 100644 --- a/pkg/infoprovider/rdmaInfoProvider_test.go +++ b/pkg/infoprovider/rdmaInfoProvider_test.go @@ -56,10 +56,28 @@ var _ = Describe("rdmaInfoProvider", func() { }) }) Describe("GetEnvVal", func() { - It("should always return an empty string", func() { + It("should return an empty object if there are no mounts", func() { rdma := &mocks.RdmaSpec{} dip := infoprovider.NewRdmaInfoProvider(rdma) - Expect(dip.GetEnvVal()).To(BeEmpty()) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["rdma"] + Expect(exist).To(BeTrue()) + Expect(len(envs["rdma"])).To(Equal(0)) + }) + It("should the rdma mounts from deviceSpecs", func() { + rdma := &mocks.RdmaSpec{} + rdma.On("IsRdma").Return(true). + On("GetRdmaDeviceSpec").Return([]*pluginapi.DeviceSpec{{ContainerPath: "/dev/infiniband/issm4"}, {ContainerPath: "/dev/infiniband/umad4"}}) + dip := infoprovider.NewRdmaInfoProvider(rdma) + dip.GetDeviceSpecs() + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["rdma"] + Expect(exist).To(BeTrue()) + mounts, exist := envs["rdma"]["mounts"] + Expect(exist).To(BeTrue()) + Expect(mounts).To(Equal("/dev/infiniband/issm4,/dev/infiniband/umad4")) }) }) Describe("GetMounts", func() { diff --git a/pkg/infoprovider/uioInfoProvider.go b/pkg/infoprovider/uioInfoProvider.go index 4c96d5e8a..7ccaf18ea 100644 --- a/pkg/infoprovider/uioInfoProvider.go +++ b/pkg/infoprovider/uioInfoProvider.go @@ -24,6 +24,7 @@ import ( type uioInfoProvider struct { pciAddr string + uioDev string } // NewUioInfoProvider return instance of uio DeviceInfoProvider @@ -47,13 +48,22 @@ func (rp *uioInfoProvider) GetDeviceSpecs() []*pluginapi.DeviceSpec { ContainerPath: uioDev, Permissions: "mrw", }) + rp.uioDev = uioDev } return devSpecs } -func (rp *uioInfoProvider) GetEnvVal() string { - return rp.pciAddr +func (rp *uioInfoProvider) GetEnvVal() map[string]types.EnvironmentVariables { + envs := make(map[string]string, 0) + envs["pci"] = rp.pciAddr + if rp.uioDev != "" { + envs["mount"] = rp.uioDev + } + + uioMap := map[string]types.EnvironmentVariables{"uio": envs} + glog.Infof("UIO GetEnvVal(): %v", uioMap) + return uioMap } func (rp *uioInfoProvider) GetMounts() []*pluginapi.Mount { diff --git a/pkg/infoprovider/uioInfoProvider_test.go b/pkg/infoprovider/uioInfoProvider_test.go index b737842d8..c89bc206f 100644 --- a/pkg/infoprovider/uioInfoProvider_test.go +++ b/pkg/infoprovider/uioInfoProvider_test.go @@ -66,7 +66,35 @@ var _ = Describe("uioInfoProvider", func() { It("should always return passed PCI address", func() { in := "00:02.0" dip := infoprovider.NewUioInfoProvider(in) - Expect(dip.GetEnvVal()).To(Equal(in)) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["uio"] + Expect(exist).To(BeTrue()) + pci, exist := envs["uio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal(in)) + }) + It("should return passed PCI address and mounts for device", func() { + pciAddr := "0000:02:00.0" + fs := utils.FakeFilesystem{ + Dirs: []string{ + "sys/bus/pci/devices/0000:02:00.0/uio/uio0", + }, + } + defer fs.Use()() + dip := infoprovider.NewUioInfoProvider(pciAddr) + dip.GetDeviceSpecs() + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["uio"] + Expect(exist).To(BeTrue()) + Expect(len(envs["uio"])).To(Equal(2)) + pci, exist := envs["uio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal(pciAddr)) + mount, exist := envs["uio"]["mount"] + Expect(exist).To(BeTrue()) + Expect(mount).To(Equal("/dev/uio0")) }) }) }) diff --git a/pkg/infoprovider/vdpaInfoProvider.go b/pkg/infoprovider/vdpaInfoProvider.go index f60dacb17..97c940cc7 100644 --- a/pkg/infoprovider/vdpaInfoProvider.go +++ b/pkg/infoprovider/vdpaInfoProvider.go @@ -30,6 +30,7 @@ import ( type vdpaInfoProvider struct { dev types.VdpaDevice vdpaType types.VdpaType + vdpaPath string } // NewVdpaInfoProvider returns a new InfoProvider associated with the given VDPAInfo @@ -52,18 +53,27 @@ func (vip *vdpaInfoProvider) GetDeviceSpecs() []*pluginapi.DeviceSpec { // DeviceSpecs only required for vhost vdpa type as the if vip.vdpaType == types.VdpaVhostType { + vdpaPath := vip.dev.GetPath() devSpecs = append(devSpecs, &pluginapi.DeviceSpec{ - HostPath: vip.dev.GetPath(), - ContainerPath: vip.dev.GetPath(), + HostPath: vdpaPath, + ContainerPath: vdpaPath, Permissions: "mrw", }) + vip.vdpaPath = vdpaPath } return devSpecs } // GetEnvVal returns the environment variable value -func (vip *vdpaInfoProvider) GetEnvVal() string { - return "" +func (vip *vdpaInfoProvider) GetEnvVal() map[string]types.EnvironmentVariables { + envs := make(map[string]string, 0) + if vip.vdpaPath != "" { + envs["mount"] = vip.vdpaPath + } + + vdpaMap := map[string]types.EnvironmentVariables{"vdpa": envs} + glog.Infof("VDPA GetEnvVal(): %v", vdpaMap) + return vdpaMap } // GetMounts returns the mount points (none for this InfoProvider) diff --git a/pkg/infoprovider/vdpaInfoProvider_test.go b/pkg/infoprovider/vdpaInfoProvider_test.go index ca911ce29..9b4318c4c 100644 --- a/pkg/infoprovider/vdpaInfoProvider_test.go +++ b/pkg/infoprovider/vdpaInfoProvider_test.go @@ -76,9 +76,28 @@ var _ = Describe("vdpaInfoProvider", func() { }) }) Describe("GetEnvVal", func() { - It("should always return an empty string", func() { + It("should return an empty object if there are no mounts", func() { dip := infoprovider.NewVdpaInfoProvider(types.VdpaVirtioType, nil) - Expect(dip.GetEnvVal()).To(BeEmpty()) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["vdpa"] + Expect(exist).To(BeTrue()) + Expect(len(envs["vdpa"])).To(Equal(0)) + }) + It("should return object with the mounts", func() { + vdpa := &mocks.VdpaDevice{} + vdpa.On("GetType").Return(types.VdpaVhostType). + On("GetPath").Return("/dev/vhost-vdpa1") + dip := infoprovider.NewVdpaInfoProvider(types.VdpaVhostType, vdpa) + dip.GetDeviceSpecs() + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["vdpa"] + Expect(exist).To(BeTrue()) + Expect(len(envs["vdpa"])).To(Equal(1)) + mount, exist := envs["vdpa"]["mount"] + Expect(exist).To(BeTrue()) + Expect(mount).To(Equal("/dev/vhost-vdpa1")) }) }) Describe("GetMounts", func() { diff --git a/pkg/infoprovider/vfioInfoProvider.go b/pkg/infoprovider/vfioInfoProvider.go index fd3ad4c8d..b15c0a9cf 100644 --- a/pkg/infoprovider/vfioInfoProvider.go +++ b/pkg/infoprovider/vfioInfoProvider.go @@ -26,8 +26,9 @@ import ( vfioInfoProvider implements DeviceInfoProvider */ type vfioInfoProvider struct { - pciAddr string - vfioMount string + pciAddr string + vfioMount string + vfioDevContainer string } // NewVfioInfoProvider create instance of VFIO DeviceInfoProvider @@ -55,13 +56,23 @@ func (rp *vfioInfoProvider) GetDeviceSpecs() []*pluginapi.DeviceSpec { ContainerPath: vfioDevContainer, Permissions: "mrw", }) + rp.vfioDevContainer = vfioDevContainer } return devSpecs } -func (rp *vfioInfoProvider) GetEnvVal() string { - return rp.pciAddr +func (rp *vfioInfoProvider) GetEnvVal() map[string]types.EnvironmentVariables { + envs := make(map[string]string, 0) + envs["vfio-mount"] = "/dev/vfio/vfio" + envs["pci"] = rp.pciAddr + if rp.vfioDevContainer != "" { + envs["vfio-dev-mount"] = rp.vfioDevContainer + } + + vfioMap := map[string]types.EnvironmentVariables{"vfio": envs} + glog.Infof("VFIO GetEnvVal(): %v", vfioMap) + return vfioMap } func (rp *vfioInfoProvider) GetMounts() []*pluginapi.Mount { diff --git a/pkg/infoprovider/vfioInfoProvider_test.go b/pkg/infoprovider/vfioInfoProvider_test.go index 66affa1de..2f6e27f3e 100644 --- a/pkg/infoprovider/vfioInfoProvider_test.go +++ b/pkg/infoprovider/vfioInfoProvider_test.go @@ -76,7 +76,41 @@ var _ = Describe("vfioInfoProvider", func() { It("should always return passed PCI address", func() { in := "00:02.0" dip := infoprovider.NewVfioInfoProvider(in) - Expect(dip.GetEnvVal()).To(Equal(in)) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["vfio"] + Expect(exist).To(BeTrue()) + pci, exist := envs["vfio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal(in)) + }) + It("should return passed PCI address and vfio device mount", func() { + pciAddr := "0000:02:00.0" + fs := &utils.FakeFilesystem{ + Dirs: []string{ + "sys/bus/pci/devices/0000:02:00.0", "sys/kernel/iommu_groups/0", + }, + Symlinks: map[string]string{ + "sys/bus/pci/devices/0000:02:00.0/iommu_group": "../../../../kernel/iommu_groups/0", + }, + } + defer fs.Use()() + + dip := infoprovider.NewVfioInfoProvider(pciAddr) + dip.GetDeviceSpecs() + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["vfio"] + Expect(exist).To(BeTrue()) + pci, exist := envs["vfio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal(pciAddr)) + devMount, exist := envs["vfio"]["vfio-dev-mount"] + Expect(exist).To(BeTrue()) + Expect(devMount).To(Equal("/dev/vfio/0")) + vfioMount, exist := envs["vfio"]["vfio-mount"] + Expect(exist).To(BeTrue()) + Expect(vfioMount).To(Equal("/dev/vfio/vfio")) }) }) }) diff --git a/pkg/infoprovider/vhostNetInfoProvider.go b/pkg/infoprovider/vhostNetInfoProvider.go index 3f7995b6d..3a2402624 100644 --- a/pkg/infoprovider/vhostNetInfoProvider.go +++ b/pkg/infoprovider/vhostNetInfoProvider.go @@ -92,8 +92,14 @@ func (ip *vhostNetInfoProvider) GetDeviceSpecs() []*pluginapi.DeviceSpec { return deviceSpec } -func (ip *vhostNetInfoProvider) GetEnvVal() string { - return "" +func (ip *vhostNetInfoProvider) GetEnvVal() map[string]types.EnvironmentVariables { + envs := make(map[string]string, 0) + envs["net-mount"] = "/dev/vhost-net" + envs["tun-mount"] = "/dev/net/tun" + + vhostMap := map[string]types.EnvironmentVariables{"vhost": envs} + glog.Infof("VHOST GetEnvVal(): %v", vhostMap) + return vhostMap } func (ip *vhostNetInfoProvider) GetMounts() []*pluginapi.Mount { diff --git a/pkg/infoprovider/vhostNetInfoProvider_test.go b/pkg/infoprovider/vhostNetInfoProvider_test.go index c04d51075..0f37a6991 100644 --- a/pkg/infoprovider/vhostNetInfoProvider_test.go +++ b/pkg/infoprovider/vhostNetInfoProvider_test.go @@ -51,9 +51,18 @@ var _ = Describe("vdpaInfoProvider", func() { }) }) Describe("GetEnvVal", func() { - It("should always return an empty string", func() { + It("should always return the device mounts info", func() { dip := infoprovider.NewVhostNetInfoProvider() - Expect(dip.GetEnvVal()).To(BeEmpty()) + envs := dip.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["vhost"] + Expect(exist).To(BeTrue()) + mount, exist := envs["vhost"]["net-mount"] + Expect(exist).To(BeTrue()) + Expect(mount).To(Equal("/dev/vhost-net")) + mount, exist = envs["vhost"]["tun-mount"] + Expect(exist).To(BeTrue()) + Expect(mount).To(Equal("/dev/net/tun")) }) }) Describe("GetMounts", func() { diff --git a/pkg/netdevice/pciNetDevice.go b/pkg/netdevice/pciNetDevice.go index f967b728c..cb23b7222 100644 --- a/pkg/netdevice/pciNetDevice.go +++ b/pkg/netdevice/pciNetDevice.go @@ -43,6 +43,10 @@ func NewPciNetDevice(dev *ghw.PCIDevice, rFactory types.ResourceFactory, rc *typ } infoProviders = append(infoProviders, rFactory.GetDefaultInfoProvider(dev.Address, driverName)) + if rc.ExtraEnvVariables != nil { + infoProviders = append(infoProviders, infoprovider.NewEnvInfoProvider(dev.Address, rc.ExtraEnvVariables)) + } + isRdma := false nf, ok := rc.SelectorObj.(*types.NetDeviceSelectors) if ok { diff --git a/pkg/netdevice/pciNetDevice_test.go b/pkg/netdevice/pciNetDevice_test.go index b8ac73998..e24abb149 100644 --- a/pkg/netdevice/pciNetDevice_test.go +++ b/pkg/netdevice/pciNetDevice_test.go @@ -71,7 +71,13 @@ var _ = Describe("PciNetDevice", func() { Expect(dev.GetDriver()).To(Equal("vfio-pci")) Expect(dev.GetNetName()).To(Equal("eth0")) - Expect(dev.GetEnvVal()).To(Equal("0000:00:00.1")) + envs := dev.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["vfio"] + Expect(exist).To(BeTrue()) + pci, exist := envs["vfio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.1")) Expect(dev.GetDeviceSpecs()).To(HaveLen(2)) // /dev/vfio/vfio0 and default /dev/vfio/vfio Expect(dev.IsRdma()).To(BeFalse()) Expect(dev.GetLinkType()).To(Equal("fakeLinkType")) @@ -115,11 +121,13 @@ var _ = Describe("PciNetDevice", func() { f := &mocks.ResourceFactory{} mockInfo1 := &mocks.DeviceInfoProvider{} - mockInfo1.On("GetEnvVal").Return("0000:00:00.1") + mockEnv1 := map[string]types.EnvironmentVariables{"netdevice": {"pci": "0000:00:00.1"}} + mockInfo1.On("GetEnvVal").Return(mockEnv1) mockInfo1.On("GetDeviceSpecs").Return(nil) mockInfo1.On("GetMounts").Return(nil) mockInfo2 := &mocks.DeviceInfoProvider{} - mockInfo2.On("GetEnvVal").Return("0000:00:00.2") + mockEnv2 := map[string]types.EnvironmentVariables{"netdevice": {"pci": "0000:00:00.2"}} + mockInfo2.On("GetEnvVal").Return(mockEnv2) mockInfo2.On("GetDeviceSpecs").Return(nil) mockInfo2.On("GetMounts").Return(nil) f.On("GetDefaultInfoProvider", "0000:00:00.1", "mlx5_core").Return(mockInfo1). @@ -137,7 +145,15 @@ var _ = Describe("PciNetDevice", func() { Expect(dev.GetDriver()).To(Equal("mlx5_core")) Expect(dev.IsRdma()).To(BeTrue()) - Expect(dev.GetEnvVal()).To(Equal("0000:00:00.1")) + envs := dev.GetEnvVal() + Expect(len(envs)).To(Equal(2)) + _, exist := envs["netdevice"] + Expect(exist).To(BeTrue()) + _, exist = envs["rdma"] + Expect(exist).To(BeTrue()) + pci, exist := envs["netdevice"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.1")) Expect(dev.GetDeviceSpecs()).To(HaveLen(2)) // 2x Rdma devs Expect(dev.GetMounts()).To(HaveLen(0)) Expect(err).NotTo(HaveOccurred()) @@ -150,7 +166,15 @@ var _ = Describe("PciNetDevice", func() { dev, err := netdevice.NewPciNetDevice(in2, f, rc) Expect(dev.GetDriver()).To(Equal("mlx5_core")) - Expect(dev.GetEnvVal()).To(Equal("0000:00:00.2")) + envs := dev.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["netdevice"] + Expect(exist).To(BeTrue()) + _, exist = envs["rdma"] + Expect(exist).To(BeFalse()) + pci, exist := envs["netdevice"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.2")) Expect(dev.IsRdma()).To(BeFalse()) Expect(dev.GetDeviceSpecs()).To(HaveLen(0)) Expect(dev.GetMounts()).To(HaveLen(0)) @@ -190,7 +214,15 @@ var _ = Describe("PciNetDevice", func() { dev, err := netdevice.NewPciNetDevice(in, f, rc) Expect(dev.GetDriver()).To(Equal("vfio-pci")) - Expect(dev.GetEnvVal()).To(Equal("0000:00:00.1")) + envs := dev.GetEnvVal() + Expect(len(envs)).To(Equal(2)) + _, exist := envs["vfio"] + Expect(exist).To(BeTrue()) + _, exist = envs["vhost"] + Expect(exist).To(BeTrue()) + pci, exist := envs["vfio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.1")) Expect(dev.GetDeviceSpecs()).To(HaveLen(4)) // /dev/vfio/0 and default /dev/vfio/vfio + vhost-net + tun Expect(dev.IsRdma()).To(BeFalse()) Expect(err).NotTo(HaveOccurred()) @@ -215,7 +247,13 @@ var _ = Describe("PciNetDevice", func() { dev, err := netdevice.NewPciNetDevice(in, f, rc) Expect(dev).NotTo(BeNil()) - Expect(dev.GetEnvVal()).To(Equal("0000:00:00.1")) + envs := dev.GetEnvVal() + Expect(len(envs)).To(Equal(1)) + _, exist := envs["vfio"] + Expect(exist).To(BeTrue()) + pci, exist := envs["vfio"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.1")) Expect(err).NotTo(HaveOccurred()) }) }) @@ -249,11 +287,13 @@ var _ = Describe("PciNetDevice", func() { } defaultInfo1 := &mocks.DeviceInfoProvider{} - defaultInfo1.On("GetEnvVal").Return("0000:00:00.1") + mockEnv1 := map[string]types.EnvironmentVariables{"netdevice": {"pci": "0000:00:00.1"}} + defaultInfo1.On("GetEnvVal").Return(mockEnv1) defaultInfo1.On("GetDeviceSpecs").Return(nil) defaultInfo1.On("GetMounts").Return(nil) defaultInfo2 := &mocks.DeviceInfoProvider{} - defaultInfo2.On("GetEnvVal").Return("0000:00:00.2") + mockEnv2 := map[string]types.EnvironmentVariables{"netdevice": {"pci": "0000:00:00.2"}} + defaultInfo2.On("GetEnvVal").Return(mockEnv2) defaultInfo2.On("GetDeviceSpecs").Return(nil) defaultInfo2.On("GetMounts").Return(nil) @@ -286,7 +326,15 @@ var _ = Describe("PciNetDevice", func() { dev2, err2 := netdevice.NewPciNetDevice(in2, f, rc_virtio) Expect(dev1.GetDriver()).To(Equal("mlx5_core")) - Expect(dev1.GetEnvVal()).To(Equal("0000:00:00.1")) + envs := dev1.GetEnvVal() + Expect(len(envs)).To(Equal(2)) + _, exist := envs["netdevice"] + Expect(exist).To(BeTrue()) + _, exist = envs["vdpa"] + Expect(exist).To(BeTrue()) + pci, exist := envs["netdevice"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.1")) Expect(dev1.GetDeviceSpecs()).To(Equal([]*pluginapi.DeviceSpec{ { HostPath: "/dev/vhost-vdpa1", @@ -298,7 +346,15 @@ var _ = Describe("PciNetDevice", func() { Expect(err1).NotTo(HaveOccurred()) Expect(dev2.GetDriver()).To(Equal("ifcvf")) - Expect(dev2.GetEnvVal()).To(Equal("0000:00:00.2")) + envs = dev2.GetEnvVal() + Expect(len(envs)).To(Equal(2)) + _, exist = envs["netdevice"] + Expect(exist).To(BeTrue()) + _, exist = envs["vdpa"] + Expect(exist).To(BeTrue()) + pci, exist = envs["netdevice"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.2")) Expect(dev2.GetDeviceSpecs()).To(HaveLen(0)) Expect(dev2.GetMounts()).To(HaveLen(0)) Expect(dev2.GetVdpaDevice()).To(Equal(fakeVdpaVirtio)) @@ -315,11 +371,27 @@ var _ = Describe("PciNetDevice", func() { dev1, err1 := netdevice.NewPciNetDevice(in1, f, rc_virtio) dev2, err2 := netdevice.NewPciNetDevice(in2, f, rc_vhost) - Expect(dev1.GetEnvVal()).To(Equal("0000:00:00.1")) + envs := dev1.GetEnvVal() + Expect(len(envs)).To(Equal(2)) + _, exist := envs["netdevice"] + Expect(exist).To(BeTrue()) + _, exist = envs["vdpa"] + Expect(exist).To(BeTrue()) + pci, exist := envs["netdevice"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.1")) Expect(dev1.GetDeviceSpecs()).To(HaveLen(0)) Expect(dev1.GetMounts()).To(HaveLen(0)) Expect(err1).NotTo(HaveOccurred()) - Expect(dev2.GetEnvVal()).To(Equal("0000:00:00.2")) + envs = dev2.GetEnvVal() + Expect(len(envs)).To(Equal(2)) + _, exist = envs["netdevice"] + Expect(exist).To(BeTrue()) + _, exist = envs["vdpa"] + Expect(exist).To(BeTrue()) + pci, exist = envs["netdevice"]["pci"] + Expect(exist).To(BeTrue()) + Expect(pci).To(Equal("0000:00:00.2")) Expect(dev2.GetDeviceSpecs()).To(HaveLen(0)) Expect(dev2.GetMounts()).To(HaveLen(0)) Expect(err2).NotTo(HaveOccurred()) diff --git a/pkg/resources/pool_stub.go b/pkg/resources/pool_stub.go index b738462f7..da4eaa8f6 100644 --- a/pkg/resources/pool_stub.go +++ b/pkg/resources/pool_stub.go @@ -15,10 +15,14 @@ package resources import ( - "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" + "encoding/json" + "fmt" + "strings" "github.com/golang/glog" pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" + + "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" ) // ResourcePoolImpl implements stub ResourcePool interface @@ -93,19 +97,40 @@ func (rp *ResourcePoolImpl) GetDeviceSpecs(deviceIDs []string) []*pluginapi.Devi } // GetEnvs returns a list of device specific Env values for device IDs -func (rp *ResourcePoolImpl) GetEnvs(deviceIDs []string) []string { +func (rp *ResourcePoolImpl) GetEnvs(prefix string, deviceIDs []string) (map[string]string, error) { glog.Infof("GetEnvs(): for devices: %v", deviceIDs) - devEnvs := make([]string, 0) - - // Consolidates all Envs + devEnvs := make(map[string]map[string]types.EnvironmentVariables, 0) + IDList := "" + // Consolidates all ExtraEnvVariables for _, id := range deviceIDs { if dev, ok := rp.devicePool[id]; ok { - env := dev.GetEnvVal() - devEnvs = append(devEnvs, env) + envs := dev.GetEnvVal() + devEnvs[id] = envs + IDList = IDList + id + "," } } - return devEnvs + if len(deviceIDs) > 0 { + IDList = strings.TrimSuffix(IDList, ",") + } + + envs := make(map[string]string) + + // support the old method + key := fmt.Sprintf("%s_%s_%s", "PCIDEVICE", prefix, rp.GetResourceName()) + key = strings.ToUpper(strings.Replace(key, ".", "_", -1)) + envs[key] = IDList + + // new environment json + key = fmt.Sprintf("%s_%s_%s_INFO", "PCIDEVICE", prefix, rp.GetResourceName()) + key = strings.ToUpper(strings.Replace(key, ".", "_", -1)) + envData, err := json.Marshal(devEnvs) + if err != nil { + return nil, fmt.Errorf("failed to marshal environment variable object: %v", err) + } + envs[key] = string(envData) + + return envs, nil } // GetMounts returns a list of Mount for device IDs diff --git a/pkg/resources/pool_stub_test.go b/pkg/resources/pool_stub_test.go index 44f8a4699..7decf9bfb 100644 --- a/pkg/resources/pool_stub_test.go +++ b/pkg/resources/pool_stub_test.go @@ -80,28 +80,6 @@ var _ = Describe("ResourcePool", func() { }) }) }) - Describe("getting envs", func() { - Context("for valid devices", func() { - It("should return valid envs array", func() { - defer fs.Use()() - utils.SetDefaultMockNetlinkProvider() - - d1, _ = netdevice.NewPciNetDevice(newPciDeviceFn("0000:00:00.1"), f, rc) - d2, _ = netdevice.NewPciNetDevice(newPciDeviceFn("0000:00:00.2"), f, rc) - rp = resources.NewResourcePool(rc, - map[string]types.HostDevice{ - "0000:00:00.1": d1, - "0000:00:00.2": d2, - }, - ) - envs := rp.GetEnvs(devs) - - expected := []string{"0000:00:00.1", "0000:00:00.2"} - Expect(envs).To(HaveLen(2)) - Expect(envs).To(ConsistOf(expected)) - }) - }) - }) Describe("getting mounts", func() { Context("for valid devices", func() { It("should return valid mounts array", func() { diff --git a/pkg/resources/server.go b/pkg/resources/server.go index c31c9c9f3..9cf507cb6 100644 --- a/pkg/resources/server.go +++ b/pkg/resources/server.go @@ -121,7 +121,14 @@ func (rs *resourceServer) Allocate(ctx context.Context, rqt *pluginapi.AllocateR for _, container := range rqt.ContainerRequests { containerResp := new(pluginapi.ContainerAllocateResponse) containerResp.Devices = rs.resourcePool.GetDeviceSpecs(container.DevicesIDs) - containerResp.Envs = rs.getEnvs(container.DevicesIDs) + + envs, err := rs.getEnvs(container.DevicesIDs) + if err != nil { + glog.Errorf("failed to get environment variables for device IDs %v: %v", container.DevicesIDs, err) + return nil, err + } + containerResp.Envs = envs + containerResp.Mounts = rs.resourcePool.GetMounts(container.DevicesIDs) resp.ContainerResponses = append(resp.ContainerResponses, containerResp) } @@ -336,20 +343,6 @@ func (rs *resourceServer) triggerUpdate() { } } -func (rs *resourceServer) getEnvs(deviceIDs []string) map[string]string { - envs := make(map[string]string) - key := fmt.Sprintf("%s_%s_%s", "PCIDEVICE", rs.resourceNamePrefix, rs.resourcePool.GetResourceName()) - key = strings.ToUpper(strings.Replace(key, ".", "_", -1)) - envVals := rs.resourcePool.GetEnvs(deviceIDs) - values := "" - lastIndex := len(envVals) - 1 - for i, s := range envVals { - values += s - if i == lastIndex { - break - } - values += "," - } - envs[key] = values - return envs +func (rs *resourceServer) getEnvs(deviceIDs []string) (map[string]string, error) { + return rs.resourcePool.GetEnvs(rs.resourceNamePrefix, deviceIDs) } diff --git a/pkg/resources/server_test.go b/pkg/resources/server_test.go index 2f1eff314..52afa230c 100644 --- a/pkg/resources/server_test.go +++ b/pkg/resources/server_test.go @@ -270,8 +270,8 @@ var _ = Describe("Server", func() { Return(map[string]string{"00:00.01": "/dev/fake"}). On("GetDeviceSpecs", []string{"00:00.01"}). Return([]*pluginapi.DeviceSpec{{ContainerPath: "/dev/fake", HostPath: "/dev/fake", Permissions: "rw"}}). - On("GetEnvs", []string{"00:00.01"}). - Return([]string{"00:00.01"}). + On("GetEnvs", "fake.com", []string{"00:00.01"}). + Return(map[string]string{"PCIDEVICE_FAKE_COM_FAKE_INFO": "{\"00:00.01\":{\"netdevice\":{\"pci\":\"00:00.01\"}}}"}, nil). On("GetMounts", []string{"00:00.01"}). Return([]*pluginapi.Mount{{ContainerPath: "/dev/fake", HostPath: "/dev/fake", ReadOnly: false}}) @@ -319,32 +319,6 @@ var _ = Describe("Server", func() { Expect(err).NotTo(HaveOccurred()) }) }) - DescribeTable("getting env variables", - func(in []string, expected map[string]string) { - fs := &utils.FakeFilesystem{} - defer fs.Use()() - deviceIDs := []string{"fakeid"} - rp := mocks.ResourcePool{} - rp. - On("GetResourceName").Return("fake"). - On("GetEnvs", deviceIDs).Return(in) - - obj := NewResourceServer("fake.com", "fake", true, &rp) - rs := *obj.(*resourceServer) - rs.sockPath = fs.RootDir - actual := rs.getEnvs(deviceIDs) - for k, v := range expected { - Expect(actual).To(HaveKeyWithValue(k, v)) - } - }, - Entry("some values", - []string{"fakeId0", "fakeId1"}, - map[string]string{ - "PCIDEVICE_FAKE_COM_FAKE": "fakeId0,fakeId1", - }, - ), - ) - Describe("ListAndWatch", func() { Context("when first Send call in DevicePlugin_ListAndWatch failed", func() { It("should fail", func() { diff --git a/pkg/types/mocks/APIDevice.go b/pkg/types/mocks/APIDevice.go new file mode 100644 index 000000000..99d18217e --- /dev/null +++ b/pkg/types/mocks/APIDevice.go @@ -0,0 +1,93 @@ +// Code generated by mockery v2.15.0. DO NOT EDIT. + +package mocks + +import ( + types "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" + mock "github.com/stretchr/testify/mock" + v1beta1 "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" +) + +// APIDevice is an autogenerated mock type for the APIDevice type +type APIDevice struct { + mock.Mock +} + +// GetAPIDevice provides a mock function with given fields: +func (_m *APIDevice) GetAPIDevice() *v1beta1.Device { + ret := _m.Called() + + var r0 *v1beta1.Device + if rf, ok := ret.Get(0).(func() *v1beta1.Device); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*v1beta1.Device) + } + } + + return r0 +} + +// GetDeviceSpecs provides a mock function with given fields: +func (_m *APIDevice) GetDeviceSpecs() []*v1beta1.DeviceSpec { + ret := _m.Called() + + var r0 []*v1beta1.DeviceSpec + if rf, ok := ret.Get(0).(func() []*v1beta1.DeviceSpec); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1beta1.DeviceSpec) + } + } + + return r0 +} + +// GetEnvVal provides a mock function with given fields: +func (_m *APIDevice) GetEnvVal() map[string]types.EnvironmentVariables { + ret := _m.Called() + + var r0 map[string]types.EnvironmentVariables + if rf, ok := ret.Get(0).(func() map[string]types.EnvironmentVariables); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]types.EnvironmentVariables) + } + } + + return r0 +} + +// GetMounts provides a mock function with given fields: +func (_m *APIDevice) GetMounts() []*v1beta1.Mount { + ret := _m.Called() + + var r0 []*v1beta1.Mount + if rf, ok := ret.Get(0).(func() []*v1beta1.Mount); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*v1beta1.Mount) + } + } + + return r0 +} + +type mockConstructorTestingTNewAPIDevice interface { + mock.TestingT + Cleanup(func()) +} + +// NewAPIDevice creates a new instance of APIDevice. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewAPIDevice(t mockConstructorTestingTNewAPIDevice) *APIDevice { + mock := &APIDevice{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/types/mocks/AccelDevice.go b/pkg/types/mocks/AccelDevice.go index 7e5cf6245..4433e164c 100644 --- a/pkg/types/mocks/AccelDevice.go +++ b/pkg/types/mocks/AccelDevice.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks import ( + types "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" mock "github.com/stretchr/testify/mock" - v1beta1 "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" ) @@ -88,14 +88,16 @@ func (_m *AccelDevice) GetDriver() string { } // GetEnvVal provides a mock function with given fields: -func (_m *AccelDevice) GetEnvVal() string { +func (_m *AccelDevice) GetEnvVal() map[string]types.EnvironmentVariables { ret := _m.Called() - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { + var r0 map[string]types.EnvironmentVariables + if rf, ok := ret.Get(0).(func() map[string]types.EnvironmentVariables); ok { r0 = rf() } else { - r0 = ret.Get(0).(string) + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]types.EnvironmentVariables) + } } return r0 @@ -131,20 +133,6 @@ func (_m *AccelDevice) GetPciAddr() string { return r0 } -// GetVFID provides a mock function with given fields: -func (_m *AccelDevice) GetVFID() int { - ret := _m.Called() - - var r0 int - if rf, ok := ret.Get(0).(func() int); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(int) - } - - return r0 -} - // GetVendor provides a mock function with given fields: func (_m *AccelDevice) GetVendor() string { ret := _m.Called() @@ -159,13 +147,13 @@ func (_m *AccelDevice) GetVendor() string { return r0 } -type NewAccelDeviceT interface { +type mockConstructorTestingTNewAccelDevice interface { mock.TestingT Cleanup(func()) } // NewAccelDevice creates a new instance of AccelDevice. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewAccelDevice(t NewAccelDeviceT) *AccelDevice { +func NewAccelDevice(t mockConstructorTestingTNewAccelDevice) *AccelDevice { mock := &AccelDevice{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/DeviceInfoProvider.go b/pkg/types/mocks/DeviceInfoProvider.go index a6dd6c156..d4776b8f9 100644 --- a/pkg/types/mocks/DeviceInfoProvider.go +++ b/pkg/types/mocks/DeviceInfoProvider.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks import ( + types "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" mock "github.com/stretchr/testify/mock" - v1beta1 "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" ) @@ -30,14 +30,16 @@ func (_m *DeviceInfoProvider) GetDeviceSpecs() []*v1beta1.DeviceSpec { } // GetEnvVal provides a mock function with given fields: -func (_m *DeviceInfoProvider) GetEnvVal() string { +func (_m *DeviceInfoProvider) GetEnvVal() map[string]types.EnvironmentVariables { ret := _m.Called() - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { + var r0 map[string]types.EnvironmentVariables + if rf, ok := ret.Get(0).(func() map[string]types.EnvironmentVariables); ok { r0 = rf() } else { - r0 = ret.Get(0).(string) + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]types.EnvironmentVariables) + } } return r0 @@ -59,13 +61,13 @@ func (_m *DeviceInfoProvider) GetMounts() []*v1beta1.Mount { return r0 } -type NewDeviceInfoProviderT interface { +type mockConstructorTestingTNewDeviceInfoProvider interface { mock.TestingT Cleanup(func()) } // NewDeviceInfoProvider creates a new instance of DeviceInfoProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewDeviceInfoProvider(t NewDeviceInfoProviderT) *DeviceInfoProvider { +func NewDeviceInfoProvider(t mockConstructorTestingTNewDeviceInfoProvider) *DeviceInfoProvider { mock := &DeviceInfoProvider{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/DeviceProvider.go b/pkg/types/mocks/DeviceProvider.go index 9efc76da1..84ccf2e6d 100644 --- a/pkg/types/mocks/DeviceProvider.go +++ b/pkg/types/mocks/DeviceProvider.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -97,13 +97,13 @@ func (_m *DeviceProvider) ValidConfig(_a0 *types.ResourceConfig) bool { return r0 } -type NewDeviceProviderT interface { +type mockConstructorTestingTNewDeviceProvider interface { mock.TestingT Cleanup(func()) } // NewDeviceProvider creates a new instance of DeviceProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewDeviceProvider(t NewDeviceProviderT) *DeviceProvider { +func NewDeviceProvider(t mockConstructorTestingTNewDeviceProvider) *DeviceProvider { mock := &DeviceProvider{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/DeviceSelector.go b/pkg/types/mocks/DeviceSelector.go index abce95d5b..d4c71c34f 100644 --- a/pkg/types/mocks/DeviceSelector.go +++ b/pkg/types/mocks/DeviceSelector.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -28,13 +28,13 @@ func (_m *DeviceSelector) Filter(_a0 []types.HostDevice) []types.HostDevice { return r0 } -type NewDeviceSelectorT interface { +type mockConstructorTestingTNewDeviceSelector interface { mock.TestingT Cleanup(func()) } // NewDeviceSelector creates a new instance of DeviceSelector. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewDeviceSelector(t NewDeviceSelectorT) *DeviceSelector { +func NewDeviceSelector(t mockConstructorTestingTNewDeviceSelector) *DeviceSelector { mock := &DeviceSelector{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/HostDevice.go b/pkg/types/mocks/HostDevice.go index f9f22d663..d2ea1fb05 100644 --- a/pkg/types/mocks/HostDevice.go +++ b/pkg/types/mocks/HostDevice.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks import ( + types "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" mock "github.com/stretchr/testify/mock" - v1beta1 "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" ) @@ -88,14 +88,16 @@ func (_m *HostDevice) GetDriver() string { } // GetEnvVal provides a mock function with given fields: -func (_m *HostDevice) GetEnvVal() string { +func (_m *HostDevice) GetEnvVal() map[string]types.EnvironmentVariables { ret := _m.Called() - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { + var r0 map[string]types.EnvironmentVariables + if rf, ok := ret.Get(0).(func() map[string]types.EnvironmentVariables); ok { r0 = rf() } else { - r0 = ret.Get(0).(string) + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]types.EnvironmentVariables) + } } return r0 @@ -117,20 +119,6 @@ func (_m *HostDevice) GetMounts() []*v1beta1.Mount { return r0 } -// GetVFID provides a mock function with given fields: -func (_m *HostDevice) GetVFID() int { - ret := _m.Called() - - var r0 int - if rf, ok := ret.Get(0).(func() int); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(int) - } - - return r0 -} - // GetVendor provides a mock function with given fields: func (_m *HostDevice) GetVendor() string { ret := _m.Called() @@ -145,13 +133,13 @@ func (_m *HostDevice) GetVendor() string { return r0 } -type NewHostDeviceT interface { +type mockConstructorTestingTNewHostDevice interface { mock.TestingT Cleanup(func()) } // NewHostDevice creates a new instance of HostDevice. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewHostDevice(t NewHostDeviceT) *HostDevice { +func NewHostDevice(t mockConstructorTestingTNewHostDevice) *HostDevice { mock := &HostDevice{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/LinkWatcher.go b/pkg/types/mocks/LinkWatcher.go index a27e03224..10d74ede0 100644 --- a/pkg/types/mocks/LinkWatcher.go +++ b/pkg/types/mocks/LinkWatcher.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -14,13 +14,13 @@ func (_m *LinkWatcher) Subscribe() { _m.Called() } -type NewLinkWatcherT interface { +type mockConstructorTestingTNewLinkWatcher interface { mock.TestingT Cleanup(func()) } // NewLinkWatcher creates a new instance of LinkWatcher. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewLinkWatcher(t NewLinkWatcherT) *LinkWatcher { +func NewLinkWatcher(t mockConstructorTestingTNewLinkWatcher) *LinkWatcher { mock := &LinkWatcher{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/NadUtils.go b/pkg/types/mocks/NadUtils.go index f0912e030..a3c642237 100644 --- a/pkg/types/mocks/NadUtils.go +++ b/pkg/types/mocks/NadUtils.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -41,13 +41,13 @@ func (_m *NadUtils) SaveDeviceInfoFile(resourceName string, deviceID string, dev return r0 } -type NewNadUtilsT interface { +type mockConstructorTestingTNewNadUtils interface { mock.TestingT Cleanup(func()) } // NewNadUtils creates a new instance of NadUtils. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewNadUtils(t NewNadUtilsT) *NadUtils { +func NewNadUtils(t mockConstructorTestingTNewNadUtils) *NadUtils { mock := &NadUtils{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/NetDevice.go b/pkg/types/mocks/NetDevice.go index 30e3ad02d..c2630f712 100644 --- a/pkg/types/mocks/NetDevice.go +++ b/pkg/types/mocks/NetDevice.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks import ( + types "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" mock "github.com/stretchr/testify/mock" - v1beta1 "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" ) @@ -88,14 +88,16 @@ func (_m *NetDevice) GetDriver() string { } // GetEnvVal provides a mock function with given fields: -func (_m *NetDevice) GetEnvVal() string { +func (_m *NetDevice) GetEnvVal() map[string]types.EnvironmentVariables { ret := _m.Called() - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { + var r0 map[string]types.EnvironmentVariables + if rf, ok := ret.Get(0).(func() map[string]types.EnvironmentVariables); ok { r0 = rf() } else { - r0 = ret.Get(0).(string) + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]types.EnvironmentVariables) + } } return r0 @@ -229,13 +231,13 @@ func (_m *NetDevice) IsRdma() bool { return r0 } -type NewNetDeviceT interface { +type mockConstructorTestingTNewNetDevice interface { mock.TestingT Cleanup(func()) } // NewNetDevice creates a new instance of NetDevice. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewNetDevice(t NewNetDeviceT) *NetDevice { +func NewNetDevice(t mockConstructorTestingTNewNetDevice) *NetDevice { mock := &NetDevice{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/PciDevice.go b/pkg/types/mocks/PciDevice.go index beacbe43b..35c797f5d 100644 --- a/pkg/types/mocks/PciDevice.go +++ b/pkg/types/mocks/PciDevice.go @@ -1,10 +1,10 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks import ( + types "github.com/k8snetworkplumbingwg/sriov-network-device-plugin/pkg/types" mock "github.com/stretchr/testify/mock" - v1beta1 "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" ) @@ -88,14 +88,16 @@ func (_m *PciDevice) GetDriver() string { } // GetEnvVal provides a mock function with given fields: -func (_m *PciDevice) GetEnvVal() string { +func (_m *PciDevice) GetEnvVal() map[string]types.EnvironmentVariables { ret := _m.Called() - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { + var r0 map[string]types.EnvironmentVariables + if rf, ok := ret.Get(0).(func() map[string]types.EnvironmentVariables); ok { r0 = rf() } else { - r0 = ret.Get(0).(string) + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]types.EnvironmentVariables) + } } return r0 @@ -131,20 +133,6 @@ func (_m *PciDevice) GetPciAddr() string { return r0 } -// GetVFID provides a mock function with given fields: -func (_m *PciDevice) GetVFID() int { - ret := _m.Called() - - var r0 int - if rf, ok := ret.Get(0).(func() int); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(int) - } - - return r0 -} - // GetVendor provides a mock function with given fields: func (_m *PciDevice) GetVendor() string { ret := _m.Called() @@ -159,13 +147,13 @@ func (_m *PciDevice) GetVendor() string { return r0 } -type NewPciDeviceT interface { +type mockConstructorTestingTNewPciDevice interface { mock.TestingT Cleanup(func()) } // NewPciDevice creates a new instance of PciDevice. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewPciDevice(t NewPciDeviceT) *PciDevice { +func NewPciDevice(t mockConstructorTestingTNewPciDevice) *PciDevice { mock := &PciDevice{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/PciNetDevice.go b/pkg/types/mocks/PciNetDevice.go index 905cd1580..72b84d4cb 100644 --- a/pkg/types/mocks/PciNetDevice.go +++ b/pkg/types/mocks/PciNetDevice.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -102,14 +102,16 @@ func (_m *PciNetDevice) GetDriver() string { } // GetEnvVal provides a mock function with given fields: -func (_m *PciNetDevice) GetEnvVal() string { +func (_m *PciNetDevice) GetEnvVal() map[string]types.EnvironmentVariables { ret := _m.Called() - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { + var r0 map[string]types.EnvironmentVariables + if rf, ok := ret.Get(0).(func() map[string]types.EnvironmentVariables); ok { r0 = rf() } else { - r0 = ret.Get(0).(string) + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string]types.EnvironmentVariables) + } } return r0 @@ -173,8 +175,8 @@ func (_m *PciNetDevice) GetNetName() string { return r0 } -// GetPfNetName provides a mock function with given fields: -func (_m *PciNetDevice) GetPfNetName() string { +// GetPciAddr provides a mock function with given fields: +func (_m *PciNetDevice) GetPciAddr() string { ret := _m.Called() var r0 string @@ -187,8 +189,8 @@ func (_m *PciNetDevice) GetPfNetName() string { return r0 } -// GetPciAddr provides a mock function with given fields: -func (_m *PciNetDevice) GetPciAddr() string { +// GetPfNetName provides a mock function with given fields: +func (_m *PciNetDevice) GetPfNetName() string { ret := _m.Called() var r0 string @@ -273,13 +275,13 @@ func (_m *PciNetDevice) IsRdma() bool { return r0 } -type NewPciNetDeviceT interface { +type mockConstructorTestingTNewPciNetDevice interface { mock.TestingT Cleanup(func()) } // NewPciNetDevice creates a new instance of PciNetDevice. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewPciNetDevice(t NewPciNetDeviceT) *PciNetDevice { +func NewPciNetDevice(t mockConstructorTestingTNewPciNetDevice) *PciNetDevice { mock := &PciNetDevice{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/RdmaSpec.go b/pkg/types/mocks/RdmaSpec.go index 56b020b70..fde710260 100644 --- a/pkg/types/mocks/RdmaSpec.go +++ b/pkg/types/mocks/RdmaSpec.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -43,13 +43,13 @@ func (_m *RdmaSpec) IsRdma() bool { return r0 } -type NewRdmaSpecT interface { +type mockConstructorTestingTNewRdmaSpec interface { mock.TestingT Cleanup(func()) } // NewRdmaSpec creates a new instance of RdmaSpec. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewRdmaSpec(t NewRdmaSpecT) *RdmaSpec { +func NewRdmaSpec(t mockConstructorTestingTNewRdmaSpec) *RdmaSpec { mock := &RdmaSpec{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/ResourceFactory.go b/pkg/types/mocks/ResourceFactory.go index aa69944c9..7313f54b3 100644 --- a/pkg/types/mocks/ResourceFactory.go +++ b/pkg/types/mocks/ResourceFactory.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -184,13 +184,13 @@ func (_m *ResourceFactory) GetVdpaDevice(_a0 string) types.VdpaDevice { return r0 } -type NewResourceFactoryT interface { +type mockConstructorTestingTNewResourceFactory interface { mock.TestingT Cleanup(func()) } // NewResourceFactory creates a new instance of ResourceFactory. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewResourceFactory(t NewResourceFactoryT) *ResourceFactory { +func NewResourceFactory(t mockConstructorTestingTNewResourceFactory) *ResourceFactory { mock := &ResourceFactory{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/ResourcePool.go b/pkg/types/mocks/ResourcePool.go index 40e85c95d..5b37e868a 100644 --- a/pkg/types/mocks/ResourcePool.go +++ b/pkg/types/mocks/ResourcePool.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -59,20 +59,27 @@ func (_m *ResourcePool) GetDevices() map[string]*v1beta1.Device { return r0 } -// GetEnvs provides a mock function with given fields: deviceIDs -func (_m *ResourcePool) GetEnvs(deviceIDs []string) []string { - ret := _m.Called(deviceIDs) +// GetEnvs provides a mock function with given fields: prefix, deviceIDs +func (_m *ResourcePool) GetEnvs(prefix string, deviceIDs []string) (map[string]string, error) { + ret := _m.Called(prefix, deviceIDs) - var r0 []string - if rf, ok := ret.Get(0).(func([]string) []string); ok { - r0 = rf(deviceIDs) + var r0 map[string]string + if rf, ok := ret.Get(0).(func(string, []string) map[string]string); ok { + r0 = rf(prefix, deviceIDs) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) + r0 = ret.Get(0).(map[string]string) } } - return r0 + var r1 error + if rf, ok := ret.Get(1).(func(string, []string) error); ok { + r1 = rf(prefix, deviceIDs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } // GetMounts provides a mock function with given fields: deviceIDs @@ -147,13 +154,13 @@ func (_m *ResourcePool) StoreDeviceInfoFile(resourceNamePrefix string) error { return r0 } -type NewResourcePoolT interface { +type mockConstructorTestingTNewResourcePool interface { mock.TestingT Cleanup(func()) } // NewResourcePool creates a new instance of ResourcePool. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewResourcePool(t NewResourcePoolT) *ResourcePool { +func NewResourcePool(t mockConstructorTestingTNewResourcePool) *ResourcePool { mock := &ResourcePool{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/ResourceServer.go b/pkg/types/mocks/ResourceServer.go index f397885c0..059e7aab6 100644 --- a/pkg/types/mocks/ResourceServer.go +++ b/pkg/types/mocks/ResourceServer.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -168,13 +168,13 @@ func (_m *ResourceServer) Watch() { _m.Called() } -type NewResourceServerT interface { +type mockConstructorTestingTNewResourceServer interface { mock.TestingT Cleanup(func()) } // NewResourceServer creates a new instance of ResourceServer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewResourceServer(t NewResourceServerT) *ResourceServer { +func NewResourceServer(t mockConstructorTestingTNewResourceServer) *ResourceServer { mock := &ResourceServer{} mock.Mock.Test(t) diff --git a/pkg/types/mocks/VdpaDevice.go b/pkg/types/mocks/VdpaDevice.go index 866fa7765..6dd0e35c0 100644 --- a/pkg/types/mocks/VdpaDevice.go +++ b/pkg/types/mocks/VdpaDevice.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -54,13 +54,13 @@ func (_m *VdpaDevice) GetType() types.VdpaType { return r0 } -type NewVdpaDeviceT interface { +type mockConstructorTestingTNewVdpaDevice interface { mock.TestingT Cleanup(func()) } // NewVdpaDevice creates a new instance of VdpaDevice. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewVdpaDevice(t NewVdpaDeviceT) *VdpaDevice { +func NewVdpaDevice(t mockConstructorTestingTNewVdpaDevice) *VdpaDevice { mock := &VdpaDevice{} mock.Mock.Test(t) diff --git a/pkg/types/types.go b/pkg/types/types.go index 193adbc3a..b97999fec 100644 --- a/pkg/types/types.go +++ b/pkg/types/types.go @@ -91,12 +91,13 @@ var SupportedVdpaTypes = map[VdpaType]string{ // ResourceConfig contains configuration parameters for a resource pool type ResourceConfig struct { // optional resource prefix that will overwrite global prefix specified in cli params - ResourcePrefix string `json:"resourcePrefix,omitempty"` - ResourceName string `json:"resourceName"` // the resource name will be added with resource prefix in K8s api - DeviceType DeviceType `json:"deviceType,omitempty"` - ExcludeTopology bool `json:"excludeTopology,omitempty"` - Selectors *json.RawMessage `json:"selectors,omitempty"` - SelectorObj interface{} + ResourcePrefix string `json:"resourcePrefix,omitempty"` + ResourceName string `json:"resourceName"` // the resource name will be added with resource prefix in K8s api + DeviceType DeviceType `json:"deviceType,omitempty"` + ExcludeTopology bool `json:"excludeTopology,omitempty"` + Selectors *json.RawMessage `json:"selectors,omitempty"` + ExtraEnvVariables map[string]EnvironmentVariables `json:"extraEnvVariables,omitempty"` + SelectorObj interface{} } // DeviceSelectors contains common device selectors fields @@ -106,6 +107,9 @@ type DeviceSelectors struct { Drivers []string `json:"drivers,omitempty"` } +// EnvironmentVariables contains all the key value environment variables for a selected list of PCI +type EnvironmentVariables map[string]string + // GenericPciDeviceSelectors contains common PCI device selectors fields type GenericPciDeviceSelectors struct { PciAddresses []string `json:"pciAddresses,omitempty"` @@ -174,7 +178,7 @@ type ResourcePool interface { GetDevices() map[string]*pluginapi.Device // for ListAndWatch Probe() bool GetDeviceSpecs(deviceIDs []string) []*pluginapi.DeviceSpec - GetEnvs(deviceIDs []string) []string + GetEnvs(prefix string, deviceIDs []string) (map[string]string, error) GetMounts(deviceIDs []string) []*pluginapi.Mount StoreDeviceInfoFile(resourceNamePrefix string) error CleanDeviceInfoFile(resourceNamePrefix string) error @@ -200,7 +204,7 @@ type APIDevice interface { // GetDeviceSpecs returns a list of specs which describes host devices GetDeviceSpecs() []*pluginapi.DeviceSpec // GetEnvVal returns environment variable associated with device - GetEnvVal() string + GetEnvVal() map[string]EnvironmentVariables // GetMounts returns a list of host volumes associated with device GetMounts() []*pluginapi.Mount // GetAPIDevice returns k8s API device @@ -270,7 +274,7 @@ type AccelDevice interface { // DeviceInfoProvider is an interface to get Device Plugin API specific device information type DeviceInfoProvider interface { GetDeviceSpecs() []*pluginapi.DeviceSpec - GetEnvVal() string + GetEnvVal() map[string]EnvironmentVariables GetMounts() []*pluginapi.Mount } diff --git a/pkg/utils/mocks/NetlinkProvider.go b/pkg/utils/mocks/NetlinkProvider.go index e8e19d7e4..968c11ac4 100644 --- a/pkg/utils/mocks/NetlinkProvider.go +++ b/pkg/utils/mocks/NetlinkProvider.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -58,13 +58,13 @@ func (_m *NetlinkProvider) GetLinkAttrs(ifName string) (*netlink.LinkAttrs, erro return r0, r1 } -type NewNetlinkProviderT interface { +type mockConstructorTestingTNewNetlinkProvider interface { mock.TestingT Cleanup(func()) } // NewNetlinkProvider creates a new instance of NetlinkProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewNetlinkProvider(t NewNetlinkProviderT) *NetlinkProvider { +func NewNetlinkProvider(t mockConstructorTestingTNewNetlinkProvider) *NetlinkProvider { mock := &NetlinkProvider{} mock.Mock.Test(t) diff --git a/pkg/utils/mocks/RdmaProvider.go b/pkg/utils/mocks/RdmaProvider.go index 3a01f5680..6a7ccbdc2 100644 --- a/pkg/utils/mocks/RdmaProvider.go +++ b/pkg/utils/mocks/RdmaProvider.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -41,13 +41,13 @@ func (_m *RdmaProvider) GetRdmaDevicesForPcidev(pciAddr string) []string { return r0 } -type NewRdmaProviderT interface { +type mockConstructorTestingTNewRdmaProvider interface { mock.TestingT Cleanup(func()) } // NewRdmaProvider creates a new instance of RdmaProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewRdmaProvider(t NewRdmaProviderT) *RdmaProvider { +func NewRdmaProvider(t mockConstructorTestingTNewRdmaProvider) *RdmaProvider { mock := &RdmaProvider{} mock.Mock.Test(t) diff --git a/pkg/utils/mocks/SriovnetProvider.go b/pkg/utils/mocks/SriovnetProvider.go index 1d92fc9ac..f7eeb7f0a 100644 --- a/pkg/utils/mocks/SriovnetProvider.go +++ b/pkg/utils/mocks/SriovnetProvider.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -30,13 +30,13 @@ func (_m *SriovnetProvider) GetUplinkRepresentor(vfPciAddress string) (string, e return r0, r1 } -type NewSriovnetProviderT interface { +type mockConstructorTestingTNewSriovnetProvider interface { mock.TestingT Cleanup(func()) } // NewSriovnetProvider creates a new instance of SriovnetProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewSriovnetProvider(t NewSriovnetProviderT) *SriovnetProvider { +func NewSriovnetProvider(t mockConstructorTestingTNewSriovnetProvider) *SriovnetProvider { mock := &SriovnetProvider{} mock.Mock.Test(t) diff --git a/pkg/utils/mocks/VdpaProvider.go b/pkg/utils/mocks/VdpaProvider.go index f86dcd278..3e50077ad 100644 --- a/pkg/utils/mocks/VdpaProvider.go +++ b/pkg/utils/mocks/VdpaProvider.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.12.3. DO NOT EDIT. +// Code generated by mockery v2.15.0. DO NOT EDIT. package mocks @@ -35,13 +35,13 @@ func (_m *VdpaProvider) GetVdpaDeviceByPci(pciAddr string) (kvdpa.VdpaDevice, er return r0, r1 } -type NewVdpaProviderT interface { +type mockConstructorTestingTNewVdpaProvider interface { mock.TestingT Cleanup(func()) } // NewVdpaProvider creates a new instance of VdpaProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewVdpaProvider(t NewVdpaProviderT) *VdpaProvider { +func NewVdpaProvider(t mockConstructorTestingTNewVdpaProvider) *VdpaProvider { mock := &VdpaProvider{} mock.Mock.Test(t)