Skip to content

Commit d6ee9ca

Browse files
test/e2e_node: add proc mount tests
including one Alpha only test, as the feature is in alpha Signed-off-by: Peter Hunt <[email protected]> Co-authored-by: Sohan Kunkerkar <[email protected]>
1 parent ae1caa4 commit d6ee9ca

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

test/e2e/nodefeature/nodefeature.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ var (
8888
// RecursiveReadOnlyMounts (SIG-node, used for testing recursive read-only mounts <https://kep.k8s.io/3857>)
8989
RecursiveReadOnlyMounts = framework.WithNodeFeature(framework.ValidNodeFeatures.Add("RecursiveReadOnlyMounts"))
9090

91+
// TODO: document the feature (owning SIG, when to use this feature for a test)
92+
ProcMountType = framework.WithNodeFeature(framework.ValidNodeFeatures.Add("ProcMountType"))
93+
9194
// TODO: document the feature (owning SIG, when to use this feature for a test)
9295
ResourceMetrics = framework.WithNodeFeature(framework.ValidNodeFeatures.Add("ResourceMetrics"))
9396

@@ -104,6 +107,8 @@ var (
104107
// TODO: document the feature (owning SIG, when to use this feature for a test)
105108
SystemNodeCriticalPod = framework.WithNodeFeature(framework.ValidNodeFeatures.Add("SystemNodeCriticalPod"))
106109

110+
// TODO: document the feature (owning SIG, when to use this feature for a test)
111+
UserNamespacesSupport = framework.WithNodeFeature(framework.ValidNodeFeatures.Add("UserNamespacesSupport"))
107112
// Please keep the list in alphabetical order.
108113
)
109114

test/e2e_node/proc_mount_test.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
Copyright 2024 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+
"strings"
22+
23+
"github.com/onsi/ginkgo/v2"
24+
"github.com/onsi/gomega"
25+
gomegatypes "github.com/onsi/gomega/types"
26+
v1 "k8s.io/api/core/v1"
27+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
"k8s.io/kubernetes/test/e2e/feature"
29+
"k8s.io/kubernetes/test/e2e/framework"
30+
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
31+
"k8s.io/kubernetes/test/e2e/nodefeature"
32+
testutils "k8s.io/kubernetes/test/utils"
33+
imageutils "k8s.io/kubernetes/test/utils/image"
34+
admissionapi "k8s.io/pod-security-admission/api"
35+
)
36+
37+
var falseVar = false
38+
39+
var _ = SIGDescribe("DefaultProcMount [LinuxOnly]", framework.WithNodeConformance(), func() {
40+
f := framework.NewDefaultFramework("proc-mount-default-test")
41+
f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
42+
43+
ginkgo.It("will mask proc mounts by default", func(ctx context.Context) {
44+
testProcMount(ctx, f, v1.DefaultProcMount, gomega.BeNumerically(">=", 10), gomega.BeNumerically(">=", 7))
45+
})
46+
})
47+
48+
var _ = SIGDescribe("ProcMount [LinuxOnly]", nodefeature.ProcMountType, nodefeature.UserNamespacesSupport, feature.UserNamespacesSupport, func() {
49+
f := framework.NewDefaultFramework("proc-mount-baseline-test")
50+
f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
51+
52+
f.It("will fail to unmask proc mounts if not privileged", func(ctx context.Context) {
53+
pmt := v1.UnmaskedProcMount
54+
podClient := e2epod.NewPodClient(f)
55+
_, err := podClient.PodInterface.Create(ctx, &v1.Pod{
56+
ObjectMeta: metav1.ObjectMeta{Name: "proc-mount-pod"},
57+
Spec: v1.PodSpec{
58+
Containers: []v1.Container{
59+
{
60+
Name: "test-container-1",
61+
Image: imageutils.GetE2EImage(imageutils.BusyBox),
62+
Command: []string{"/bin/sleep"},
63+
Args: []string{"10000"},
64+
SecurityContext: &v1.SecurityContext{
65+
ProcMount: &pmt,
66+
},
67+
},
68+
},
69+
HostUsers: &falseVar,
70+
},
71+
}, metav1.CreateOptions{})
72+
gomega.Expect(err).To(gomega.HaveOccurred())
73+
})
74+
})
75+
76+
var _ = SIGDescribe("ProcMount [LinuxOnly]", nodefeature.ProcMountType, nodefeature.UserNamespacesSupport, feature.UserNamespacesSupport, func() {
77+
f := framework.NewDefaultFramework("proc-mount-privileged-test")
78+
79+
f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
80+
81+
f.It("will unmask proc mounts if requested", func(ctx context.Context) {
82+
testProcMount(ctx, f, v1.UnmaskedProcMount, gomega.Equal(1), gomega.BeZero())
83+
})
84+
})
85+
86+
func testProcMount(ctx context.Context, f *framework.Framework, pmt v1.ProcMountType, expectedLines gomegatypes.GomegaMatcher, expectedReadOnly gomegatypes.GomegaMatcher) {
87+
ginkgo.By("creating a target pod")
88+
podClient := e2epod.NewPodClient(f)
89+
pod := podClient.CreateSync(ctx, &v1.Pod{
90+
ObjectMeta: metav1.ObjectMeta{Name: "proc-mount-pod"},
91+
Spec: v1.PodSpec{
92+
Containers: []v1.Container{
93+
{
94+
Name: "test-container-1",
95+
Image: imageutils.GetE2EImage(imageutils.BusyBox),
96+
Command: []string{"/bin/sleep"},
97+
Args: []string{"10000"},
98+
SecurityContext: &v1.SecurityContext{
99+
ProcMount: &pmt,
100+
},
101+
},
102+
},
103+
HostUsers: &falseVar,
104+
},
105+
})
106+
107+
_, err := testutils.PodRunningReady(pod)
108+
framework.ExpectNoError(err)
109+
110+
output := e2epod.ExecCommandInContainer(f, pod.Name, pod.Spec.Containers[0].Name, "/bin/sh", "-ec", "mount | grep /proc")
111+
ginkgo.By(output)
112+
lines := strings.Split(output, "\n")
113+
gomega.Expect(len(lines)).To(expectedLines)
114+
gomega.Expect(strings.Count(output, "(ro")).To(expectedReadOnly)
115+
}

0 commit comments

Comments
 (0)