From fe41fd5cd38e2f589638165623fa81707c0c64c5 Mon Sep 17 00:00:00 2001 From: Sebastian Sch Date: Thu, 25 Nov 2021 11:39:38 +0200 Subject: [PATCH 1/2] Load tun kernel driver This commit extend the sriov-network-config-daemon to try and load the tun device on start. Signed-off-by: Sebastian Sch --- bindata/scripts/load-kmod.sh | 2 +- pkg/daemon/daemon.go | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/bindata/scripts/load-kmod.sh b/bindata/scripts/load-kmod.sh index fb80eebf3..7f3d4dc58 100755 --- a/bindata/scripts/load-kmod.sh +++ b/bindata/scripts/load-kmod.sh @@ -1,7 +1,7 @@ #!/bin/sh # chroot /host/ modprobe $1 kmod_name=$(tr "-" "_" <<< $1) -chroot /host/ lsmod | grep $1 >& /dev/null +chroot /host/ lsmod | grep "^$1" >& /dev/null if [ $? -eq 0 ] then diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index 3830b0064..6a9f5c1aa 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -231,6 +231,7 @@ func (dn *Daemon) Run(stopCh <-chan struct{}, exitCh <-chan error) error { defer dn.workqueue.ShutDown() tryEnableRdma() + tryEnableTun() if err := sriovnetworkv1.InitNicIdMap(dn.kubeClient, namespace); err != nil { return err @@ -942,6 +943,12 @@ func registerPlugins(ns *sriovnetworkv1.SriovNetworkNodeState) []string { return nameList } +func tryEnableTun() { + if err := utils.LoadKernelModule("tun"); err != nil { + glog.Errorf("tryEnableTun(): TUN kernel module not loaded: %v", err) + } +} + func tryEnableRdma() (bool, error) { glog.V(2).Infof("tryEnableRdma()") var stdout, stderr bytes.Buffer From 94c7c8fa819a0dd753a80c1555d2fbcd562b296b Mon Sep 17 00:00:00 2001 From: Sebastian Sch Date: Thu, 25 Nov 2021 11:39:56 +0200 Subject: [PATCH 2/2] Add functional tests for the tun device creation inside a pod Signed-off-by: Sebastian Sch --- test/conformance/tests/sriov_operator.go | 45 +++++++++++++++++++----- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/test/conformance/tests/sriov_operator.go b/test/conformance/tests/sriov_operator.go index 81d303bf5..bc1b04598 100644 --- a/test/conformance/tests/sriov_operator.go +++ b/test/conformance/tests/sriov_operator.go @@ -1136,7 +1136,7 @@ var _ = Describe("[sriov] operator", func() { resourceName := "mainpfresource" sriovDeviceList, err := sriovInfos.FindSriovDevices(testNode) Expect(err).ToNot(HaveOccurred()) - executorPod := createCustomTestPod(testNode, []string{}, true) + executorPod := createCustomTestPod(testNode, []string{}, true, nil) mainDeviceForNode := findMainSriovDevice(executorPod, sriovDeviceList) if mainDeviceForNode == nil { Skip("Could not find pf used as gateway") @@ -1572,7 +1572,7 @@ var _ = Describe("[sriov] operator", func() { }) - Context("vhost-net device Validation", func() { + Context("vhost-net and tun devices Validation", func() { var node string resourceName := "vhostresource" vhostnetwork := "test-vhostnetwork" @@ -1679,17 +1679,35 @@ var _ = Describe("[sriov] operator", func() { It("Should have the vhost-net device inside the container", func() { By("creating a pod") - podObj := createTestPod(node, []string{vhostnetwork}) + podObj := createCustomTestPod(node, []string{vhostnetwork}, false, []corev1.Capability{"NET_ADMIN", "NET_RAW"}) ips, err := network.GetSriovNicIPs(podObj, "net1") Expect(err).ToNot(HaveOccurred()) Expect(ips).NotTo(BeNil(), "No sriov network interface found.") Expect(len(ips)).Should(Equal(1)) - By("check the /dev/vhost device exist inside the container") + By("checking the /dev/vhost device exist inside the container") output, errOutput, err := pod.ExecCommand(clients, podObj, "ls", "/dev/vhost-net") Expect(err).ToNot(HaveOccurred()) Expect(errOutput).To(Equal("")) Expect(output).ToNot(ContainSubstring("cannot access")) + + By("checking the /dev/vhost device exist inside the container") + output, errOutput, err = pod.ExecCommand(clients, podObj, "ls", "/dev/net/tun") + Expect(err).ToNot(HaveOccurred()) + Expect(errOutput).To(Equal("")) + Expect(output).ToNot(ContainSubstring("cannot access")) + + By("creating a tap device inside the container") + output, errOutput, err = pod.ExecCommand(clients, podObj, "ip", "tuntap", "add", "tap23", "mode", "tap", "multi_queue") + Expect(err).ToNot(HaveOccurred()) + Expect(errOutput).To(Equal("")) + Expect(output).ToNot(ContainSubstring("No such file")) + + By("checking the tap device was created inside the container") + output, errOutput, err = pod.ExecCommand(clients, podObj, "ip", "link", "show", "tap23") + Expect(err).ToNot(HaveOccurred()) + Expect(errOutput).To(Equal("")) + Expect(output).To(ContainSubstring("tap23: mtu 1500")) }) }) }) @@ -1738,7 +1756,7 @@ func discoverResourceForMainSriov(nodes *cluster.EnabledNodes) (*sriovv1.Interfa continue } - executorPod := createCustomTestPod(node, []string{}, true) + executorPod := createCustomTestPod(node, []string{}, true, nil) mainDevice := findMainSriovDevice(executorPod, nodeDevices) if mainDevice == nil { return nil, "", "", false @@ -1810,7 +1828,7 @@ func findMainSriovDevice(executorPod *corev1.Pod, sriovDevices []*sriovv1.Interf } func findUnusedSriovDevices(testNode string, sriovDevices []*sriovv1.InterfaceExt) ([]*sriovv1.InterfaceExt, error) { - createdPod := createCustomTestPod(testNode, []string{}, true) + createdPod := createCustomTestPod(testNode, []string{}, true, nil) filteredDevices := []*sriovv1.InterfaceExt{} stdout, _, err := pod.ExecCommand(clients, createdPod, "ip", "route") Expect(err).ToNot(HaveOccurred()) @@ -1991,10 +2009,10 @@ func isPodConditionUnschedulable(pod *k8sv1.Pod, resourceName string) bool { } func createTestPod(node string, networks []string) *k8sv1.Pod { - return createCustomTestPod(node, networks, false) + return createCustomTestPod(node, networks, false, nil) } -func createCustomTestPod(node string, networks []string, hostNetwork bool) *k8sv1.Pod { +func createCustomTestPod(node string, networks []string, hostNetwork bool, podCapabilities []corev1.Capability) *k8sv1.Pod { var podDefinition *corev1.Pod if hostNetwork { podDefinition = pod.DefineWithHostNetwork(node) @@ -2004,6 +2022,17 @@ func createCustomTestPod(node string, networks []string, hostNetwork bool) *k8sv node, ) } + + if podCapabilities != nil && len(podCapabilities) != 0 { + if podDefinition.Spec.Containers[0].SecurityContext == nil { + podDefinition.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{} + } + if podDefinition.Spec.Containers[0].SecurityContext.Capabilities == nil { + podDefinition.Spec.Containers[0].SecurityContext.Capabilities = &corev1.Capabilities{} + } + podDefinition.Spec.Containers[0].SecurityContext.Capabilities.Add = podCapabilities + } + createdPod, err := clients.Pods(namespaces.Test).Create(context.Background(), podDefinition, metav1.CreateOptions{}) Expect(err).ToNot(HaveOccurred())