Skip to content

Commit 1fdb8e3

Browse files
authored
Merge pull request kubernetes#126991 from carlory/fix-126956
e2e-node: should succeed with multiple pods and same image
2 parents 0c5e832 + c6904b7 commit 1fdb8e3

File tree

1 file changed

+134
-20
lines changed

1 file changed

+134
-20
lines changed

test/e2e_node/image_volume.go

Lines changed: 134 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"k8s.io/kubernetes/pkg/features"
3232
"k8s.io/kubernetes/pkg/kubelet/images"
3333
"k8s.io/kubernetes/test/e2e/framework"
34+
e2enode "k8s.io/kubernetes/test/e2e/framework/node"
3435
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
3536
e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
3637
"k8s.io/kubernetes/test/e2e/nodefeature"
@@ -60,23 +61,14 @@ var _ = SIGDescribe("ImageVolume", nodefeature.ImageVolume, func() {
6061
e2eskipper.SkipUnlessFeatureGateEnabled(features.ImageVolume)
6162
})
6263

63-
createPod := func(ctx context.Context, volumes []v1.Volume, volumeMounts []v1.VolumeMount) {
64-
var selinuxOptions *v1.SELinuxOptions
65-
if selinux.GetEnabled() {
66-
selinuxOptions = &v1.SELinuxOptions{
67-
User: defaultSELinuxUser,
68-
Role: defaultSELinuxRole,
69-
Type: defaultSELinuxType,
70-
Level: defaultSELinuxLevel,
71-
}
72-
ginkgo.By(fmt.Sprintf("Using SELinux on pod: %v", selinuxOptions))
73-
}
64+
createPod := func(ctx context.Context, podName, nodeName string, volumes []v1.Volume, volumeMounts []v1.VolumeMount, selinuxOptions *v1.SELinuxOptions) {
7465
pod := &v1.Pod{
7566
ObjectMeta: metav1.ObjectMeta{
7667
Name: podName,
7768
Namespace: f.Namespace.Name,
7869
},
7970
Spec: v1.PodSpec{
71+
NodeName: nodeName,
8072
RestartPolicy: v1.RestartPolicyAlways,
8173
SecurityContext: &v1.PodSecurityContext{
8274
SELinuxOptions: selinuxOptions,
@@ -93,20 +85,34 @@ var _ = SIGDescribe("ImageVolume", nodefeature.ImageVolume, func() {
9385
},
9486
}
9587

96-
ginkgo.By(fmt.Sprintf("Creating a pod (%v/%v)", f.Namespace.Name, podName))
88+
ginkgo.By(fmt.Sprintf("Creating a pod (%s/%s)", f.Namespace.Name, podName))
9789
e2epod.NewPodClient(f).Create(ctx, pod)
9890

9991
}
10092

10193
f.It("should succeed with pod and pull policy of Always", func(ctx context.Context) {
94+
var selinuxOptions *v1.SELinuxOptions
95+
if selinux.GetEnabled() {
96+
selinuxOptions = &v1.SELinuxOptions{
97+
User: defaultSELinuxUser,
98+
Role: defaultSELinuxRole,
99+
Type: defaultSELinuxType,
100+
Level: defaultSELinuxLevel,
101+
}
102+
ginkgo.By(fmt.Sprintf("Using SELinux on pod: %v", selinuxOptions))
103+
}
104+
102105
createPod(ctx,
106+
podName,
107+
"",
103108
[]v1.Volume{{Name: volumeName, VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: validImageRef, PullPolicy: v1.PullAlways}}}},
104109
[]v1.VolumeMount{{Name: volumeName, MountPath: volumePathPrefix}},
110+
selinuxOptions,
105111
)
106112

107-
ginkgo.By(fmt.Sprintf("Waiting for the pod (%v/%v) to be running", f.Namespace.Name, podName))
113+
ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to be running", f.Namespace.Name, podName))
108114
err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, podName, f.Namespace.Name)
109-
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%v/%v)", f.Namespace.Name, podName)
115+
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName)
110116

111117
ginkgo.By(fmt.Sprintf("Verifying the volume mount contents for path: %s", volumePathPrefix))
112118

@@ -118,7 +124,20 @@ var _ = SIGDescribe("ImageVolume", nodefeature.ImageVolume, func() {
118124
})
119125

120126
f.It("should succeed with pod and multiple volumes", func(ctx context.Context) {
127+
var selinuxOptions *v1.SELinuxOptions
128+
if selinux.GetEnabled() {
129+
selinuxOptions = &v1.SELinuxOptions{
130+
User: defaultSELinuxUser,
131+
Role: defaultSELinuxRole,
132+
Type: defaultSELinuxType,
133+
Level: defaultSELinuxLevel,
134+
}
135+
ginkgo.By(fmt.Sprintf("Using SELinux on pod: %v", selinuxOptions))
136+
}
137+
121138
createPod(ctx,
139+
podName,
140+
"",
122141
[]v1.Volume{
123142
{Name: volumeName + "-0", VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: validImageRef}}},
124143
{Name: volumeName + "-1", VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: validImageRef}}},
@@ -127,11 +146,12 @@ var _ = SIGDescribe("ImageVolume", nodefeature.ImageVolume, func() {
127146
{Name: volumeName + "-0", MountPath: volumePathPrefix + "-0"},
128147
{Name: volumeName + "-1", MountPath: volumePathPrefix + "-1"},
129148
},
149+
selinuxOptions,
130150
)
131151

132-
ginkgo.By(fmt.Sprintf("Waiting for the pod (%v/%v) to be running", f.Namespace.Name, podName))
152+
ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to be running", f.Namespace.Name, podName))
133153
err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, podName, f.Namespace.Name)
134-
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%v/%v)", f.Namespace.Name, podName)
154+
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName)
135155

