runtime: overwrite mount type to bind for bind mounts

Some clients like nerdctl may pass mount type of none for volumes/bind mounts,
this will lead to container start fails.

Referring to runc, it overwrites the mount type to bind and ignores the input value.

Fixes: #4548

Signed-off-by: liubin <liubin0329@gmail.com>
This commit is contained in:
liubin 2022-06-29 16:43:16 +08:00
parent 916ffb75d7
commit 1f363a386c
2 changed files with 90 additions and 6 deletions

View File

@ -187,16 +187,27 @@ func cmdEnvs(spec specs.Spec, envs []types.EnvVar) []types.EnvVar {
func newMount(m specs.Mount) vc.Mount {
readonly := false
bind := false
for _, flag := range m.Options {
if flag == "ro" {
switch flag {
case "rbind", "bind":
bind = true
case "ro":
readonly = true
break
}
}
// normal bind mounts, set type to bind.
// https://github.com/opencontainers/runc/blob/v1.1.3/libcontainer/specconv/spec_linux.go#L512-L520
mountType := m.Type
if mountType != vc.KataEphemeralDevType && mountType != vc.KataLocalDevType && bind {
mountType = "bind"
}
return vc.Mount{
Source: m.Source,
Destination: m.Destination,
Type: m.Type,
Type: mountType,
Options: m.Options,
ReadOnly: readonly,
}
@ -913,9 +924,6 @@ func SandboxConfig(ocispec specs.Spec, runtime RuntimeConfig, bundlePath, cid, c
DisableGuestSeccomp: runtime.DisableGuestSeccomp,
// Q: Is this really necessary? @weizhang555
// Spec: &ocispec,
Experimental: runtime.Experimental,
}

View File

@ -1210,3 +1210,79 @@ func TestCalculateSandboxSizing(t *testing.T) {
assert.Equal(tt.expectedMem, mem, "unexpected memory")
}
}
func TestNewMount(t *testing.T) {
assert := assert.New(t)
testCases := []struct {
out vc.Mount
in specs.Mount
}{
{
in: specs.Mount{
Source: "proc",
Destination: "/proc",
Type: "proc",
Options: nil,
},
out: vc.Mount{
Source: "proc",
Destination: "/proc",
Type: "proc",
Options: nil,
},
},
{
in: specs.Mount{
Source: "proc",
Destination: "/proc",
Type: "proc",
Options: []string{"ro"},
},
out: vc.Mount{
Source: "proc",
Destination: "/proc",
Type: "proc",
Options: []string{"ro"},
ReadOnly: true,
},
},
{
in: specs.Mount{
Source: "/abc",
Destination: "/def",
Type: "none",
Options: []string{"bind"},
},
out: vc.Mount{
Source: "/abc",
Destination: "/def",
Type: "bind",
Options: []string{"bind"},
},
}, {
in: specs.Mount{
Source: "/abc",
Destination: "/def",
Type: "none",
Options: []string{"rbind"},
},
out: vc.Mount{
Source: "/abc",
Destination: "/def",
Type: "bind",
Options: []string{"rbind"},
},
},
}
for _, tt := range testCases {
actualMount := newMount(tt.in)
assert.Equal(tt.out.Source, actualMount.Source, "unexpected mount source")
assert.Equal(tt.out.Destination, actualMount.Destination, "unexpected mount destination")
assert.Equal(tt.out.Type, actualMount.Type, "unexpected mount type")
assert.Equal(tt.out.Options, actualMount.Options, "unexpected mount options")
assert.Equal(tt.out.ReadOnly, actualMount.ReadOnly, "unexpected mount ReadOnly")
}
}