11package node
22
33import (
4+ "context"
5+ "fmt"
6+ "regexp"
47 "strings"
58 "time"
69
710 g "github.com/onsi/ginkgo/v2"
811 o "github.com/onsi/gomega"
9- nodeutils "github.com/openshift/origin/test/extended/node "
10- exutil "github.com/openshift/origin/test/extended/util "
12+ corev1 "k8s.io/api/core/v1 "
13+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1 "
1114 "k8s.io/apimachinery/pkg/util/wait"
1215 e2e "k8s.io/kubernetes/test/e2e/framework"
16+ e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
17+
18+ nodeutils "github.com/openshift/origin/test/extended/node"
19+ exutil "github.com/openshift/origin/test/extended/util"
1320)
1421
1522var _ = g .Describe ("[sig-node] [Jira:Node/Kubelet] Kubelet, CRI-O, CPU manager" , func () {
@@ -19,8 +26,24 @@ var _ = g.Describe("[sig-node] [Jira:Node/Kubelet] Kubelet, CRI-O, CPU manager",
1926
2027 // Skip all tests on MicroShift clusters as MachineConfig resources are not available
2128 g .BeforeEach (func () {
22- isMicroShift , err := exutil .IsMicroShiftCluster (oc .AdminKubeClient ())
23- o .Expect (err ).NotTo (o .HaveOccurred ())
29+ var isMicroShift bool
30+ var err error
31+
32+ // Retry check for robustness - OpenShift should eventually respond
33+ pollErr := wait .Poll (2 * time .Second , 30 * time .Second , func () (bool , error ) {
34+ isMicroShift , err = exutil .IsMicroShiftCluster (oc .AdminKubeClient ())
35+ if err != nil {
36+ e2e .Logf ("Failed to check if cluster is MicroShift: %v, retrying..." , err )
37+ return false , nil
38+ }
39+ return true , nil
40+ })
41+
42+ if pollErr != nil {
43+ e2e .Logf ("Setup failed: unable to determine if cluster is MicroShift after retries: %v" , err )
44+ g .Fail ("Setup failed: unable to determine cluster type - this is an infrastructure/connectivity issue, not a test failure" )
45+ }
46+
2447 if isMicroShift {
2548 g .Skip ("Skipping test on MicroShift cluster - MachineConfig resources are not available" )
2649 }
@@ -104,3 +127,166 @@ var _ = g.Describe("[sig-node] [Jira:Node/Kubelet] Kubelet, CRI-O, CPU manager",
104127 o .Expect (output ).To (o .ContainSubstring ("spec.cgroupMode: Unsupported value: \" v1\" : supported values: \" v2\" , \" \" " ))
105128 })
106129})
130+
131+ var _ = g .Describe ("[sig-node] [Jira:Node/Kubelet] NODE initContainer policy,volume,readines,quota" , func () {
132+ defer g .GinkgoRecover ()
133+
134+ var (
135+ oc = exutil .NewCLI ("node-initcontainer" )
136+ )
137+
138+ // Skip all tests on MicroShift clusters as MachineConfig resources are not available
139+ g .BeforeEach (func () {
140+ var isMicroShift bool
141+ var err error
142+
143+ // Retry check for robustness - OpenShift should eventually respond
144+ pollErr := wait .Poll (2 * time .Second , 30 * time .Second , func () (bool , error ) {
145+ isMicroShift , err = exutil .IsMicroShiftCluster (oc .AdminKubeClient ())
146+ if err != nil {
147+ e2e .Logf ("Failed to check if cluster is MicroShift: %v, retrying..." , err )
148+ return false , nil
149+ }
150+ return true , nil
151+ })
152+
153+ if pollErr != nil {
154+ e2e .Logf ("Setup failed: unable to determine if cluster is MicroShift after retries: %v" , err )
155+ g .Fail ("Setup failed: unable to determine cluster type - this is an infrastructure/connectivity issue, not a test failure" )
156+ }
157+
158+ if isMicroShift {
159+ g .Skip ("Skipping test on MicroShift cluster - MachineConfig resources are not available" )
160+ }
161+ })
162+
163+ //author: bgudi@redhat.com
164+ g .It ("[OTP] Init containers should not restart when the exited init container is removed from node [OCP-38271]" , func () {
165+ g .By ("Test for case OCP-38271" )
166+ oc .SetupProject ()
167+
168+ podName := "initcon-pod"
169+ namespace := oc .Namespace ()
170+ ctx := context .Background ()
171+
172+ g .By ("Create a pod with init container" )
173+ pod := & corev1.Pod {
174+ ObjectMeta : metav1.ObjectMeta {
175+ Name : podName ,
176+ Namespace : namespace ,
177+ },
178+ Spec : corev1.PodSpec {
179+ InitContainers : []corev1.Container {
180+ {
181+ Name : "inittest" ,
182+ Image : "quay.io/openshifttest/busybox@sha256:c5439d7db88ab5423999530349d327b04279ad3161d7596d2126dfb5b02bfd1f" ,
183+ Command : []string {"bin/sh" , "-ec" , "echo running >> /mnt/data/test" },
184+ VolumeMounts : []corev1.VolumeMount {
185+ {
186+ Name : "data" ,
187+ MountPath : "/mnt/data" ,
188+ },
189+ },
190+ },
191+ },
192+ Containers : []corev1.Container {
193+ {
194+ Name : "hello-test" ,
195+ Image : "quay.io/openshifttest/busybox@sha256:c5439d7db88ab5423999530349d327b04279ad3161d7596d2126dfb5b02bfd1f" ,
196+ Command : []string {"bin/sh" , "-c" , "sleep 3600" },
197+ VolumeMounts : []corev1.VolumeMount {
198+ {
199+ Name : "data" ,
200+ MountPath : "/mnt/data" ,
201+ },
202+ },
203+ },
204+ },
205+ Volumes : []corev1.Volume {
206+ {
207+ Name : "data" ,
208+ VolumeSource : corev1.VolumeSource {
209+ EmptyDir : & corev1.EmptyDirVolumeSource {},
210+ },
211+ },
212+ },
213+ RestartPolicy : corev1 .RestartPolicyNever ,
214+ },
215+ }
216+
217+ _ , err := oc .KubeClient ().CoreV1 ().Pods (namespace ).Create (ctx , pod , metav1.CreateOptions {})
218+ o .Expect (err ).NotTo (o .HaveOccurred ())
219+ defer func () {
220+ oc .KubeClient ().CoreV1 ().Pods (namespace ).Delete (ctx , podName , metav1.DeleteOptions {})
221+ }()
222+
223+ g .By ("Check pod status" )
224+ err = e2epod .WaitForPodRunningInNamespace (ctx , oc .KubeClient (), pod )
225+ o .Expect (err ).NotTo (o .HaveOccurred (), "pod is not running" )
226+
227+ g .By ("Check init container exit normally" )
228+ err = wait .Poll (5 * time .Second , 1 * time .Minute , func () (bool , error ) {
229+ pod , err := oc .KubeClient ().CoreV1 ().Pods (namespace ).Get (ctx , podName , metav1.GetOptions {})
230+ if err != nil {
231+ return false , err
232+ }
233+ for _ , status := range pod .Status .InitContainerStatuses {
234+ if status .Name == "inittest" {
235+ if status .State .Terminated != nil && status .State .Terminated .ExitCode == 0 {
236+ e2e .Logf ("Init container exited with code 0" )
237+ return true , nil
238+ }
239+ }
240+ }
241+ return false , nil
242+ })
243+ o .Expect (err ).NotTo (o .HaveOccurred (), "container not exit normally" )
244+
245+ g .By ("Get node where pod is running" )
246+ pod , err = oc .KubeClient ().CoreV1 ().Pods (namespace ).Get (ctx , podName , metav1.GetOptions {})
247+ o .Expect (err ).NotTo (o .HaveOccurred ())
248+ nodeName := pod .Spec .NodeName
249+ o .Expect (nodeName ).NotTo (o .BeEmpty (), "pod node name is empty" )
250+
251+ g .By ("Get init container ID from pod status" )
252+ var containerID string
253+ for _ , status := range pod .Status .InitContainerStatuses {
254+ if status .Name == "inittest" {
255+ containerID = status .ContainerID
256+ break
257+ }
258+ }
259+ o .Expect (containerID ).NotTo (o .BeEmpty (), "init container ID is empty" )
260+
261+ // Extract the actual container ID (remove prefix like "cri-o://")
262+ containerIDPattern := regexp .MustCompile (`^[^/]+://(.+)$` )
263+ matches := containerIDPattern .FindStringSubmatch (containerID )
264+ o .Expect (matches ).To (o .HaveLen (2 ), "failed to parse container ID" )
265+ actualContainerID := matches [1 ]
266+
267+ g .By ("Delete init container from node" )
268+ deleteCmd := fmt .Sprintf ("crictl rm %s" , actualContainerID )
269+ output , err := nodeutils .ExecOnNodeWithChroot (oc , nodeName , "/bin/bash" , "-c" , deleteCmd )
270+ o .Expect (err ).NotTo (o .HaveOccurred (), "fail to delete container" )
271+ e2e .Logf ("Container deletion output: %s" , output )
272+
273+ g .By ("Check init container not restart again" )
274+ err = wait .Poll (5 * time .Second , 1 * time .Minute , func () (bool , error ) {
275+ pod , err := oc .KubeClient ().CoreV1 ().Pods (namespace ).Get (ctx , podName , metav1.GetOptions {})
276+ if err != nil {
277+ return false , err
278+ }
279+ for _ , status := range pod .Status .InitContainerStatuses {
280+ if status .Name == "inittest" {
281+ if status .RestartCount > 0 {
282+ e2e .Logf ("Init container restarted, restart count: %d" , status .RestartCount )
283+ return true , fmt .Errorf ("init container restarted" )
284+ }
285+ }
286+ }
287+ e2e .Logf ("Init container has not restarted" )
288+ return false , nil
289+ })
290+ o .Expect (err ).To (o .Equal (wait .ErrWaitTimeout ), "expected timeout while waiting confirms init container did not restart" )
291+ })
292+ })
0 commit comments