Skip to content

container inspect: make Mounts order deterministic - #53534

Merged
vvoland merged 5 commits into
moby:masterfrom
thaJeztah:stable_inspect
Sep 1, 2026
Merged

vvoland merged 5 commits into
moby:masterfrom
thaJeztah:stable_inspect

Conversation

@thaJeztah

@thaJeztah thaJeztah commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

daemon: sortMounts: rewrite with slices package

daemon: sortMounts: remove return value

sortMounts sorts the input in-place; the return value was added as part of
its initial implementation in 81fa9fe (#13161), and
from the looks of it was just for convenience.

Remove the return value to make it clear it sorts in-place and to not give
the impression that it returns a clone.

daemon: make mount sorting deterministic

Use the mount destination as a tie-breaker when mounts have the same
depth. This preserves the existing parent-before-child ordering while
ensuring that the same set of mounts always produces the same order.

daemon: sortMounts: move to container.SortMounts

Move the utility to the container package, which is where the Mount
type is defined, and to allow re-use of the utility both inside the
container package and the daemon package.

daemon/container: GetMountPoints: sort mount-points

Container mount-points are stored in a map, so GetMountPoints could return
them in arbitrary order.

Sort the result using the common mount-path ordering to provide deterministic
container inspect output.

Before this patch, order of mounts would be randomized in container inspect;

docker inspect mycontainer | jq .[].Mounts.[].Destination
"/hello"
"/hello/world"

docker inspect mycontainer | jq .[].Mounts.[].Destination
"/hello/world"
"/hello"

Release notes (optional)

Fix inconsistent mount ordering in `docker inspect` output (`GET /containers/{id}/json`) and container listings (`docker ps`, `GET /containers/json`).

A picture of a cute animal (not mandatory but encouraged)

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
sortMounts sorts the input in-place; the return value was added as part of
its initial implementation in 81fa9fe, and
from the looks of it was just for convenience.

Remove the return value to make it clear it sorts in-place and to not give
the impression that it returns a clone.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@thaJeztah thaJeztah added this to the 29.8.0 milestone Sep 1, 2026
@github-actions github-actions Bot added the area/daemon Core Engine label Sep 1, 2026
@thaJeztah
thaJeztah requested a lite review from Copilot September 1, 2026 09:25
@thaJeztah
thaJeztah marked this pull request as draft September 1, 2026 09:26
Use the mount destination as a tie-breaker when mounts have the same
depth. This preserves the existing parent-before-child ordering while
ensuring that the same set of mounts always produces the same order.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors mount sorting into daemon/container and aims to make docker inspect mount output deterministic by sorting mounts (and mount-points derived from a map) in a consistent parent-before-child order.

Changes:

  • Move mount sorting into daemon/container.SortMounts and switch callers to sort in-place.
  • Add unit tests for mount ordering and stability with duplicate destinations.
  • Sort Container.GetMountPoints() results to avoid nondeterministic map iteration order in inspect output.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
daemon/volumes.go Removes the old local mount sorting implementation and related imports.
daemon/volumes_windows.go Updates Windows mount setup to use the shared mount sorting helper (currently with a compile issue noted in comments).
daemon/volumes_unix.go Switches Unix mount setup to container.SortMounts (in-place sort).
daemon/oci_linux.go Switches OCI spec mount sorting to container.SortMounts.
daemon/container/mounts.go Introduces shared mount path comparison and exported SortMounts (currently missing destination tie-breaker per comments).
daemon/container/mounts_test.go Adds test coverage for depth ordering, same-depth determinism, and stability for duplicates.
daemon/container/container_unix.go Sorts returned mount-points for deterministic inspect output (currently missing a required import per comments).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread daemon/container/mounts.go
Comment thread daemon/container/container_unix.go
Comment thread daemon/volumes_windows.go Outdated
@thaJeztah
thaJeztah force-pushed the stable_inspect branch 2 times, most recently from cf8951b to ff6d6da Compare September 1, 2026 09:36
Move the utility to the container package, which is where the Mount
type is defined, and to allow re-use of the utility both inside the
container package and the daemon package.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Container mount-points are stored in a map, so GetMountPoints could return
them in arbitrary order.

Sort the result using the common mount-path ordering to provide deterministic
container inspect output.

Before this patch, order of mounts would be randomized in container inspect;

    docker inspect mycontainer | jq .[].Mounts.[].Destination
    "/hello"
    "/hello/world"

    docker inspect mycontainer | jq .[].Mounts.[].Destination
    "/hello/world"
    "/hello"

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@thaJeztah
thaJeztah requested a balanced review from Copilot September 1, 2026 09:37
@thaJeztah
thaJeztah marked this pull request as ready for review September 1, 2026 09:40

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

@GordonTheTurtle GordonTheTurtle left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟢 APPROVE

Reviewed the mount-sorting refactor (sortMounts → container.SortMounts, plus deterministic tie-breaking and sorted GetMountPoints output for docker inspect).

The refactor is sound:

  • All previous sortMounts call sites (daemon/oci_linux.go, daemon/volumes_unix.go, daemon/volumes_windows.go) were correctly updated to call container.SortMounts in-place; no stale references to the removed function remain, and volumes_windows.go correctly relies on the in-place mutation rather than the removed return value.
  • GetMountPoints sorting operates on a locally-built slice, so no race condition is introduced.
  • The new depth-then-lexicographic tie-break preserves the original parent-before-child ordering guarantee while making output deterministic.

No high or medium severity issues were found in this diff.

Non-blocking notes from automated analysis (low severity, informational only):

  1. daemon/container/mounts_test.go — test cases only cover POSIX-style destinations (/etc, /var, ...). Since compareMountPaths/SortMounts are shared by both container_unix.go and container_windows.go's GetMountPoints, consider adding a case (or Windows-specific test) covering backslash/drive-letter destinations to lock in cross-platform behavior.
  2. daemon/container/mounts.go — compareMountPaths (line 13) computes depth via separator count after filepath.Clean; / (root) and top-level paths like /etc both count as depth 1, so root/top-level ordering currently relies solely on the lexicographic tie-break. Works today, but isn't covered by a dedicated test case, so a future change to the tie-break could silently regress it.
  3. daemon/container/mounts.go — the tie-break (cmp.Compare(a, b), line 22) is byte-wise/case-sensitive, which may not match case-insensitive filesystem semantics on Windows. Not a functional bug (case-differing destinations at equal depth can't be parent/child of each other), just worth being aware of if visible ordering differences are ever reported.

@vvoland
vvoland merged commit 1d3cc31 into moby:master Sep 1, 2026
274 of 276 checks passed
@thaJeztah
thaJeztah deleted the stable_inspect branch September 1, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants