mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 16:29:21 +00:00
fix permissions when using fsGroup
This commit is contained in:
parent
81b3644017
commit
51ae5a34b9
@ -51,6 +51,17 @@ func SetVolumeOwnership(mounter Mounter, fsGroup *int64) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// chown and chmod pass through to the underlying file for symlinks.
|
||||||
|
// Symlinks have a mode of 777 but this really doesn't mean anything.
|
||||||
|
// The permissions of the underlying file are what matter.
|
||||||
|
// However, if one reads the mode of a symlink then chmods the symlink
|
||||||
|
// with that mode, it changes the mode of the underlying file, overridden
|
||||||
|
// the defaultMode and permissions initialized by the volume plugin, which
|
||||||
|
// is not what we want; thus, we skip chown/chmod for symlinks.
|
||||||
|
if info.Mode()&os.ModeSymlink != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
stat, ok := info.Sys().(*syscall.Stat_t)
|
stat, ok := info.Sys().(*syscall.Stat_t)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
|
@ -41,6 +41,11 @@ var _ = framework.KubeDescribe("ConfigMap", func() {
|
|||||||
doConfigMapE2EWithoutMappings(f, 0, 0, &defaultMode)
|
doConfigMapE2EWithoutMappings(f, 0, 0, &defaultMode)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [Feature:FSGroup]", func() {
|
||||||
|
defaultMode := int32(0440) /* setting fsGroup sets mode to at least 440 */
|
||||||
|
doConfigMapE2EWithoutMappings(f, 1000, 1001, &defaultMode)
|
||||||
|
})
|
||||||
|
|
||||||
It("should be consumable from pods in volume as non-root [Conformance]", func() {
|
It("should be consumable from pods in volume as non-root [Conformance]", func() {
|
||||||
doConfigMapE2EWithoutMappings(f, 1000, 0, nil)
|
doConfigMapE2EWithoutMappings(f, 1000, 0, nil)
|
||||||
})
|
})
|
||||||
@ -343,14 +348,10 @@ func doConfigMapE2EWithoutMappings(f *framework.Framework, uid, fsGroup int64, d
|
|||||||
defaultMode = &mode
|
defaultMode = &mode
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just check file mode if fsGroup is not set. If fsGroup is set, the
|
modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
|
||||||
// final mode is adjusted and we are not testing that case.
|
|
||||||
output := []string{
|
output := []string{
|
||||||
"content of file \"/etc/configmap-volume/data-1\": value-1",
|
"content of file \"/etc/configmap-volume/data-1\": value-1",
|
||||||
}
|
"mode of file \"/etc/configmap-volume/data-1\": " + modeString,
|
||||||
if fsGroup == 0 {
|
|
||||||
modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
|
|
||||||
output = append(output, "mode of file \"/etc/configmap-volume/data-1\": "+modeString)
|
|
||||||
}
|
}
|
||||||
f.TestContainerOutput("consume configMaps", pod, 0, output)
|
f.TestContainerOutput("consume configMaps", pod, 0, output)
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,21 @@ var _ = framework.KubeDescribe("Downward API volume", func() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("should provide podname as non-root with fsgroup and defaultMode [Feature:FSGroup]", func() {
|
||||||
|
podName := "metadata-volume-" + string(uuid.NewUUID())
|
||||||
|
uid := int64(1001)
|
||||||
|
gid := int64(1234)
|
||||||
|
mode := int32(0440) /* setting fsGroup sets mode to at least 440 */
|
||||||
|
pod := downwardAPIVolumePodForModeTest(podName, "/etc/podname", &mode, nil)
|
||||||
|
pod.Spec.SecurityContext = &v1.PodSecurityContext{
|
||||||
|
RunAsUser: &uid,
|
||||||
|
FSGroup: &gid,
|
||||||
|
}
|
||||||
|
f.TestContainerOutput("downward API volume plugin", pod, 0, []string{
|
||||||
|
"mode of file \"/etc/podname\": -r--r-----",
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
It("should update labels on modification [Conformance]", func() {
|
It("should update labels on modification [Conformance]", func() {
|
||||||
labels := map[string]string{}
|
labels := map[string]string{}
|
||||||
labels["key1"] = "value1"
|
labels["key1"] = "value1"
|
||||||
|
@ -31,12 +31,19 @@ var _ = framework.KubeDescribe("Secrets", func() {
|
|||||||
f := framework.NewDefaultFramework("secrets")
|
f := framework.NewDefaultFramework("secrets")
|
||||||
|
|
||||||
It("should be consumable from pods in volume [Conformance]", func() {
|
It("should be consumable from pods in volume [Conformance]", func() {
|
||||||
doSecretE2EWithoutMapping(f, nil /* default mode */, "secret-test-"+string(uuid.NewUUID()))
|
doSecretE2EWithoutMapping(f, nil /* default mode */, "secret-test-"+string(uuid.NewUUID()), nil, nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be consumable from pods in volume with defaultMode set [Conformance]", func() {
|
It("should be consumable from pods in volume with defaultMode set [Conformance]", func() {
|
||||||
defaultMode := int32(0400)
|
defaultMode := int32(0400)
|
||||||
doSecretE2EWithoutMapping(f, &defaultMode, "secret-test-"+string(uuid.NewUUID()))
|
doSecretE2EWithoutMapping(f, &defaultMode, "secret-test-"+string(uuid.NewUUID()), nil, nil)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("should be consumable from pods in volume as non-root with defaultMode and fsGroup set [Conformance]", func() {
|
||||||
|
defaultMode := int32(0440) /* setting fsGroup sets mode to at least 440 */
|
||||||
|
fsGroup := int64(1001)
|
||||||
|
uid := int64(1000)
|
||||||
|
doSecretE2EWithoutMapping(f, &defaultMode, "secret-test-"+string(uuid.NewUUID()), &fsGroup, &uid)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be consumable from pods in volume with mappings [Conformance]", func() {
|
It("should be consumable from pods in volume with mappings [Conformance]", func() {
|
||||||
@ -66,7 +73,7 @@ var _ = framework.KubeDescribe("Secrets", func() {
|
|||||||
if secret2, err = f.ClientSet.Core().Secrets(namespace2.Name).Create(secret2); err != nil {
|
if secret2, err = f.ClientSet.Core().Secrets(namespace2.Name).Create(secret2); err != nil {
|
||||||
framework.Failf("unable to create test secret %s: %v", secret2.Name, err)
|
framework.Failf("unable to create test secret %s: %v", secret2.Name, err)
|
||||||
}
|
}
|
||||||
doSecretE2EWithoutMapping(f, nil /* default mode */, secret2.Name)
|
doSecretE2EWithoutMapping(f, nil /* default mode */, secret2.Name, nil, nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should be consumable in multiple volumes in a pod [Conformance]", func() {
|
It("should be consumable in multiple volumes in a pod [Conformance]", func() {
|
||||||
@ -201,7 +208,7 @@ func secretForTest(namespace, name string) *v1.Secret {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func doSecretE2EWithoutMapping(f *framework.Framework, defaultMode *int32, secretName string) {
|
func doSecretE2EWithoutMapping(f *framework.Framework, defaultMode *int32, secretName string, fsGroup *int64, uid *int64) {
|
||||||
var (
|
var (
|
||||||
volumeName = "secret-volume"
|
volumeName = "secret-volume"
|
||||||
volumeMountPath = "/etc/secret-volume"
|
volumeMountPath = "/etc/secret-volume"
|
||||||
@ -256,6 +263,13 @@ func doSecretE2EWithoutMapping(f *framework.Framework, defaultMode *int32, secre
|
|||||||
defaultMode = &mode
|
defaultMode = &mode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fsGroup != nil || uid != nil {
|
||||||
|
pod.Spec.SecurityContext = &v1.PodSecurityContext{
|
||||||
|
FSGroup: fsGroup,
|
||||||
|
RunAsUser: uid,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
|
modeString := fmt.Sprintf("%v", os.FileMode(*defaultMode))
|
||||||
expectedOutput := []string{
|
expectedOutput := []string{
|
||||||
"content of file \"/etc/secret-volume/data-1\": value-1",
|
"content of file \"/etc/secret-volume/data-1\": value-1",
|
||||||
|
Loading…
Reference in New Issue
Block a user