mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-03 19:58:17 +00:00 
			
		
		
		
	This is the result of automatically editing source files like this:
    go install golang.org/x/tools/cmd/goimports@latest
    find ./test/e2e* -name "*.go" | xargs env PATH=$GOPATH/bin:$PATH ./e2e-framework-sed.sh
with e2e-framework-sed.sh containing this:
sed -i \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecCommandInContainer(/e2epod.ExecCommandInContainer(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecCommandInContainerWithFullOutput(/e2epod.ExecCommandInContainerWithFullOutput(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecShellInContainer(/e2epod.ExecShellInContainer(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecShellInPod(/e2epod.ExecShellInPod(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecShellInPodWithFullOutput(/e2epod.ExecShellInPodWithFullOutput(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.ExecWithOptions(/e2epod.ExecWithOptions(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.MatchContainerOutput(/e2eoutput.MatchContainerOutput(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.PodClient(/e2epod.NewPodClient(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.PodClientNS(/e2epod.PodClientNS(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.TestContainerOutput(/e2eoutput.TestContainerOutput(\1, /" \
    -e "s/\(f\|fr\|\w\w*\.[fF]\w*\)\.TestContainerOutputRegexp(/e2eoutput.TestContainerOutputRegexp(\1, /" \
    -e "s/framework.AddOrUpdateLabelOnNode\b/e2enode.AddOrUpdateLabelOnNode/" \
    -e "s/framework.AllNodes\b/e2edebug.AllNodes/" \
    -e "s/framework.AllNodesReady\b/e2enode.AllNodesReady/" \
    -e "s/framework.ContainerResourceGatherer\b/e2edebug.ContainerResourceGatherer/" \
    -e "s/framework.ContainerResourceUsage\b/e2edebug.ContainerResourceUsage/" \
    -e "s/framework.CreateEmptyFileOnPod\b/e2eoutput.CreateEmptyFileOnPod/" \
    -e "s/framework.DefaultPodDeletionTimeout\b/e2epod.DefaultPodDeletionTimeout/" \
    -e "s/framework.DumpAllNamespaceInfo\b/e2edebug.DumpAllNamespaceInfo/" \
    -e "s/framework.DumpDebugInfo\b/e2eoutput.DumpDebugInfo/" \
    -e "s/framework.DumpNodeDebugInfo\b/e2edebug.DumpNodeDebugInfo/" \
    -e "s/framework.EtcdUpgrade\b/e2eproviders.EtcdUpgrade/" \
    -e "s/framework.EventsLister\b/e2edebug.EventsLister/" \
    -e "s/framework.ExecOptions\b/e2epod.ExecOptions/" \
    -e "s/framework.ExpectNodeHasLabel\b/e2enode.ExpectNodeHasLabel/" \
    -e "s/framework.ExpectNodeHasTaint\b/e2enode.ExpectNodeHasTaint/" \
    -e "s/framework.GCEUpgradeScript\b/e2eproviders.GCEUpgradeScript/" \
    -e "s/framework.ImagePrePullList\b/e2epod.ImagePrePullList/" \
    -e "s/framework.KubectlBuilder\b/e2ekubectl.KubectlBuilder/" \
    -e "s/framework.LocationParamGKE\b/e2eproviders.LocationParamGKE/" \
    -e "s/framework.LogSizeDataTimeseries\b/e2edebug.LogSizeDataTimeseries/" \
    -e "s/framework.LogSizeGatherer\b/e2edebug.LogSizeGatherer/" \
    -e "s/framework.LogsSizeData\b/e2edebug.LogsSizeData/" \
    -e "s/framework.LogsSizeDataSummary\b/e2edebug.LogsSizeDataSummary/" \
    -e "s/framework.LogsSizeVerifier\b/e2edebug.LogsSizeVerifier/" \
    -e "s/framework.LookForStringInLog\b/e2eoutput.LookForStringInLog/" \
    -e "s/framework.LookForStringInPodExec\b/e2eoutput.LookForStringInPodExec/" \
    -e "s/framework.LookForStringInPodExecToContainer\b/e2eoutput.LookForStringInPodExecToContainer/" \
    -e "s/framework.MasterAndDNSNodes\b/e2edebug.MasterAndDNSNodes/" \
    -e "s/framework.MasterNodes\b/e2edebug.MasterNodes/" \
    -e "s/framework.MasterUpgradeGKE\b/e2eproviders.MasterUpgradeGKE/" \
    -e "s/framework.NewKubectlCommand\b/e2ekubectl.NewKubectlCommand/" \
    -e "s/framework.NewLogsVerifier\b/e2edebug.NewLogsVerifier/" \
    -e "s/framework.NewNodeKiller\b/e2enode.NewNodeKiller/" \
    -e "s/framework.NewResourceUsageGatherer\b/e2edebug.NewResourceUsageGatherer/" \
    -e "s/framework.NodeHasTaint\b/e2enode.NodeHasTaint/" \
    -e "s/framework.NodeKiller\b/e2enode.NodeKiller/" \
    -e "s/framework.NodesSet\b/e2edebug.NodesSet/" \
    -e "s/framework.PodClient\b/e2epod.PodClient/" \
    -e "s/framework.RemoveLabelOffNode\b/e2enode.RemoveLabelOffNode/" \
    -e "s/framework.ResourceConstraint\b/e2edebug.ResourceConstraint/" \
    -e "s/framework.ResourceGathererOptions\b/e2edebug.ResourceGathererOptions/" \
    -e "s/framework.ResourceUsagePerContainer\b/e2edebug.ResourceUsagePerContainer/" \
    -e "s/framework.ResourceUsageSummary\b/e2edebug.ResourceUsageSummary/" \
    -e "s/framework.RunHostCmd\b/e2eoutput.RunHostCmd/" \
    -e "s/framework.RunHostCmdOrDie\b/e2eoutput.RunHostCmdOrDie/" \
    -e "s/framework.RunHostCmdWithFullOutput\b/e2eoutput.RunHostCmdWithFullOutput/" \
    -e "s/framework.RunHostCmdWithRetries\b/e2eoutput.RunHostCmdWithRetries/" \
    -e "s/framework.RunKubectl\b/e2ekubectl.RunKubectl/" \
    -e "s/framework.RunKubectlInput\b/e2ekubectl.RunKubectlInput/" \
    -e "s/framework.RunKubectlOrDie\b/e2ekubectl.RunKubectlOrDie/" \
    -e "s/framework.RunKubectlOrDieInput\b/e2ekubectl.RunKubectlOrDieInput/" \
    -e "s/framework.RunKubectlWithFullOutput\b/e2ekubectl.RunKubectlWithFullOutput/" \
    -e "s/framework.RunKubemciCmd\b/e2ekubectl.RunKubemciCmd/" \
    -e "s/framework.RunKubemciWithKubeconfig\b/e2ekubectl.RunKubemciWithKubeconfig/" \
    -e "s/framework.SingleContainerSummary\b/e2edebug.SingleContainerSummary/" \
    -e "s/framework.SingleLogSummary\b/e2edebug.SingleLogSummary/" \
    -e "s/framework.TimestampedSize\b/e2edebug.TimestampedSize/" \
    -e "s/framework.WaitForAllNodesSchedulable\b/e2enode.WaitForAllNodesSchedulable/" \
    -e "s/framework.WaitForSSHTunnels\b/e2enode.WaitForSSHTunnels/" \
    -e "s/framework.WorkItem\b/e2edebug.WorkItem/" \
    "$@"
for i in "$@"; do
    # Import all sub packages and let goimports figure out which of those
    # are redundant (= already imported) or not needed.
    sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2edebug "k8s.io/kubernetes/test/e2e/framework/debug"' "$i"
    sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2ekubectl "k8s.io/kubernetes/test/e2e/framework/kubectl"' "$i"
    sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2enode "k8s.io/kubernetes/test/e2e/framework/node"' "$i"
    sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"' "$i"
    sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2epod "k8s.io/kubernetes/test/e2e/framework/pod"' "$i"
    sed -i -e '/"k8s.io.kubernetes.test.e2e.framework"/a e2eproviders "k8s.io/kubernetes/test/e2e/framework/providers"' "$i"
    goimports -w "$i"
done
		
	
		
			
				
	
	
		
			229 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			229 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2020 The Kubernetes Authors.
 | 
						|
 | 
						|
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 e2enode
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"strconv"
 | 
						|
	"strings"
 | 
						|
	"time"
 | 
						|
 | 
						|
	v1 "k8s.io/api/core/v1"
 | 
						|
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						|
	admissionapi "k8s.io/pod-security-admission/api"
 | 
						|
 | 
						|
	"k8s.io/apimachinery/pkg/fields"
 | 
						|
	"k8s.io/apimachinery/pkg/util/uuid"
 | 
						|
	"k8s.io/kubernetes/pkg/kubelet/events"
 | 
						|
	kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
 | 
						|
	"k8s.io/kubernetes/test/e2e/framework"
 | 
						|
	e2eevents "k8s.io/kubernetes/test/e2e/framework/events"
 | 
						|
	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
 | 
						|
	testutils "k8s.io/kubernetes/test/utils"
 | 
						|
	imageutils "k8s.io/kubernetes/test/utils/image"
 | 
						|
 | 
						|
	"k8s.io/kubernetes/pkg/features"
 | 
						|
	kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
 | 
						|
 | 
						|
	"github.com/onsi/ginkgo/v2"
 | 
						|
)
 | 
						|
 | 
						|
var _ = SIGDescribe("Pod conditions managed by Kubelet", func() {
 | 
						|
	f := framework.NewDefaultFramework("pod-conditions")
 | 
						|
	f.NamespacePodSecurityEnforceLevel = admissionapi.LevelBaseline
 | 
						|
 | 
						|
	ginkgo.Context("including PodHasNetwork condition [Serial] [Feature:PodHasNetwork]", func() {
 | 
						|
		tempSetCurrentKubeletConfig(f, func(initialConfig *kubeletconfig.KubeletConfiguration) {
 | 
						|
			initialConfig.FeatureGates = map[string]bool{
 | 
						|
				string(features.PodHasNetworkCondition): true,
 | 
						|
			}
 | 
						|
		})
 | 
						|
		ginkgo.It("a pod without init containers should report all conditions set in expected order after the pod is up", runPodReadyConditionsTest(f, false, true))
 | 
						|
		ginkgo.It("a pod with init containers should report all conditions set in expected order after the pod is up", runPodReadyConditionsTest(f, true, true))
 | 
						|
		ginkgo.It("a pod failing to mount volumes and without init containers should report scheduled and initialized conditions set", runPodFailingConditionsTest(f, false, true))
 | 
						|
		ginkgo.It("a pod failing to mount volumes and with init containers should report just the scheduled condition set", runPodFailingConditionsTest(f, true, true))
 | 
						|
	})
 | 
						|
 | 
						|
	ginkgo.Context("without PodHasNetwork condition", func() {
 | 
						|
		ginkgo.It("a pod without init containers should report all conditions set in expected order after the pod is up", runPodReadyConditionsTest(f, false, false))
 | 
						|
		ginkgo.It("a pod with init containers should report all conditions set in expected order after the pod is up", runPodReadyConditionsTest(f, true, false))
 | 
						|
		ginkgo.It("a pod failing to mount volumes and without init containers should report scheduled and initialized conditions set", runPodFailingConditionsTest(f, false, false))
 | 
						|
		ginkgo.It("a pod failing to mount volumes and with init containers should report just the scheduled condition set", runPodFailingConditionsTest(f, true, false))
 | 
						|
	})
 | 
						|
})
 | 
						|
 | 
						|
func runPodFailingConditionsTest(f *framework.Framework, hasInitContainers, checkPodHasNetwork bool) func() {
 | 
						|
	return func() {
 | 
						|
		ginkgo.By("creating a pod whose sandbox creation is blocked due to a missing volume")
 | 
						|
 | 
						|
		p := webserverPodSpec("pod-"+string(uuid.NewUUID()), "web1", "init1", hasInitContainers)
 | 
						|
		p.Spec.Volumes = []v1.Volume{
 | 
						|
			{
 | 
						|
				Name: "cm",
 | 
						|
				VolumeSource: v1.VolumeSource{
 | 
						|
					ConfigMap: &v1.ConfigMapVolumeSource{
 | 
						|
						LocalObjectReference: v1.LocalObjectReference{Name: "does-not-exist"},
 | 
						|
					},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		}
 | 
						|
		p.Spec.Containers[0].VolumeMounts = []v1.VolumeMount{
 | 
						|
			{
 | 
						|
				Name:      "cm",
 | 
						|
				MountPath: "/config",
 | 
						|
			},
 | 
						|
		}
 | 
						|
 | 
						|
		p = e2epod.NewPodClient(f).Create(p)
 | 
						|
 | 
						|
		ginkgo.By("waiting until kubelet has started trying to set up the pod and started to fail")
 | 
						|
 | 
						|
		eventSelector := fields.Set{
 | 
						|
			"involvedObject.kind":      "Pod",
 | 
						|
			"involvedObject.name":      p.Name,
 | 
						|
			"involvedObject.namespace": f.Namespace.Name,
 | 
						|
			"reason":                   events.FailedMountVolume,
 | 
						|
		}.AsSelector().String()
 | 
						|
		e2eevents.WaitTimeoutForEvent(f.ClientSet, f.Namespace.Name, eventSelector, "MountVolume.SetUp failed for volume", framework.PodEventTimeout)
 | 
						|
 | 
						|
		p, err := e2epod.NewPodClient(f).Get(context.TODO(), p.Name, metav1.GetOptions{})
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
 | 
						|
		ginkgo.By("checking pod condition for a pod whose sandbox creation is blocked")
 | 
						|
 | 
						|
		scheduledTime, err := getTransitionTimeForPodConditionWithStatus(p, v1.PodScheduled, true)
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
 | 
						|
		// Verify PodHasNetwork is not set (since sandboxcreation is blocked)
 | 
						|
		if checkPodHasNetwork {
 | 
						|
			_, err := getTransitionTimeForPodConditionWithStatus(p, kubetypes.PodHasNetwork, false)
 | 
						|
			framework.ExpectNoError(err)
 | 
						|
		}
 | 
						|
 | 
						|
		if hasInitContainers {
 | 
						|
			// Verify PodInitialized is not set if init containers are present (since sandboxcreation is blocked)
 | 
						|
			_, err := getTransitionTimeForPodConditionWithStatus(p, v1.PodInitialized, false)
 | 
						|
			framework.ExpectNoError(err)
 | 
						|
		} else {
 | 
						|
			// Verify PodInitialized is set if init containers are not present (since without init containers, it gets set very early)
 | 
						|
			initializedTime, err := getTransitionTimeForPodConditionWithStatus(p, v1.PodInitialized, true)
 | 
						|
			framework.ExpectNoError(err)
 | 
						|
			framework.ExpectNotEqual(initializedTime.Before(scheduledTime), true, fmt.Sprintf("pod without init containers is initialized at: %v which is before pod scheduled at: %v", initializedTime, scheduledTime))
 | 
						|
		}
 | 
						|
 | 
						|
		// Verify ContainersReady is not set (since sandboxcreation is blocked)
 | 
						|
		_, err = getTransitionTimeForPodConditionWithStatus(p, v1.ContainersReady, false)
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
		// Verify PodReady is not set (since sandboxcreation is blocked)
 | 
						|
		_, err = getTransitionTimeForPodConditionWithStatus(p, v1.PodReady, false)
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func runPodReadyConditionsTest(f *framework.Framework, hasInitContainers, checkPodHasNetwork bool) func() {
 | 
						|
	return func() {
 | 
						|
		ginkgo.By("creating a pod that successfully comes up in a ready/running state")
 | 
						|
 | 
						|
		p := e2epod.NewPodClient(f).Create(webserverPodSpec("pod-"+string(uuid.NewUUID()), "web1", "init1", hasInitContainers))
 | 
						|
		e2epod.WaitTimeoutForPodReadyInNamespace(f.ClientSet, p.Name, f.Namespace.Name, framework.PodStartTimeout)
 | 
						|
 | 
						|
		p, err := e2epod.NewPodClient(f).Get(context.TODO(), p.Name, metav1.GetOptions{})
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
		isReady, err := testutils.PodRunningReady(p)
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
		framework.ExpectEqual(isReady, true, "pod should be ready")
 | 
						|
 | 
						|
		ginkgo.By("checking order of pod condition transitions for a pod with no container/sandbox restarts")
 | 
						|
 | 
						|
		scheduledTime, err := getTransitionTimeForPodConditionWithStatus(p, v1.PodScheduled, true)
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
		initializedTime, err := getTransitionTimeForPodConditionWithStatus(p, v1.PodInitialized, true)
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
 | 
						|
		condBeforeContainersReadyTransitionTime := initializedTime
 | 
						|
		errSubstrIfContainersReadyTooEarly := "is initialized"
 | 
						|
		if checkPodHasNetwork {
 | 
						|
			hasNetworkTime, err := getTransitionTimeForPodConditionWithStatus(p, kubetypes.PodHasNetwork, true)
 | 
						|
			framework.ExpectNoError(err)
 | 
						|
 | 
						|
			if hasInitContainers {
 | 
						|
				// With init containers, verify the sequence of conditions is: Scheduled => HasNetwork => Initialized
 | 
						|
				framework.ExpectNotEqual(hasNetworkTime.Before(scheduledTime), true, fmt.Sprintf("pod with init containers is initialized at: %v which is before pod has network at: %v", initializedTime, hasNetworkTime))
 | 
						|
				framework.ExpectNotEqual(initializedTime.Before(hasNetworkTime), true, fmt.Sprintf("pod with init containers is initialized at: %v which is before pod has network at: %v", initializedTime, hasNetworkTime))
 | 
						|
			} else {
 | 
						|
				// Without init containers, verify the sequence of conditions is: Scheduled => Initialized => HasNetwork
 | 
						|
				condBeforeContainersReadyTransitionTime = hasNetworkTime
 | 
						|
				errSubstrIfContainersReadyTooEarly = "has network"
 | 
						|
				framework.ExpectNotEqual(initializedTime.Before(scheduledTime), true, fmt.Sprintf("pod without init containers initialized at: %v which is before pod scheduled at: %v", initializedTime, scheduledTime))
 | 
						|
				framework.ExpectNotEqual(hasNetworkTime.Before(initializedTime), true, fmt.Sprintf("pod without init containers has network at: %v which is before pod is initialized at: %v", hasNetworkTime, initializedTime))
 | 
						|
			}
 | 
						|
		} else {
 | 
						|
			// In the absence of HasNetwork feature disabled, verify the sequence is: Scheduled => Initialized
 | 
						|
			framework.ExpectNotEqual(initializedTime.Before(scheduledTime), true, fmt.Sprintf("pod initialized at: %v which is before pod scheduled at: %v", initializedTime, scheduledTime))
 | 
						|
		}
 | 
						|
		// Verify the next condition to get set is ContainersReady
 | 
						|
		containersReadyTime, err := getTransitionTimeForPodConditionWithStatus(p, v1.ContainersReady, true)
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
		framework.ExpectNotEqual(containersReadyTime.Before(condBeforeContainersReadyTransitionTime), true, fmt.Sprintf("containers ready at: %v which is before pod %s: %v", containersReadyTime, errSubstrIfContainersReadyTooEarly, initializedTime))
 | 
						|
 | 
						|
		// Verify ContainersReady => PodReady
 | 
						|
		podReadyTime, err := getTransitionTimeForPodConditionWithStatus(p, v1.PodReady, true)
 | 
						|
		framework.ExpectNoError(err)
 | 
						|
		framework.ExpectNotEqual(podReadyTime.Before(containersReadyTime), true, fmt.Sprintf("pod ready at: %v which is before pod containers ready at: %v", podReadyTime, containersReadyTime))
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func getTransitionTimeForPodConditionWithStatus(pod *v1.Pod, condType v1.PodConditionType, expectedStatus bool) (time.Time, error) {
 | 
						|
	for _, cond := range pod.Status.Conditions {
 | 
						|
		if cond.Type == condType {
 | 
						|
			if strings.EqualFold(string(cond.Status), strconv.FormatBool(expectedStatus)) {
 | 
						|
				return cond.LastTransitionTime.Time, nil
 | 
						|
			}
 | 
						|
			return time.Time{}, fmt.Errorf("condition: %s found for pod but status: %s did not match expected status: %s", condType, cond.Status, strconv.FormatBool(expectedStatus))
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return time.Time{}, fmt.Errorf("condition: %s not found for pod", condType)
 | 
						|
}
 | 
						|
 | 
						|
func webserverPodSpec(podName, containerName, initContainerName string, addInitContainer bool) *v1.Pod {
 | 
						|
	p := &v1.Pod{
 | 
						|
		ObjectMeta: metav1.ObjectMeta{
 | 
						|
			Name: podName,
 | 
						|
		},
 | 
						|
		Spec: v1.PodSpec{
 | 
						|
			Containers: []v1.Container{
 | 
						|
				{
 | 
						|
					Name:  containerName,
 | 
						|
					Image: imageutils.GetE2EImage(imageutils.Agnhost),
 | 
						|
					Args:  []string{"test-webserver"},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
	}
 | 
						|
	if addInitContainer {
 | 
						|
		p.Spec.InitContainers = []v1.Container{
 | 
						|
			{
 | 
						|
				Name:    initContainerName,
 | 
						|
				Image:   imageutils.GetE2EImage(imageutils.BusyBox),
 | 
						|
				Command: []string{"sh", "-c", "sleep 5s"},
 | 
						|
			},
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return p
 | 
						|
}
 |