k8s.io/kubernetes@v1.29.3/test/e2e_node/volume_manager_test.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 e2enode
    18  
    19  import (
    20  	"context"
    21  	"time"
    22  
    23  	v1 "k8s.io/api/core/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/util/uuid"
    26  	"k8s.io/kubernetes/test/e2e/framework"
    27  	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
    28  	admissionapi "k8s.io/pod-security-admission/api"
    29  
    30  	"fmt"
    31  
    32  	"github.com/onsi/ginkgo/v2"
    33  )
    34  
    35  var _ = SIGDescribe("Kubelet Volume Manager", func() {
    36  	f := framework.NewDefaultFramework("kubelet-volume-manager")
    37  	f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
    38  	ginkgo.Describe("Volume Manager", func() {
    39  		ginkgo.Context("On termination of pod with memory backed volume", func() {
    40  			f.It("should remove the volume from the node", f.WithNodeConformance(), func(ctx context.Context) {
    41  				var (
    42  					memoryBackedPod *v1.Pod
    43  					volumeName      string
    44  				)
    45  				ginkgo.By("Creating a pod with a memory backed volume that exits success without restart", func() {
    46  					volumeName = "memory-volume"
    47  					memoryBackedPod = e2epod.NewPodClient(f).Create(ctx, &v1.Pod{
    48  						ObjectMeta: metav1.ObjectMeta{
    49  							Name:      "pod" + string(uuid.NewUUID()),
    50  							Namespace: f.Namespace.Name,
    51  						},
    52  						Spec: v1.PodSpec{
    53  							RestartPolicy: v1.RestartPolicyNever,
    54  							Containers: []v1.Container{
    55  								{
    56  									Image:   busyboxImage,
    57  									Name:    "container" + string(uuid.NewUUID()),
    58  									Command: []string{"sh", "-c", "echo"},
    59  									VolumeMounts: []v1.VolumeMount{
    60  										{
    61  											Name:      volumeName,
    62  											MountPath: "/tmp",
    63  										},
    64  									},
    65  								},
    66  							},
    67  							Volumes: []v1.Volume{
    68  								{
    69  									Name: volumeName,
    70  									VolumeSource: v1.VolumeSource{
    71  										EmptyDir: &v1.EmptyDirVolumeSource{Medium: v1.StorageMediumMemory},
    72  									},
    73  								},
    74  							},
    75  						},
    76  					})
    77  					err := e2epod.WaitForPodSuccessInNamespace(ctx, f.ClientSet, memoryBackedPod.Name, f.Namespace.Name)
    78  					framework.ExpectNoError(err)
    79  				})
    80  				ginkgo.By("Verifying the memory backed volume was removed from node", func() {
    81  					volumePath := fmt.Sprintf("/tmp/%s/volumes/kubernetes.io~empty-dir/%s", string(memoryBackedPod.UID), volumeName)
    82  					var err error
    83  					for i := 0; i < 10; i++ {
    84  						// need to create a new verification pod on each pass since updates
    85  						//to the HostPath volume aren't propogated to the pod
    86  						pod := e2epod.NewPodClient(f).Create(ctx, &v1.Pod{
    87  							ObjectMeta: metav1.ObjectMeta{
    88  								Name:      "pod" + string(uuid.NewUUID()),
    89  								Namespace: f.Namespace.Name,
    90  							},
    91  							Spec: v1.PodSpec{
    92  								RestartPolicy: v1.RestartPolicyNever,
    93  								Containers: []v1.Container{
    94  									{
    95  										Image:   busyboxImage,
    96  										Name:    "container" + string(uuid.NewUUID()),
    97  										Command: []string{"sh", "-c", "if [ -d " + volumePath + " ]; then exit 1; fi;"},
    98  										VolumeMounts: []v1.VolumeMount{
    99  											{
   100  												Name:      "kubelet-pods",
   101  												MountPath: "/tmp",
   102  											},
   103  										},
   104  									},
   105  								},
   106  								Volumes: []v1.Volume{
   107  									{
   108  										Name: "kubelet-pods",
   109  										VolumeSource: v1.VolumeSource{
   110  											// TODO: remove hardcoded kubelet volume directory path
   111  											// framework.TestContext.KubeVolumeDir is currently not populated for node e2e
   112  											HostPath: &v1.HostPathVolumeSource{Path: "/var/lib/kubelet/pods"},
   113  										},
   114  									},
   115  								},
   116  							},
   117  						})
   118  						err = e2epod.WaitForPodSuccessInNamespace(ctx, f.ClientSet, pod.Name, f.Namespace.Name)
   119  						gp := int64(1)
   120  						_ = e2epod.NewPodClient(f).Delete(ctx, pod.Name, metav1.DeleteOptions{GracePeriodSeconds: &gp})
   121  						if err == nil {
   122  							break
   123  						}
   124  						<-time.After(10 * time.Second)
   125  					}
   126  					framework.ExpectNoError(err)
   127  				})
   128  			})
   129  		})
   130  	})
   131  })