136156
for i := range 2 {
137157
volumePath := fmt.Sprintf("%s-%d", volumePathPrefix, i)
@@ -146,29 +166,123 @@ var _ = SIGDescribe("ImageVolume", nodefeature.ImageVolume, func() {
146166
})
147167

148168
f.It("should fail if image volume is not existing", func(ctx context.Context) {
169+
var selinuxOptions *v1.SELinuxOptions
170+
if selinux.GetEnabled() {
171+
selinuxOptions = &v1.SELinuxOptions{
172+
User: defaultSELinuxUser,
173+
Role: defaultSELinuxRole,
174+
Type: defaultSELinuxType,
175+
Level: defaultSELinuxLevel,
176+
}
177+
ginkgo.By(fmt.Sprintf("Using SELinux on pod: %v", selinuxOptions))
178+
}
179+
149180
createPod(ctx,
181+
podName,
182+
"",
150183
[]v1.Volume{{Name: volumeName, VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: invalidImageRef}}}},
151184
[]v1.VolumeMount{{Name: volumeName, MountPath: volumePathPrefix}},
185+
selinuxOptions,
152186
)
153187

154-
ginkgo.By(fmt.Sprintf("Waiting for the pod (%v/%v) to fail", f.Namespace.Name, podName))
188+
ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to fail", f.Namespace.Name, podName))
155189
err := e2epod.WaitForPodContainerToFail(ctx, f.ClientSet, f.Namespace.Name, podName, 0, images.ErrImagePullBackOff.Error(), time.Minute)
156-
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%v/%v)", f.Namespace.Name, podName)
190+
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName)
157191
})
158192

159193
f.It("should succeed if image volume is not existing but unused", func(ctx context.Context) {
194+
var selinuxOptions *v1.SELinuxOptions
195+
if selinux.GetEnabled() {
196+
selinuxOptions = &v1.SELinuxOptions{
197+
User: defaultSELinuxUser,
198+
Role: defaultSELinuxRole,
199+
Type: defaultSELinuxType,
200+
Level: defaultSELinuxLevel,
201+
}
202+
ginkgo.By(fmt.Sprintf("Using SELinux on pod: %v", selinuxOptions))
203+
}
204+
160205
createPod(ctx,
206+
podName,
207+
"",
161208
[]v1.Volume{{Name: volumeName, VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: invalidImageRef}}}},
162209
nil,
210+
selinuxOptions,
163211
)
164212

