mirror of https://github.com/k3s-io/k3s
Add subPath e2e: test permissions and when subPath pre-exists
parent
e11963194e
commit
036b64d54e
|
@ -33,6 +33,7 @@ import (
|
||||||
const (
|
const (
|
||||||
testImageRootUid = "gcr.io/google_containers/mounttest:0.8"
|
testImageRootUid = "gcr.io/google_containers/mounttest:0.8"
|
||||||
testImageNonRootUid = "gcr.io/google_containers/mounttest-user:0.5"
|
testImageNonRootUid = "gcr.io/google_containers/mounttest-user:0.5"
|
||||||
|
volumePath = "/test-volume"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = framework.KubeDescribe("EmptyDir volumes", func() {
|
var _ = framework.KubeDescribe("EmptyDir volumes", func() {
|
||||||
|
@ -48,6 +49,10 @@ var _ = framework.KubeDescribe("EmptyDir volumes", func() {
|
||||||
doTestSetgidFSGroup(f, testImageNonRootUid, v1.StorageMediumMemory)
|
doTestSetgidFSGroup(f, testImageNonRootUid, v1.StorageMediumMemory)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("nonexistent volume subPath should have the correct mode and owner using FSGroup [Volume]", func() {
|
||||||
|
doTestSubPathFSGroup(f, testImageNonRootUid, v1.StorageMediumMemory)
|
||||||
|
})
|
||||||
|
|
||||||
It("files with FSGroup ownership should support (root,0644,tmpfs) [Volume]", func() {
|
It("files with FSGroup ownership should support (root,0644,tmpfs) [Volume]", func() {
|
||||||
doTest0644FSGroup(f, testImageRootUid, v1.StorageMediumMemory)
|
doTest0644FSGroup(f, testImageRootUid, v1.StorageMediumMemory)
|
||||||
})
|
})
|
||||||
|
@ -125,7 +130,6 @@ const (
|
||||||
|
|
||||||
func doTestSetgidFSGroup(f *framework.Framework, image string, medium v1.StorageMedium) {
|
func doTestSetgidFSGroup(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
var (
|
var (
|
||||||
volumePath = "/test-volume"
|
|
||||||
filePath = path.Join(volumePath, "test-file")
|
filePath = path.Join(volumePath, "test-file")
|
||||||
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
||||||
pod = testPodWithVolume(testImageRootUid, volumePath, source)
|
pod = testPodWithVolume(testImageRootUid, volumePath, source)
|
||||||
|
@ -153,9 +157,38 @@ func doTestSetgidFSGroup(f *framework.Framework, image string, medium v1.Storage
|
||||||
f.TestContainerOutput(msg, pod, 0, out)
|
f.TestContainerOutput(msg, pod, 0, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func doTestSubPathFSGroup(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
|
var (
|
||||||
|
subPath = "test-sub"
|
||||||
|
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
||||||
|
pod = testPodWithVolume(image, volumePath, source)
|
||||||
|
)
|
||||||
|
|
||||||
|
pod.Spec.Containers[0].Args = []string{
|
||||||
|
fmt.Sprintf("--fs_type=%v", volumePath),
|
||||||
|
fmt.Sprintf("--file_perm=%v", volumePath),
|
||||||
|
fmt.Sprintf("--file_owner=%v", volumePath),
|
||||||
|
}
|
||||||
|
|
||||||
|
pod.Spec.Containers[0].VolumeMounts[0].SubPath = subPath
|
||||||
|
|
||||||
|
fsGroup := types.UnixGroupID(123)
|
||||||
|
pod.Spec.SecurityContext.FSGroup = &fsGroup
|
||||||
|
|
||||||
|
msg := fmt.Sprintf("emptydir subpath on %v", formatMedium(medium))
|
||||||
|
out := []string{
|
||||||
|
"perms of file \"/test-volume\": -rwxrwxrwx",
|
||||||
|
"owner UID of \"/test-volume\": 0",
|
||||||
|
"owner GID of \"/test-volume\": 123",
|
||||||
|
}
|
||||||
|
if medium == v1.StorageMediumMemory {
|
||||||
|
out = append(out, "mount type of \"/test-volume\": tmpfs")
|
||||||
|
}
|
||||||
|
f.TestContainerOutput(msg, pod, 0, out)
|
||||||
|
}
|
||||||
|
|
||||||
func doTestVolumeModeFSGroup(f *framework.Framework, image string, medium v1.StorageMedium) {
|
func doTestVolumeModeFSGroup(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
var (
|
var (
|
||||||
volumePath = "/test-volume"
|
|
||||||
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
||||||
pod = testPodWithVolume(testImageRootUid, volumePath, source)
|
pod = testPodWithVolume(testImageRootUid, volumePath, source)
|
||||||
)
|
)
|
||||||
|
@ -180,7 +213,6 @@ func doTestVolumeModeFSGroup(f *framework.Framework, image string, medium v1.Sto
|
||||||
|
|
||||||
func doTest0644FSGroup(f *framework.Framework, image string, medium v1.StorageMedium) {
|
func doTest0644FSGroup(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
var (
|
var (
|
||||||
volumePath = "/test-volume"
|
|
||||||
filePath = path.Join(volumePath, "test-file")
|
filePath = path.Join(volumePath, "test-file")
|
||||||
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
||||||
pod = testPodWithVolume(image, volumePath, source)
|
pod = testPodWithVolume(image, volumePath, source)
|
||||||
|
@ -208,7 +240,6 @@ func doTest0644FSGroup(f *framework.Framework, image string, medium v1.StorageMe
|
||||||
|
|
||||||
func doTestVolumeMode(f *framework.Framework, image string, medium v1.StorageMedium) {
|
func doTestVolumeMode(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
var (
|
var (
|
||||||
volumePath = "/test-volume"
|
|
||||||
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
||||||
pod = testPodWithVolume(testImageRootUid, volumePath, source)
|
pod = testPodWithVolume(testImageRootUid, volumePath, source)
|
||||||
)
|
)
|
||||||
|
@ -230,7 +261,6 @@ func doTestVolumeMode(f *framework.Framework, image string, medium v1.StorageMed
|
||||||
|
|
||||||
func doTest0644(f *framework.Framework, image string, medium v1.StorageMedium) {
|
func doTest0644(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
var (
|
var (
|
||||||
volumePath = "/test-volume"
|
|
||||||
filePath = path.Join(volumePath, "test-file")
|
filePath = path.Join(volumePath, "test-file")
|
||||||
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
||||||
pod = testPodWithVolume(image, volumePath, source)
|
pod = testPodWithVolume(image, volumePath, source)
|
||||||
|
@ -255,7 +285,6 @@ func doTest0644(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
|
|
||||||
func doTest0666(f *framework.Framework, image string, medium v1.StorageMedium) {
|
func doTest0666(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
var (
|
var (
|
||||||
volumePath = "/test-volume"
|
|
||||||
filePath = path.Join(volumePath, "test-file")
|
filePath = path.Join(volumePath, "test-file")
|
||||||
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
||||||
pod = testPodWithVolume(image, volumePath, source)
|
pod = testPodWithVolume(image, volumePath, source)
|
||||||
|
@ -280,7 +309,6 @@ func doTest0666(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
|
|
||||||
func doTest0777(f *framework.Framework, image string, medium v1.StorageMedium) {
|
func doTest0777(f *framework.Framework, image string, medium v1.StorageMedium) {
|
||||||
var (
|
var (
|
||||||
volumePath = "/test-volume"
|
|
||||||
filePath = path.Join(volumePath, "test-file")
|
filePath = path.Join(volumePath, "test-file")
|
||||||
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
source = &v1.EmptyDirVolumeSource{Medium: medium}
|
||||||
pod = testPodWithVolume(image, volumePath, source)
|
pod = testPodWithVolume(image, volumePath, source)
|
||||||
|
|
|
@ -35,12 +35,12 @@ var _ = framework.KubeDescribe("HostPath", func() {
|
||||||
f := framework.NewDefaultFramework("hostpath")
|
f := framework.NewDefaultFramework("hostpath")
|
||||||
|
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
|
// TODO permission denied cleanup failures
|
||||||
//cleanup before running the test.
|
//cleanup before running the test.
|
||||||
_ = os.Remove("/tmp/test-file")
|
_ = os.Remove("/tmp/test-file")
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should give a volume the correct mode [Conformance] [Volume]", func() {
|
It("should give a volume the correct mode [Conformance] [Volume]", func() {
|
||||||
volumePath := "/test-volume"
|
|
||||||
source := &v1.HostPathVolumeSource{
|
source := &v1.HostPathVolumeSource{
|
||||||
Path: "/tmp",
|
Path: "/tmp",
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ var _ = framework.KubeDescribe("HostPath", func() {
|
||||||
|
|
||||||
// This test requires mounting a folder into a container with write privileges.
|
// This test requires mounting a folder into a container with write privileges.
|
||||||
It("should support r/w [Volume]", func() {
|
It("should support r/w [Volume]", func() {
|
||||||
volumePath := "/test-volume"
|
|
||||||
filePath := path.Join(volumePath, "test-file")
|
filePath := path.Join(volumePath, "test-file")
|
||||||
retryDuration := 180
|
retryDuration := 180
|
||||||
source := &v1.HostPathVolumeSource{
|
source := &v1.HostPathVolumeSource{
|
||||||
|
@ -82,7 +81,6 @@ var _ = framework.KubeDescribe("HostPath", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should support subPath [Volume]", func() {
|
It("should support subPath [Volume]", func() {
|
||||||
volumePath := "/test-volume"
|
|
||||||
subPath := "sub-path"
|
subPath := "sub-path"
|
||||||
fileName := "test-file"
|
fileName := "test-file"
|
||||||
retryDuration := 180
|
retryDuration := 180
|
||||||
|
@ -94,6 +92,7 @@ var _ = framework.KubeDescribe("HostPath", func() {
|
||||||
Path: "/tmp",
|
Path: "/tmp",
|
||||||
}
|
}
|
||||||
pod := testPodWithHostVol(volumePath, source)
|
pod := testPodWithHostVol(volumePath, source)
|
||||||
|
|
||||||
// Write the file in the subPath from container 0
|
// Write the file in the subPath from container 0
|
||||||
container := &pod.Spec.Containers[0]
|
container := &pod.Spec.Containers[0]
|
||||||
container.VolumeMounts[0].SubPath = subPath
|
container.VolumeMounts[0].SubPath = subPath
|
||||||
|
@ -101,6 +100,92 @@ var _ = framework.KubeDescribe("HostPath", func() {
|
||||||
fmt.Sprintf("--new_file_0644=%v", filePathInWriter),
|
fmt.Sprintf("--new_file_0644=%v", filePathInWriter),
|
||||||
fmt.Sprintf("--file_mode=%v", filePathInWriter),
|
fmt.Sprintf("--file_mode=%v", filePathInWriter),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read it from outside the subPath from container 1
|
||||||
|
pod.Spec.Containers[1].Args = []string{
|
||||||
|
fmt.Sprintf("--file_content_in_loop=%v", filePathInReader),
|
||||||
|
fmt.Sprintf("--retry_time=%d", retryDuration),
|
||||||
|
}
|
||||||
|
|
||||||
|
f.TestContainerOutput("hostPath subPath", pod, 1, []string{
|
||||||
|
"content of file \"" + filePathInReader + "\": mount-tester new file",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should support existing directory subPath [Volume]", func() {
|
||||||
|
framework.SkipUnlessSSHKeyPresent()
|
||||||
|
|
||||||
|
subPath := "sub-path"
|
||||||
|
fileName := "test-file"
|
||||||
|
retryDuration := 180
|
||||||
|
|
||||||
|
filePathInWriter := path.Join(volumePath, fileName)
|
||||||
|
filePathInReader := path.Join(volumePath, subPath, fileName)
|
||||||
|
|
||||||
|
source := &v1.HostPathVolumeSource{
|
||||||
|
Path: "/tmp",
|
||||||
|
}
|
||||||
|
pod := testPodWithHostVol(volumePath, source)
|
||||||
|
nodeList := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
||||||
|
pod.Spec.NodeName = nodeList.Items[0].Name
|
||||||
|
|
||||||
|
// Create the subPath directory on the host
|
||||||
|
existing := path.Join(source.Path, subPath)
|
||||||
|
result, err := framework.SSH(fmt.Sprintf("mkdir -p %s", existing), framework.GetNodeExternalIP(&nodeList.Items[0]), framework.TestContext.Provider)
|
||||||
|
framework.LogSSHResult(result)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
if result.Code != 0 {
|
||||||
|
framework.Failf("mkdir returned non-zero")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the file in the subPath from container 0
|
||||||
|
container := &pod.Spec.Containers[0]
|
||||||
|
container.VolumeMounts[0].SubPath = subPath
|
||||||
|
container.Args = []string{
|
||||||
|
fmt.Sprintf("--new_file_0644=%v", filePathInWriter),
|
||||||
|
fmt.Sprintf("--file_mode=%v", filePathInWriter),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read it from outside the subPath from container 1
|
||||||
|
pod.Spec.Containers[1].Args = []string{
|
||||||
|
fmt.Sprintf("--file_content_in_loop=%v", filePathInReader),
|
||||||
|
fmt.Sprintf("--retry_time=%d", retryDuration),
|
||||||
|
}
|
||||||
|
|
||||||
|
f.TestContainerOutput("hostPath subPath", pod, 1, []string{
|
||||||
|
"content of file \"" + filePathInReader + "\": mount-tester new file",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO consolidate common code of this test and above
|
||||||
|
It("should support existing single file subPath [Volume]", func() {
|
||||||
|
framework.SkipUnlessSSHKeyPresent()
|
||||||
|
|
||||||
|
subPath := "sub-path-test-file"
|
||||||
|
retryDuration := 180
|
||||||
|
|
||||||
|
filePathInReader := path.Join(volumePath, subPath)
|
||||||
|
|
||||||
|
source := &v1.HostPathVolumeSource{
|
||||||
|
Path: "/tmp",
|
||||||
|
}
|
||||||
|
pod := testPodWithHostVol(volumePath, source)
|
||||||
|
nodeList := framework.GetReadySchedulableNodesOrDie(f.ClientSet)
|
||||||
|
pod.Spec.NodeName = nodeList.Items[0].Name
|
||||||
|
|
||||||
|
// Create the subPath file on the host
|
||||||
|
existing := path.Join(source.Path, subPath)
|
||||||
|
result, err := framework.SSH(fmt.Sprintf("echo \"mount-tester new file\" > %s", existing), framework.GetNodeExternalIP(&nodeList.Items[0]), framework.TestContext.Provider)
|
||||||
|
framework.LogSSHResult(result)
|
||||||
|
framework.ExpectNoError(err)
|
||||||
|
if result.Code != 0 {
|
||||||
|
framework.Failf("echo returned non-zero")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mount the file to the subPath in container 0
|
||||||
|
container := &pod.Spec.Containers[0]
|
||||||
|
container.VolumeMounts[0].SubPath = subPath
|
||||||
|
|
||||||
// Read it from outside the subPath from container 1
|
// Read it from outside the subPath from container 1
|
||||||
pod.Spec.Containers[1].Args = []string{
|
pod.Spec.Containers[1].Args = []string{
|
||||||
fmt.Sprintf("--file_content_in_loop=%v", filePathInReader),
|
fmt.Sprintf("--file_content_in_loop=%v", filePathInReader),
|
||||||
|
|
Loading…
Reference in New Issue