k8s.io/kubernetes@v1.29.3/test/e2e/common/node/container.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package node 18 19 import ( 20 "context" 21 "fmt" 22 "time" 23 24 v1 "k8s.io/api/core/v1" 25 apierrors "k8s.io/apimachinery/pkg/api/errors" 26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 27 "k8s.io/apimachinery/pkg/util/uuid" 28 podutil "k8s.io/kubernetes/pkg/api/v1/pod" 29 e2epod "k8s.io/kubernetes/test/e2e/framework/pod" 30 ) 31 32 const ( 33 // ContainerStatusRetryTimeout represents polling threshold before giving up to get the container status 34 ContainerStatusRetryTimeout = time.Minute * 5 35 // ContainerStatusPollInterval represents duration between polls to get the container status 36 ContainerStatusPollInterval = time.Second * 1 37 ) 38 39 // ConformanceContainer defines the types for running container conformance test cases 40 // One pod one container 41 type ConformanceContainer struct { 42 Container v1.Container 43 RestartPolicy v1.RestartPolicy 44 Volumes []v1.Volume 45 ImagePullSecrets []string 46 47 PodClient *e2epod.PodClient 48 podName string 49 PodSecurityContext *v1.PodSecurityContext 50 } 51 52 // Create creates the defined conformance container 53 func (cc *ConformanceContainer) Create(ctx context.Context) { 54 cc.podName = cc.Container.Name + string(uuid.NewUUID()) 55 imagePullSecrets := []v1.LocalObjectReference{} 56 for _, s := range cc.ImagePullSecrets { 57 imagePullSecrets = append(imagePullSecrets, v1.LocalObjectReference{Name: s}) 58 } 59 pod := &v1.Pod{ 60 ObjectMeta: metav1.ObjectMeta{ 61 Name: cc.podName, 62 }, 63 Spec: v1.PodSpec{ 64 RestartPolicy: cc.RestartPolicy, 65 Containers: []v1.Container{ 66 cc.Container, 67 }, 68 SecurityContext: cc.PodSecurityContext, 69 Volumes: cc.Volumes, 70 ImagePullSecrets: imagePullSecrets, 71 }, 72 } 73 cc.PodClient.Create(ctx, pod) 74 } 75 76 // Delete deletes the defined conformance container 77 func (cc *ConformanceContainer) Delete(ctx context.Context) error { 78 return cc.PodClient.Delete(ctx, cc.podName, *metav1.NewDeleteOptions(0)) 79 } 80 81 // IsReady returns whether this container is ready and error if any 82 func (cc *ConformanceContainer) IsReady(ctx context.Context) (bool, error) { 83 pod, err := cc.PodClient.Get(ctx, cc.podName, metav1.GetOptions{}) 84 if err != nil { 85 return false, err 86 } 87 return podutil.IsPodReady(pod), nil 88 } 89 90 // GetPhase returns the phase of the pod lifecycle and error if any 91 func (cc *ConformanceContainer) GetPhase(ctx context.Context) (v1.PodPhase, error) { 92 pod, err := cc.PodClient.Get(ctx, cc.podName, metav1.GetOptions{}) 93 if err != nil { 94 // it doesn't matter what phase to return as error would not be nil 95 return v1.PodSucceeded, err 96 } 97 return pod.Status.Phase, nil 98 } 99 100 // GetStatus returns the details of the current status of this container and error if any 101 func (cc *ConformanceContainer) GetStatus(ctx context.Context) (v1.ContainerStatus, error) { 102 pod, err := cc.PodClient.Get(ctx, cc.podName, metav1.GetOptions{}) 103 if err != nil { 104 return v1.ContainerStatus{}, err 105 } 106 statuses := pod.Status.ContainerStatuses 107 if len(statuses) != 1 || statuses[0].Name != cc.Container.Name { 108 return v1.ContainerStatus{}, fmt.Errorf("unexpected container statuses %v", statuses) 109 } 110 return statuses[0], nil 111 } 112 113 // Present returns whether this pod is present and error if any 114 func (cc *ConformanceContainer) Present(ctx context.Context) (bool, error) { 115 _, err := cc.PodClient.Get(ctx, cc.podName, metav1.GetOptions{}) 116 if err == nil { 117 return true, nil 118 } 119 if apierrors.IsNotFound(err) { 120 return false, nil 121 } 122 return false, err 123 } 124 125 // ContainerState represents different states of its lifecycle 126 type ContainerState string 127 128 const ( 129 // ContainerStateWaiting represents 'Waiting' container state 130 ContainerStateWaiting ContainerState = "Waiting" 131 // ContainerStateRunning represents 'Running' container state 132 ContainerStateRunning ContainerState = "Running" 133 // ContainerStateTerminated represents 'Terminated' container state 134 ContainerStateTerminated ContainerState = "Terminated" 135 // ContainerStateUnknown represents 'Unknown' container state 136 ContainerStateUnknown ContainerState = "Unknown" 137 ) 138 139 // GetContainerState returns current state the container represents among its lifecycle 140 func GetContainerState(state v1.ContainerState) ContainerState { 141 if state.Waiting != nil { 142 return ContainerStateWaiting 143 } 144 if state.Running != nil { 145 return ContainerStateRunning 146 } 147 if state.Terminated != nil { 148 return ContainerStateTerminated 149 } 150 return ContainerStateUnknown 151 }