From ddaa3466eb478cb4cc4bdb23915a97cddaaf7d6f Mon Sep 17 00:00:00 2001 From: pacoxu Date: Fri, 16 Apr 2021 18:01:44 +0800 Subject: [PATCH] correct unsafe sysctls e2e test case & use status reason check instead of events watch Signed-off-by: Paco Xu --- test/e2e/common/node/sysctl.go | 63 ++++------------------------------ test/e2e/framework/pod/wait.go | 18 ++++++++++ 2 files changed, 24 insertions(+), 57 deletions(-) diff --git a/test/e2e/common/node/sysctl.go b/test/e2e/common/node/sysctl.go index 45c22680bb888..dc86a38a1cd62 100644 --- a/test/e2e/common/node/sysctl.go +++ b/test/e2e/common/node/sysctl.go @@ -114,56 +114,10 @@ var _ = SIGDescribe("Sysctls [LinuxOnly] [NodeConformance]", func() { /* Release: v1.21 - Testname: Sysctl, allow specified unsafe sysctls - Description: Pod is created with kernel.shm_rmid_forced. Should allow unsafe sysctls that are specified. + Testname: Sysctls, reject invalid sysctls + Description: Pod is created with one valid and two invalid sysctls. Pod should not apply invalid sysctls. [LinuxOnly]: This test is marked as LinuxOnly since Windows does not support sysctls */ - ginkgo.It("should support unsafe sysctls which are actually allowed [MinimumKubeletVersion:1.21]", func() { - pod := testPod() - pod.Spec.SecurityContext = &v1.PodSecurityContext{ - Sysctls: []v1.Sysctl{ - { - Name: "kernel.shm_rmid_forced", - Value: "1", - }, - }, - } - pod.Spec.Containers[0].Command = []string{"/bin/sysctl", "kernel.shm_rmid_forced"} - - ginkgo.By("Creating a pod with the kernel.shm_rmid_forced sysctl") - pod = podClient.Create(pod) - - ginkgo.By("Watching for error events or started pod") - // watch for events instead of termination of pod because the kubelet deletes - // failed pods without running containers. This would create a race as the pod - // might have already been deleted here. - ev, err := f.PodClient().WaitForErrorEventOrSuccess(pod) - framework.ExpectNoError(err) - gomega.Expect(ev).To(gomega.BeNil()) - - ginkgo.By("Waiting for pod completion") - err = e2epod.WaitForPodNoLongerRunningInNamespace(f.ClientSet, pod.Name, f.Namespace.Name) - framework.ExpectNoError(err) - pod, err = podClient.Get(context.TODO(), pod.Name, metav1.GetOptions{}) - framework.ExpectNoError(err) - - ginkgo.By("Checking that the pod succeeded") - framework.ExpectEqual(pod.Status.Phase, v1.PodSucceeded) - - ginkgo.By("Getting logs from the pod") - log, err := e2epod.GetPodLogs(f.ClientSet, f.Namespace.Name, pod.Name, pod.Spec.Containers[0].Name) - framework.ExpectNoError(err) - - ginkgo.By("Checking that the sysctl is actually updated") - gomega.Expect(log).To(gomega.ContainSubstring("kernel.shm_rmid_forced = 1")) - }) - - /* - Release: v1.21 - Testname: Sysctls, reject invalid sysctls - Description: Pod is created with one valid and two invalid sysctls. Pod should not apply invalid sysctls. - [LinuxOnly]: This test is marked as LinuxOnly since Windows does not support sysctls - */ framework.ConformanceIt("should reject invalid sysctls [MinimumKubeletVersion:1.21]", func() { pod := testPod() pod.Spec.SecurityContext = &v1.PodSecurityContext{ @@ -199,6 +153,7 @@ var _ = SIGDescribe("Sysctls [LinuxOnly] [NodeConformance]", func() { gomega.Expect(err.Error()).NotTo(gomega.ContainSubstring("kernel.shmmax")) }) + // Pod is created with kernel.msgmax, an unsafe sysctl. ginkgo.It("should not launch unsafe, but not explicitly enabled sysctls on the node [MinimumKubeletVersion:1.21]", func() { pod := testPod() pod.Spec.SecurityContext = &v1.PodSecurityContext{ @@ -213,15 +168,9 @@ var _ = SIGDescribe("Sysctls [LinuxOnly] [NodeConformance]", func() { ginkgo.By("Creating a pod with an ignorelisted, but not allowlisted sysctl on the node") pod = podClient.Create(pod) - ginkgo.By("Watching for error events or started pod") - // watch for events instead of termination of pod because the kubelet deletes - // failed pods without running containers. This would create a race as the pod - // might have already been deleted here. - ev, err := f.PodClient().WaitForErrorEventOrSuccess(pod) + ginkgo.By("Wait for pod failed reason") + // watch for pod failed reason instead of termination of pod + err := e2epod.WaitForPodFailedReason(f.ClientSet, pod, "SysctlForbidden", f.Timeouts.PodStart) framework.ExpectNoError(err) - - ginkgo.By("Checking that the pod was rejected") - gomega.Expect(ev).ToNot(gomega.BeNil()) - framework.ExpectEqual(ev.Reason, "SysctlForbidden") }) }) diff --git a/test/e2e/framework/pod/wait.go b/test/e2e/framework/pod/wait.go index 2909763736808..d4780bffc5dd8 100644 --- a/test/e2e/framework/pod/wait.go +++ b/test/e2e/framework/pod/wait.go @@ -547,3 +547,21 @@ func WaitForPodContainerToFail(c clientset.Interface, namespace, podName string, func WaitForPodContainerStarted(c clientset.Interface, namespace, podName string, containerIndex int, timeout time.Duration) error { return wait.PollImmediate(poll, timeout, podContainerStarted(c, namespace, podName, containerIndex)) } + +// WaitForPodFailedReason wait for pod failed reason in status, for example "SysctlForbidden". +func WaitForPodFailedReason(c clientset.Interface, pod *v1.Pod, reason string, timeout time.Duration) error { + waitErr := wait.PollImmediate(poll, timeout, func() (bool, error) { + pod, err := c.CoreV1().Pods(pod.Namespace).Get(context.TODO(), pod.Name, metav1.GetOptions{}) + if err != nil { + return false, err + } + if pod.Status.Reason == reason { + return true, nil + } + return false, nil + }) + if waitErr != nil { + return fmt.Errorf("error waiting for pod SysctlForbidden status: %v", waitErr) + } + return nil +}