Skip to content

Commit 02ad18b

Browse files
committed
userns: Query runtime once
Sascha suggested to run this only once. Let's cache the answer from the runtime and move the tests that need idmap mounts on the host to `When("Host idmap mount support is needed"`. While we split the tests in that way, let's just query idmap mount support for the tests that need it, using the cache. Signed-off-by: Rodrigo Campos <rodrigoca@microsoft.com>
1 parent 934f1cc commit 02ad18b

File tree

1 file changed

+98
-85
lines changed

1 file changed

+98
-85
lines changed

pkg/validate/security_context_linux.go

+98-85
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"os/exec"
2626
"path/filepath"
2727
"strings"
28+
"sync"
2829
"syscall"
2930
"time"
3031

@@ -850,8 +851,11 @@ var _ = framework.KubeDescribe("Security Context", func() {
850851

851852
Context("UserNamespaces", func() {
852853
var (
853-
podName string
854-
defaultMapping = []*runtimeapi.IDMapping{{
854+
podName string
855+
statusOnce sync.Once
856+
statusResp runtimeapi.StatusResponse
857+
supportsUserNamespaces bool
858+
defaultMapping = []*runtimeapi.IDMapping{{
855859
ContainerId: 0,
856860
HostId: 1000,
857861
Length: 100000,
@@ -863,108 +867,117 @@ var _ = framework.KubeDescribe("Security Context", func() {
863867

864868
// Find a working runtime handler if none provided
865869
By("searching for runtime handler which supports user namespaces")
866-
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
867-
defer cancel()
868-
resp, err := rc.Status(ctx, true) // Set verbose to true so the info field is populated.
869-
framework.ExpectNoError(err, "failed to get runtime config: %v", err)
870-
871-
supportsUserNamespaces := false
872-
for _, rh := range resp.GetRuntimeHandlers() {
873-
if rh.GetName() == framework.TestContext.RuntimeHandler {
874-
if rh.GetFeatures().GetUserNamespaces() {
875-
supportsUserNamespaces = true
876-
break
870+
statusOnce.Do(func() {
871+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
872+
defer cancel()
873+
// Set verbose to true, other BeforeEachs calls need info populated.
874+
statusResp, err := rc.Status(ctx, true)
875+
framework.ExpectNoError(err, "failed to get runtime config: %v", err)
876+
for _, rh := range statusResp.GetRuntimeHandlers() {
877+
if rh.GetName() == framework.TestContext.RuntimeHandler {
878+
if rh.GetFeatures().GetUserNamespaces() {
879+
supportsUserNamespaces = true
880+
break
881+
}
877882
}
878883
}
879-
}
880-
884+
supportsUserNamespaces = false
885+
})
881886
if !supportsUserNamespaces {
882887
Skip("no runtime handler found which supports user namespaces")
883888
}
884-
885-
pathIDMap := rootfsPath(resp.GetInfo())
886-
if err := supportsIDMap(pathIDMap); err != nil {
887-
Skip("ID mapping is not supported" + " with path: " + pathIDMap + ": " + err.Error())
888-
}
889889
})
890890

891-
It("runtime should support NamespaceMode_POD", func() {
892-
namespaceOption := &runtimeapi.NamespaceOption{
893-
UsernsOptions: &runtimeapi.UserNamespace{
894-
Mode: runtimeapi.NamespaceMode_POD,
895-
Uids: defaultMapping,
896-
Gids: defaultMapping,
897-
},
898-
}
891+
When("Host idmap mount support is needed", func() {
892+
BeforeEach(func() {
893+
// Find a working runtime handler if none provided
894+
By("check for host idmap mount support")
895+
pathIDMap := rootfsPath(statusResp.GetInfo())
896+
if err := supportsIDMap(pathIDMap); err != nil {
897+
Skip("ID mapping is not supported" + " with path: " + pathIDMap + ": " + err.Error())
898+
}
899+
})
900+
901+
It("runtime should support NamespaceMode_POD", func() {
902+
namespaceOption := &runtimeapi.NamespaceOption{
903+
UsernsOptions: &runtimeapi.UserNamespace{
904+
Mode: runtimeapi.NamespaceMode_POD,
905+
Uids: defaultMapping,
906+
Gids: defaultMapping,
907+
},
908+
}
899909

900-
hostLogPath, podLogPath := createLogTempDir(podName)
901-
defer os.RemoveAll(hostLogPath)
902-
podID, podConfig = createNamespacePodSandbox(rc, namespaceOption, podName, podLogPath)
903-
containerName := runUserNamespaceContainer(rc, ic, podID, podConfig)
910+
hostLogPath, podLogPath := createLogTempDir(podName)
911+
defer os.RemoveAll(hostLogPath)
912+
podID, podConfig = createNamespacePodSandbox(rc, namespaceOption, podName, podLogPath)
913+
containerName := runUserNamespaceContainer(rc, ic, podID, podConfig)
904914

905-
matchContainerOutputRe(podConfig, containerName, `\s+0\s+1000\s+100000\n`)
915+
matchContainerOutputRe(podConfig, containerName, `\s+0\s+1000\s+100000\n`)
916+
})
906917
})
907918

908-
It("runtime should support NamespaceMode_NODE", func() {
909-
namespaceOption := &runtimeapi.NamespaceOption{
910-
UsernsOptions: &runtimeapi.UserNamespace{
911-
Mode: runtimeapi.NamespaceMode_NODE,
912-
},
913-
}
914-
915-
hostLogPath, podLogPath := createLogTempDir(podName)
916-
defer os.RemoveAll(hostLogPath)
917-
podID, podConfig = createNamespacePodSandbox(rc, namespaceOption, podName, podLogPath)
918-
containerName := runUserNamespaceContainer(rc, ic, podID, podConfig)
919-
920-
// 4294967295 means that the entire range is available
921-
matchContainerOutputRe(podConfig, containerName, `\s+0\s+0\s+4294967295\n`)
922-
})
919+
When("Host idmap mount support is not needed", func() {
920+
It("runtime should support NamespaceMode_NODE", func() {
921+
namespaceOption := &runtimeapi.NamespaceOption{
922+
UsernsOptions: &runtimeapi.UserNamespace{
923+
Mode: runtimeapi.NamespaceMode_NODE,
924+
},
925+
}
923926

924-
It("runtime should fail if more than one mapping provided", func() {
925-
wrongMapping := []*runtimeapi.IDMapping{{
926-
ContainerId: 0,
927-
HostId: 1000,
928-
Length: 100000,
929-
}, {
930-
ContainerId: 0,
931-
HostId: 2000,
932-
Length: 100000,
933-
}}
934-
usernsOptions := &runtimeapi.UserNamespace{
935-
Mode: runtimeapi.NamespaceMode_POD,
936-
Uids: wrongMapping,
937-
Gids: wrongMapping,
938-
}
927+
hostLogPath, podLogPath := createLogTempDir(podName)
928+
defer os.RemoveAll(hostLogPath)
929+
podID, podConfig = createNamespacePodSandbox(rc, namespaceOption, podName, podLogPath)
930+
containerName := runUserNamespaceContainer(rc, ic, podID, podConfig)
931+
932+
// 4294967295 means that the entire range is available
933+
matchContainerOutputRe(podConfig, containerName, `\s+0\s+0\s+4294967295\n`)
934+
})
935+
936+
It("runtime should fail if more than one mapping provided", func() {
937+
wrongMapping := []*runtimeapi.IDMapping{{
938+
ContainerId: 0,
939+
HostId: 1000,
940+
Length: 100000,
941+
}, {
942+
ContainerId: 0,
943+
HostId: 2000,
944+
Length: 100000,
945+
}}
946+
usernsOptions := &runtimeapi.UserNamespace{
947+
Mode: runtimeapi.NamespaceMode_POD,
948+
Uids: wrongMapping,
949+
Gids: wrongMapping,
950+
}
939951

940-
runUserNamespacePodWithError(rc, podName, usernsOptions)
941-
})
952+
runUserNamespacePodWithError(rc, podName, usernsOptions)
953+
})
942954

943-
It("runtime should fail if container ID 0 is not mapped", func() {
944-
mapping := []*runtimeapi.IDMapping{{
945-
ContainerId: 1,
946-
HostId: 1000,
947-
Length: 100000,
948-
}}
949-
usernsOptions := &runtimeapi.UserNamespace{
950-
Mode: runtimeapi.NamespaceMode_POD,
951-
Uids: mapping,
952-
Gids: mapping,
953-
}
955+
It("runtime should fail if container ID 0 is not mapped", func() {
956+
mapping := []*runtimeapi.IDMapping{{
957+
ContainerId: 1,
958+
HostId: 1000,
959+
Length: 100000,
960+
}}
961+
usernsOptions := &runtimeapi.UserNamespace{
962+
Mode: runtimeapi.NamespaceMode_POD,
963+
Uids: mapping,
964+
Gids: mapping,
965+
}
954966

955-
runUserNamespacePodWithError(rc, podName, usernsOptions)
956-
})
967+
runUserNamespacePodWithError(rc, podName, usernsOptions)
968+
})
957969

958-
It("runtime should fail with NamespaceMode_CONTAINER", func() {
959-
usernsOptions := &runtimeapi.UserNamespace{Mode: runtimeapi.NamespaceMode_CONTAINER}
970+
It("runtime should fail with NamespaceMode_CONTAINER", func() {
971+
usernsOptions := &runtimeapi.UserNamespace{Mode: runtimeapi.NamespaceMode_CONTAINER}
960972

961-
runUserNamespacePodWithError(rc, podName, usernsOptions)
962-
})
973+
runUserNamespacePodWithError(rc, podName, usernsOptions)
974+
})
963975

964-
It("runtime should fail with NamespaceMode_TARGET", func() {
965-
usernsOptions := &runtimeapi.UserNamespace{Mode: runtimeapi.NamespaceMode_TARGET}
976+
It("runtime should fail with NamespaceMode_TARGET", func() {
977+
usernsOptions := &runtimeapi.UserNamespace{Mode: runtimeapi.NamespaceMode_TARGET}
966978

967-
runUserNamespacePodWithError(rc, podName, usernsOptions)
979+
runUserNamespacePodWithError(rc, podName, usernsOptions)
980+
})
968981
})
969982
})
970983
})

0 commit comments

Comments
 (0)