Merge pull request #26164 from openshift-cherrypick-robot/cherry-pick-26162-to-v5.5

[v5.5] libpod: fix mount order for "/" volume
This commit is contained in:
openshift-merge-bot[bot]
2025-05-20 17:50:26 +00:00
committed by GitHub
2 changed files with 89 additions and 18 deletions

View File

@ -12,7 +12,7 @@ import (
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"sort" "slices"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -46,26 +46,28 @@ func MountExists(specMounts []spec.Mount, dest string) bool {
return false return false
} }
type byDestination []spec.Mount func parts(m spec.Mount) int {
// We must special case a root mount /.
func (m byDestination) Len() int { // The count of "/" and "/proc" are both 1 but of course logically "/" must
return len(m) // 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 (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 sortMounts(m []spec.Mount) []spec.Mount { 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 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)
})
}
}