Unverified Commit 18f4924f authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #62633 from jsafrane/automated-cherry-pick-of-#62462-upstream-release-1.10

Automatic merge from submit-queue. Automated cherry pick of #62462: Add private mount propagation to API. Cherry pick of #62462 on release-1.10. #62462: Add private mount propagation to API.
parents f662ec83 9a954248
......@@ -1711,6 +1711,12 @@ type VolumeMount struct {
type MountPropagationMode string
const (
// MountPropagationNone means that the volume in a container will
// not receive new mounts from the host or other containers, and filesystems
// mounted inside the container won't be propagated to the host or other
// containers.
// Note that this mode corresponds to "private" in Linux terminology.
MountPropagationNone MountPropagationMode = "None"
// MountPropagationHostToContainer means that the volume in a container will
// receive new mounts from the host or other containers, but filesystems
// mounted inside the container won't be propagated to the host or other
......
......@@ -1140,7 +1140,7 @@ func validateMountPropagation(mountPropagation *core.MountPropagationMode, conta
return allErrs
}
supportedMountPropagations := sets.NewString(string(core.MountPropagationBidirectional), string(core.MountPropagationHostToContainer))
supportedMountPropagations := sets.NewString(string(core.MountPropagationBidirectional), string(core.MountPropagationHostToContainer), string(core.MountPropagationNone))
if !supportedMountPropagations.Has(string(*mountPropagation)) {
allErrs = append(allErrs, field.NotSupported(fldPath, *mountPropagation, supportedMountPropagations.List()))
}
......
......@@ -4845,6 +4845,7 @@ func TestValidateMountPropagation(t *testing.T) {
propagationBidirectional := core.MountPropagationBidirectional
propagationHostToContainer := core.MountPropagationHostToContainer
propagationNone := core.MountPropagationNone
propagationInvalid := core.MountPropagationMode("invalid")
tests := []struct {
......@@ -4865,6 +4866,12 @@ func TestValidateMountPropagation(t *testing.T) {
false,
},
{
// non-privileged container + None
core.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationNone},
defaultContainer,
false,
},
{
// error: implicitly non-privileged container + Bidirectional
core.VolumeMount{Name: "foo", MountPath: "/foo", MountPropagation: &propagationBidirectional},
defaultContainer,
......
......@@ -301,12 +301,14 @@ func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.M
}
switch {
case mountMode == nil:
// HostToContainer is the default
return runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER, nil
// PRIVATE is the default
return runtimeapi.MountPropagation_PROPAGATION_PRIVATE, nil
case *mountMode == v1.MountPropagationHostToContainer:
return runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER, nil
case *mountMode == v1.MountPropagationBidirectional:
return runtimeapi.MountPropagation_PROPAGATION_BIDIRECTIONAL, nil
case *mountMode == v1.MountPropagationNone:
return runtimeapi.MountPropagation_PROPAGATION_PRIVATE, nil
default:
return 0, fmt.Errorf("invalid MountPropagation mode: %q", mountMode)
}
......
......@@ -101,6 +101,7 @@ func TestMakeMounts(t *testing.T) {
bTrue := true
propagationHostToContainer := v1.MountPropagationHostToContainer
propagationBidirectional := v1.MountPropagationBidirectional
propagationNone := v1.MountPropagationNone
testCases := map[string]struct {
container v1.Container
......@@ -125,9 +126,10 @@ func TestMakeMounts(t *testing.T) {
MountPropagation: &propagationHostToContainer,
},
{
MountPath: "/mnt/path3",
Name: "disk",
ReadOnly: true,
MountPath: "/mnt/path3",
Name: "disk",
ReadOnly: true,
MountPropagation: &propagationNone,
},
{
MountPath: "/mnt/path4",
......@@ -156,7 +158,7 @@ func TestMakeMounts(t *testing.T) {
HostPath: "/mnt/disk",
ReadOnly: true,
SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
Propagation: runtimeapi.MountPropagation_PROPAGATION_PRIVATE,
},
{
Name: "disk4",
......@@ -164,7 +166,7 @@ func TestMakeMounts(t *testing.T) {
HostPath: "/mnt/host",
ReadOnly: false,
SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
Propagation: runtimeapi.MountPropagation_PROPAGATION_PRIVATE,
},
{
Name: "disk5",
......@@ -172,7 +174,7 @@ func TestMakeMounts(t *testing.T) {
HostPath: "/var/lib/kubelet/podID/volumes/empty/disk5",
ReadOnly: false,
SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
Propagation: runtimeapi.MountPropagation_PROPAGATION_PRIVATE,
},
},
expectErr: false,
......@@ -231,7 +233,7 @@ func TestMakeMounts(t *testing.T) {
HostPath: "/mnt/host",
ReadOnly: false,
SELinuxRelabel: false,
Propagation: runtimeapi.MountPropagation_PROPAGATION_HOST_TO_CONTAINER,
Propagation: runtimeapi.MountPropagation_PROPAGATION_PRIVATE,
},
},
expectErr: false,
......
......@@ -1831,6 +1831,12 @@ type VolumeMount struct {
type MountPropagationMode string
const (
// MountPropagationNone means that the volume in a container will
// not receive new mounts from the host or other containers, and filesystems
// mounted inside the container won't be propagated to the host or other
// containers.
// Note that this mode corresponds to "private" in Linux terminology.
MountPropagationNone MountPropagationMode = "None"
// MountPropagationHostToContainer means that the volume in a container will
// receive new mounts from the host or other containers, but filesystems
// mounted inside the container won't be propagated to the host or other
......
......@@ -28,7 +28,7 @@ import (
. "github.com/onsi/gomega"
)
func preparePod(name string, node *v1.Node, propagation v1.MountPropagationMode, hostDir string) *v1.Pod {
func preparePod(name string, node *v1.Node, propagation *v1.MountPropagationMode, hostDir string) *v1.Pod {
const containerName = "cntr"
bTrue := true
var oneSecond int64 = 1
......@@ -49,7 +49,7 @@ func preparePod(name string, node *v1.Node, propagation v1.MountPropagationMode,
{
Name: "host",
MountPath: "/mnt/test",
MountPropagation: &propagation,
MountPropagation: propagation,
},
},
SecurityContext: &v1.SecurityContext{
......@@ -105,12 +105,19 @@ var _ = SIGDescribe("Mount propagation", func() {
}()
podClient := f.PodClient()
master := podClient.CreateSync(preparePod("master", node, v1.MountPropagationBidirectional, hostDir))
slave := podClient.CreateSync(preparePod("slave", node, v1.MountPropagationHostToContainer, hostDir))
bidirectional := v1.MountPropagationBidirectional
master := podClient.CreateSync(preparePod("master", node, &bidirectional, hostDir))
hostToContainer := v1.MountPropagationHostToContainer
slave := podClient.CreateSync(preparePod("slave", node, &hostToContainer, hostDir))
none := v1.MountPropagationNone
private := podClient.CreateSync(preparePod("private", node, &none, hostDir))
defaultPropagation := podClient.CreateSync(preparePod("default", node, nil, hostDir))
// Check that the pods sees directories of each other. This just checks
// that they have the same HostPath, not the mount propagation.
podNames := []string{master.Name, slave.Name}
podNames := []string{master.Name, slave.Name, private.Name, defaultPropagation.Name}
for _, podName := range podNames {
for _, dirName := range podNames {
cmd := fmt.Sprintf("test -d /mnt/test/%s", dirName)
......@@ -147,6 +154,10 @@ var _ = SIGDescribe("Mount propagation", func() {
"master": sets.NewString("master", "host"),
// Slave sees master's mount + itself.
"slave": sets.NewString("master", "slave", "host"),
// Private sees only its own mount
"private": sets.NewString("private"),
// Default (=private) sees only its own mount
"default": sets.NewString("default"),
}
dirNames := append(podNames, "host")
for podName, mounts := range expectedMounts {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment