1
16
17 package storage
18
19 import (
20 "context"
21 "fmt"
22 "os"
23 "path"
24
25 v1 "k8s.io/api/core/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/kubernetes/test/e2e/framework"
28 e2epodoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
29 imageutils "k8s.io/kubernetes/test/utils/image"
30 admissionapi "k8s.io/pod-security-admission/api"
31
32 "github.com/onsi/ginkgo/v2"
33 )
34
35
36
37 var _ = SIGDescribe("HostPath", func() {
38 f := framework.NewDefaultFramework("hostpath")
39 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
40
41 ginkgo.BeforeEach(func() {
42
43
44 _ = os.Remove("/tmp/test-file")
45 })
46
47
52 f.It("should give a volume the correct mode [LinuxOnly]", f.WithNodeConformance(), func(ctx context.Context) {
53 source := &v1.HostPathVolumeSource{
54 Path: "/tmp",
55 }
56 pod := testPodWithHostVol(volumePath, source, false)
57
58 pod.Spec.Containers[0].Args = []string{
59 "mounttest",
60 fmt.Sprintf("--fs_type=%v", volumePath),
61 fmt.Sprintf("--file_mode=%v", volumePath),
62 }
63 e2epodoutput.TestContainerOutputRegexp(ctx, f, "hostPath mode", pod, 0, []string{
64 "mode of file \"/test-volume\": dg?trwxrwx",
65 })
66 })
67
68
69 f.It("should support r/w", f.WithNodeConformance(), func(ctx context.Context) {
70 filePath := path.Join(volumePath, "test-file")
71 retryDuration := 180
72 source := &v1.HostPathVolumeSource{
73 Path: "/tmp",
74 }
75
76 privileged := !framework.NodeOSDistroIs("windows")
77 pod := testPodWithHostVol(volumePath, source, privileged)
78
79 pod.Spec.Containers[0].Args = []string{
80 "mounttest",
81 fmt.Sprintf("--new_file_0644=%v", filePath),
82 fmt.Sprintf("--file_mode=%v", filePath),
83 }
84
85 pod.Spec.Containers[1].Args = []string{
86 "mounttest",
87 fmt.Sprintf("--file_content_in_loop=%v", filePath),
88 fmt.Sprintf("--retry_time=%d", retryDuration),
89 }
90
91
92 e2epodoutput.TestContainerOutput(ctx, f, "hostPath r/w", pod, 1, []string{
93 "content of file \"/test-volume/test-file\": mount-tester new file",
94 })
95 })
96
97 f.It("should support subPath", f.WithNodeConformance(), func(ctx context.Context) {
98 subPath := "sub-path"
99 fileName := "test-file"
100 retryDuration := 180
101
102 filePathInWriter := path.Join(volumePath, fileName)
103 filePathInReader := path.Join(volumePath, subPath, fileName)
104
105 source := &v1.HostPathVolumeSource{
106 Path: "/tmp",
107 }
108
109
110 privileged := !framework.NodeOSDistroIs("windows")
111 pod := testPodWithHostVol(volumePath, source, privileged)
112
113
114 container := &pod.Spec.Containers[0]
115 container.VolumeMounts[0].SubPath = subPath
116 container.Args = []string{
117 "mounttest",
118 fmt.Sprintf("--new_file_0644=%v", filePathInWriter),
119 fmt.Sprintf("--file_mode=%v", filePathInWriter),
120 }
121
122
123 pod.Spec.Containers[1].Args = []string{
124 "mounttest",
125 fmt.Sprintf("--file_content_in_loop=%v", filePathInReader),
126 fmt.Sprintf("--retry_time=%d", retryDuration),
127 }
128
129 e2epodoutput.TestContainerOutput(ctx, f, "hostPath subPath", pod, 1, []string{
130 "content of file \"" + filePathInReader + "\": mount-tester new file",
131 })
132 })
133 })
134
135
136
137 const containerName1 = "test-container-1"
138 const containerName2 = "test-container-2"
139
140 func mount(source *v1.HostPathVolumeSource) []v1.Volume {
141 return []v1.Volume{
142 {
143 Name: volumeName,
144 VolumeSource: v1.VolumeSource{
145 HostPath: source,
146 },
147 },
148 }
149 }
150
151
152 func testPodWithHostVol(path string, source *v1.HostPathVolumeSource, privileged bool) *v1.Pod {
153 podName := "pod-host-path-test"
154
155 return &v1.Pod{
156 TypeMeta: metav1.TypeMeta{
157 Kind: "Pod",
158 APIVersion: "v1",
159 },
160 ObjectMeta: metav1.ObjectMeta{
161 Name: podName,
162 },
163 Spec: v1.PodSpec{
164 Containers: []v1.Container{
165 {
166 Name: containerName1,
167 Image: imageutils.GetE2EImage(imageutils.Agnhost),
168 Args: []string{"mounttest"},
169 VolumeMounts: []v1.VolumeMount{
170 {
171 Name: volumeName,
172 MountPath: path,
173 },
174 },
175 SecurityContext: &v1.SecurityContext{
176 Privileged: &privileged,
177 },
178 },
179 {
180 Name: containerName2,
181 Image: imageutils.GetE2EImage(imageutils.Agnhost),
182 Args: []string{"mounttest"},
183 VolumeMounts: []v1.VolumeMount{
184 {
185 Name: volumeName,
186 MountPath: path,
187 },
188 },
189 SecurityContext: &v1.SecurityContext{
190 Privileged: &privileged,
191 },
192 },
193 },
194 RestartPolicy: v1.RestartPolicyNever,
195 Volumes: mount(source),
196 },
197 }
198 }
199
View as plain text