Merge pull request #26162 from Luap99/mount-sort

libpod: fix mount order for "/" volume
This commit is contained in:
openshift-merge-bot[bot] 2025-05-20 15:27:12 +00:00 committed by GitHub
commit c8362a1d3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 89 additions and 18 deletions

View File

@ -12,7 +12,7 @@ import (
"net/http"
"os"
"path/filepath"
"sort"
"slices"
"strconv"
"strings"
"time"
@ -46,26 +46,28 @@ func MountExists(specMounts []spec.Mount, dest string) bool {
return false
}
type byDestination []spec.Mount
func (m byDestination) Len() int {
return len(m)
}
func (m byDestination) Less(i, j int) bool {
return m.parts(i) < m.parts(j)
}
func (m byDestination) Swap(i, j int) {
m[i], m[j] = m[j], m[i]
}
func (m byDestination) parts(i int) int {
return strings.Count(filepath.Clean(m[i].Destination), string(os.PathSeparator))
func parts(m spec.Mount) int {
// We must special case a root mount /.
// The count of "/" and "/proc" are both 1 but of course logically "/" must
// be mounted before "/proc" as such set the count to 0.
if m.Destination == "/" {
return 0
}
return strings.Count(filepath.Clean(m.Destination), string(os.PathSeparator))
}
func sortMounts(m []spec.Mount) []spec.Mount {
sort.Sort(byDestination(m))
slices.SortStableFunc(m, func(a, b spec.Mount) int {
aLen := parts(a)
bLen := parts(b)
if aLen < bLen {
return -1
}
if aLen == bLen {
return 0
}
return 1
})
return m
}

69
libpod/util_test.go Normal file
View File

@ -0,0 +1,69 @@
//go:build !remote
package libpod
import (
"testing"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
)
func Test_sortMounts(t *testing.T) {
tests := []struct {
name string
args []spec.Mount
want []spec.Mount
}{
{
name: "simple nested mounts",
args: []spec.Mount{
{
Destination: "/abc/123",
},
{
Destination: "/abc",
},
},
want: []spec.Mount{
{
Destination: "/abc",
},
{
Destination: "/abc/123",
},
},
},
{
name: "root mount",
args: []spec.Mount{
{
Destination: "/abc",
},
{
Destination: "/",
},
{
Destination: "/def",
},
},
want: []spec.Mount{
{
Destination: "/",
},
{
Destination: "/abc",
},
{
Destination: "/def",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := sortMounts(tt.args)
assert.Equal(t, tt.want, got)
})
}
}