165-
ginkgo.By(fmt.Sprintf("Waiting for the pod (%v/%v) to be running", f.Namespace.Name, podName))
213+
ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to be running", f.Namespace.Name, podName))
166214
err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, podName, f.Namespace.Name)
167-
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%v/%v)", f.Namespace.Name, podName)
215+
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName)
168216

169217
ginkgo.By(fmt.Sprintf("Verifying the volume mount is not used for path: %s", volumePathPrefix))
170218

171219
output := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/ls", filepath.Dir(volumePathPrefix))
172220
gomega.Expect(output).NotTo(gomega.ContainSubstring(strings.TrimPrefix(volumePathPrefix, "/")))
173221
})
222+
223+
f.It("should succeed with multiple pods and same image on the same node", func(ctx context.Context) {
224+
node, err := e2enode.GetRandomReadySchedulableNode(ctx, f.ClientSet)
225+
framework.ExpectNoError(err, "Failed to get a ready schedulable node")
226+
227+
baseName := "test-pod"
228+
anotherSELinuxLevel := "s0:c100,c200"
229+
230+
for i := range 2 {
231+
podName := fmt.Sprintf("%s-%d", baseName, i)
232+
233+
var selinuxOptions *v1.SELinuxOptions
234+
if selinux.GetEnabled() {
235+
if i == 0 {
236+
selinuxOptions = &v1.SELinuxOptions{
237+
User: defaultSELinuxUser,
238+
Role: defaultSELinuxRole,
239+
Type: defaultSELinuxType,
240+
Level: defaultSELinuxLevel,
241+
}
242+
} else {
243+
selinuxOptions = &v1.SELinuxOptions{
244+
User: defaultSELinuxUser,
245+
Role: defaultSELinuxRole,
246+
Type: defaultSELinuxType,
247+
Level: anotherSELinuxLevel,
248+
}
249+
}
250+
251+
ginkgo.By(fmt.Sprintf("Using SELinux on pod %q: %v", podName, selinuxOptions))
252+
}
253+
254+
createPod(ctx,
255+
podName,
256+
node.Name,
257+
[]v1.Volume{{Name: volumeName, VolumeSource: v1.VolumeSource{Image: &v1.ImageVolumeSource{Reference: validImageRef}}}},
258+
[]v1.VolumeMount{{Name: volumeName, MountPath: volumePathPrefix}},
259+
selinuxOptions,
260+
)
261+
262+
ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to be running", f.Namespace.Name, podName))
263+
err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, podName, f.Namespace.Name)
264+
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName)
265+
266+
ginkgo.By(fmt.Sprintf("Verifying the volume mount contents for path: %s", volumePathPrefix))
267+
268+
firstFileContents := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/cat", filepath.Join(volumePathPrefix, "dir", "file"))
269+
gomega.Expect(firstFileContents).To(gomega.Equal("1"))
270+
271+
secondFileContents := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/cat", filepath.Join(volumePathPrefix, "file"))
272+
gomega.Expect(secondFileContents).To(gomega.Equal("2"))
273+
}
274+
275+
podName := baseName + "-0"
276+
ginkgo.By(fmt.Sprintf("Rechecking the pod (%s/%s) after another pod is running as expected", f.Namespace.Name, podName))
277+
err = e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, podName, f.Namespace.Name)
278+
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%s/%s)", f.Namespace.Name, podName)
279+
280+
ginkgo.By(fmt.Sprintf("Verifying the volume mount contents for path: %s", volumePathPrefix))
281+
282+
firstFileContents := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/cat", filepath.Join(volumePathPrefix, "dir", "file"))
283+
gomega.Expect(firstFileContents).To(gomega.Equal("1"))
284+
285+
secondFileContents := e2epod.ExecCommandInContainer(f, podName, containerName, "/bin/cat", filepath.Join(volumePathPrefix, "file"))
286+
gomega.Expect(secondFileContents).To(gomega.Equal("2"))
287+
})
174288
})

0 commit comments

Comments
 (0)