0952aa8217
When git repo mounts and regular file mounts have overlapping target paths, broader parent mounts hide deeper child mounts because Docker Compose applies volumes in array order. - Add sort_volumes_by_specificity() to docker.py: - Sorts by target path depth (parent paths first, child paths last) - Logs warnings for duplicate targets - Handles :bind and :ro suffixes correctly - Integrate into manifest flow (compile_compose): - Sorts manifest mounts + EXTRA_VOLUMES before writing compose - Integrate into legacy flow (_modify_compose_file): - Sorts after appending extra_volumes to existing template volumes - Add 6 unit tests covering parent/child ordering, stable sort, type suffixes, empty list, single volume, and duplicate warnings. Quality gates: pytest (214 passed, 6 pre-existing), tsc --noEmit (clean)
1.7 KiB
1.7 KiB
Spec: Mount Specificity Ordering
Requirements
- All volume mount entries written to compose files must be sorted by target path depth.
- Shorter / parent target paths appear before deeper / child target paths.
- Deeper mounts are applied later by Docker, overlaying parent mounts correctly.
- Exact same-target overlaps are logged as warnings.
- Works for both manifest and legacy compose generation paths.
Algorithm
def sort_volumes_by_specificity(volumes: list[str]) -> list[str]:
"""
Sort volume strings so parent paths come before child paths.
Volume format: source:target or source:target:type
"""
- Parse each volume string to extract the target path (second colon-delimited field).
- Normalize the target: strip trailing
/, collapse//. - Compute depth = number of
/-separated segments. - Sort ascending by depth. Stable sort preserves input order for equal depths.
- Detect exact same-target strings and log warnings.
Compose Format Handling
source:target→ target is second fieldsource:target:bind→ target is second fieldsource:target:ro→ target is second field- Split by
:into at most 3 parts. Target is always index 1.
Integration Points
compile_compose()inmanifest_compiler.py: sortvolumeslist before assigning toservice["volumes"]._modify_compose_file()intool_instances.py: sortservice_config["volumes"]after appending extra volumes.
Tests
- Repo mount
/workspace/x+ file mount/workspace/x/y/config.json→ file mount comes after. - Same depth mounts → stable order preserved.
- Exact same target → warning logged.
- Empty volumes list → no-op.
- Volume with
typesuffix → parsed correctly.