deduplicate mounts

Signed-off-by: CrazyMax <crazy-max@users.noreply.github.com>
master
CrazyMax 2021-10-17 17:38:22 +02:00
parent 87e1fa7ecb
commit 32d95c8ece
No known key found for this signature in database
GPG Key ID: 3248E46B6BB8C7F7
3 changed files with 105 additions and 45 deletions

View File

@ -100,3 +100,17 @@ func withBoundProc() oci.SpecOpts {
return nil return nil
} }
} }
func dedupMounts(mnts []specs.Mount) []specs.Mount {
ret := make([]specs.Mount, 0, len(mnts))
visited := make(map[string]int)
for i, mnt := range mnts {
if j, ok := visited[mnt.Destination]; ok {
ret[j] = mnt
} else {
visited[mnt.Destination] = i
ret = append(ret, mnt)
}
}
return ret
}

View File

@ -8,8 +8,56 @@ import (
"github.com/moby/buildkit/util/appcontext" "github.com/moby/buildkit/util/appcontext"
specs "github.com/opencontainers/runtime-spec/specs-go" specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
// The default mount-list from containerd
// https://github.com/containerd/containerd/blob/main/oci/mounts.go
var containerdDefMounts = []specs.Mount{
{
Destination: "/proc",
Type: "proc",
Source: "proc",
Options: []string{"nosuid", "noexec", "nodev"},
},
{
Destination: "/dev",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
},
{
Destination: "/dev/pts",
Type: "devpts",
Source: "devpts",
Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
},
{
Destination: "/dev/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
},
{
Destination: "/dev/mqueue",
Type: "mqueue",
Source: "mqueue",
Options: []string{"nosuid", "noexec", "nodev"},
},
{
Destination: "/sys",
Type: "sysfs",
Source: "sysfs",
Options: []string{"nosuid", "noexec", "nodev", "ro"},
},
{
Destination: "/run",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
},
}
func TestHasPrefix(t *testing.T) { func TestHasPrefix(t *testing.T) {
type testCase struct { type testCase struct {
path string path string
@ -99,52 +147,8 @@ func TestHasPrefix(t *testing.T) {
} }
func TestWithRemovedMounts(t *testing.T) { func TestWithRemovedMounts(t *testing.T) {
// The default mount-list from containerd
s := oci.Spec{ s := oci.Spec{
Mounts: []specs.Mount{ Mounts: containerdDefMounts,
{
Destination: "/proc",
Type: "proc",
Source: "proc",
Options: []string{"nosuid", "noexec", "nodev"},
},
{
Destination: "/dev",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
},
{
Destination: "/dev/pts",
Type: "devpts",
Source: "devpts",
Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
},
{
Destination: "/dev/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
},
{
Destination: "/dev/mqueue",
Type: "mqueue",
Source: "mqueue",
Options: []string{"nosuid", "noexec", "nodev"},
},
{
Destination: "/sys",
Type: "sysfs",
Source: "sysfs",
Options: []string{"nosuid", "noexec", "nodev", "ro"},
},
{
Destination: "/run",
Type: "tmpfs",
Source: "tmpfs",
Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
},
},
} }
oldLen := len(s.Mounts) oldLen := len(s.Mounts)
@ -152,3 +156,44 @@ func TestWithRemovedMounts(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, oldLen-1, len(s.Mounts)) assert.Equal(t, oldLen-1, len(s.Mounts))
} }
func TestDedupMounts(t *testing.T) {
s := oci.Spec{
Mounts: append(containerdDefMounts, []specs.Mount{
{
Destination: "/dev/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "size=131072k"},
},
{
Destination: "/foo",
Type: "bind",
Source: "/bar",
Options: []string{"nosuid", "noexec", "nodev", "rbind", "ro"},
},
{
Destination: "/dev/mqueue",
Type: "mqueue",
Source: "mqueue",
Options: []string{"nosuid"},
},
}...),
}
mntsLen := len(s.Mounts)
s.Mounts = dedupMounts(s.Mounts)
require.Equal(t, mntsLen-2, len(s.Mounts))
assert.Equal(t, specs.Mount{
Destination: "/dev/shm",
Type: "tmpfs",
Source: "shm",
Options: []string{"nosuid", "size=131072k"},
}, s.Mounts[3])
assert.Equal(t, specs.Mount{
Destination: "/foo",
Type: "bind",
Source: "/bar",
Options: []string{"nosuid", "noexec", "nodev", "rbind", "ro"},
}, s.Mounts[len(s.Mounts)-1])
}

View File

@ -164,6 +164,7 @@ func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mou
}) })
} }
s.Mounts = dedupMounts(s.Mounts)
return s, releaseAll, nil return s, releaseAll, nil
} }