|
4 | 4 | "context" |
5 | 5 | "fmt" |
6 | 6 | "os" |
| 7 | + "path/filepath" |
| 8 | + "sort" |
7 | 9 | "strconv" |
8 | 10 |
|
9 | 11 | "github.com/alibaba/pouch/apis/types" |
@@ -108,7 +110,7 @@ func setupMounts(ctx context.Context, c *Container, s *specs.Spec) error { |
108 | 110 | mounts = append(mounts, generateNetworkMounts(c)...) |
109 | 111 | } |
110 | 112 |
|
111 | | - s.Mounts = mounts |
| 113 | + s.Mounts = sortMounts(mounts) |
112 | 114 |
|
113 | 115 | if c.HostConfig.Privileged { |
114 | 116 | if !s.Root.Readonly { |
@@ -175,3 +177,30 @@ func trySetupNetworkMount(mount *types.MountPoint, c *Container) bool { |
175 | 177 |
|
176 | 178 | return false |
177 | 179 | } |
| 180 | + |
| 181 | +// mounts defines how to sort specs.Mount. |
| 182 | +type mounts []specs.Mount |
| 183 | + |
| 184 | +// Len returns the number of mounts. |
| 185 | +func (m mounts) Len() int { |
| 186 | + return len(m) |
| 187 | +} |
| 188 | + |
| 189 | +// Less returns true if the destination of mount i < destination of mount j |
| 190 | +// in lexicographic order. |
| 191 | +func (m mounts) Less(i, j int) bool { |
| 192 | + return filepath.Clean(m[i].Destination) < filepath.Clean(m[j].Destination) |
| 193 | +} |
| 194 | + |
| 195 | +// Swap swaps two items in an array of mounts. |
| 196 | +func (m mounts) Swap(i, j int) { |
| 197 | + m[i], m[j] = m[j], m[i] |
| 198 | +} |
| 199 | + |
| 200 | +// sortMounts sorts an array of mounts in lexicographic order. This ensure that |
| 201 | +// the mount like /etc/resolv.conf will not mount before /etc, so /etc will |
| 202 | +// not shadow /etc/resolv.conf |
| 203 | +func sortMounts(m []specs.Mount) []specs.Mount { |
| 204 | + sort.Stable(mounts(m)) |
| 205 | + return m |
| 206 | +} |
0 commit comments