Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion daemon/mgr/spec_mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"fmt"
"os"
"path/filepath"
"sort"
"strconv"

"github.com/alibaba/pouch/apis/types"
Expand Down Expand Up @@ -108,7 +110,7 @@ func setupMounts(ctx context.Context, c *Container, s *specs.Spec) error {
mounts = append(mounts, generateNetworkMounts(c)...)
}

s.Mounts = mounts
s.Mounts = sortMounts(mounts)

if c.HostConfig.Privileged {
if !s.Root.Readonly {
Expand Down Expand Up @@ -175,3 +177,30 @@ func trySetupNetworkMount(mount *types.MountPoint, c *Container) bool {

return false
}

// mounts defines how to sort specs.Mount.
type mounts []specs.Mount

// Len returns the number of mounts.
func (m mounts) Len() int {
return len(m)
}

// Less returns true if the destination of mount i < destination of mount j
// in lexicographic order.
func (m mounts) Less(i, j int) bool {
return filepath.Clean(m[i].Destination) < filepath.Clean(m[j].Destination)
}

// Swap swaps two items in an array of mounts.
func (m mounts) Swap(i, j int) {
m[i], m[j] = m[j], m[i]
}

// sortMounts sorts an array of mounts in lexicographic order. This ensure that
// the mount like /etc/resolv.conf will not mount before /etc, so /etc will
// not shadow /etc/resolv.conf
func sortMounts(m []specs.Mount) []specs.Mount {
sort.Stable(mounts(m))
return m
}
41 changes: 41 additions & 0 deletions daemon/mgr/spec_mount_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package mgr

import (
"reflect"
"testing"

specs "github.com/opencontainers/runtime-spec/specs-go"
)

func Test_sortMounts(t *testing.T) {
tests := []struct {
name string
args []specs.Mount
want []specs.Mount
}{
{
"Mounts is nil case",
nil,
nil,
},
{
"Normal Mounts",
[]specs.Mount{
{Destination: "/etc/resolv.conf"},
{Destination: "/etc"},
},
[]specs.Mount{
{Destination: "/etc"},
{Destination: "/etc/resolv.conf"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := sortMounts(tt.args)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("sortMounts() = %v, want %v", got, tt.want)
}
})
}
}