fix: use safe docker bind mount syntax for sandbox mounts (#1655)
Docker's -v host:container syntax is ambiguous for Windows drive-letter paths (e.g. D:/...) because ':' is both the drive separator and the volume separator, causing mount failures on Windows hosts. Introduce _format_container_mount() which uses '--mount type=bind,...' for Docker (unambiguous on all platforms) and keeps '-v' for Apple Container runtime which does not support the --mount flag yet. Adds unit tests covering Windows paths, read-only mounts, and Apple Container pass-through. Made-with: Cursor
This commit is contained in:
parent
cf43584d24
commit
3e461d9d08
|
|
@ -18,6 +18,26 @@ from .sandbox_info import SandboxInfo
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _format_container_mount(runtime: str, host_path: str, container_path: str, read_only: bool) -> list[str]:
|
||||||
|
"""Format a bind-mount argument for the selected runtime.
|
||||||
|
|
||||||
|
Docker's ``-v host:container`` syntax is ambiguous for Windows drive-letter
|
||||||
|
paths like ``D:/...`` because ``:`` is both the drive separator and the
|
||||||
|
volume separator. Use ``--mount type=bind,...`` for Docker to avoid that
|
||||||
|
parsing ambiguity. Apple Container keeps using ``-v``.
|
||||||
|
"""
|
||||||
|
if runtime == "docker":
|
||||||
|
mount_spec = f"type=bind,src={host_path},dst={container_path}"
|
||||||
|
if read_only:
|
||||||
|
mount_spec += ",readonly"
|
||||||
|
return ["--mount", mount_spec]
|
||||||
|
|
||||||
|
mount_spec = f"{host_path}:{container_path}"
|
||||||
|
if read_only:
|
||||||
|
mount_spec += ":ro"
|
||||||
|
return ["-v", mount_spec]
|
||||||
|
|
||||||
|
|
||||||
class LocalContainerBackend(SandboxBackend):
|
class LocalContainerBackend(SandboxBackend):
|
||||||
"""Backend that manages sandbox containers locally using Docker or Apple Container.
|
"""Backend that manages sandbox containers locally using Docker or Apple Container.
|
||||||
|
|
||||||
|
|
@ -246,18 +266,26 @@ class LocalContainerBackend(SandboxBackend):
|
||||||
|
|
||||||
# Config-level volume mounts
|
# Config-level volume mounts
|
||||||
for mount in self._config_mounts:
|
for mount in self._config_mounts:
|
||||||
mount_spec = f"{mount.host_path}:{mount.container_path}"
|
cmd.extend(
|
||||||
if mount.read_only:
|
_format_container_mount(
|
||||||
mount_spec += ":ro"
|
self._runtime,
|
||||||
cmd.extend(["-v", mount_spec])
|
mount.host_path,
|
||||||
|
mount.container_path,
|
||||||
|
mount.read_only,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Extra mounts (thread-specific, skills, etc.)
|
# Extra mounts (thread-specific, skills, etc.)
|
||||||
if extra_mounts:
|
if extra_mounts:
|
||||||
for host_path, container_path, read_only in extra_mounts:
|
for host_path, container_path, read_only in extra_mounts:
|
||||||
mount_spec = f"{host_path}:{container_path}"
|
cmd.extend(
|
||||||
if read_only:
|
_format_container_mount(
|
||||||
mount_spec += ":ro"
|
self._runtime,
|
||||||
cmd.extend(["-v", mount_spec])
|
host_path,
|
||||||
|
container_path,
|
||||||
|
read_only,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
cmd.append(self._image)
|
cmd.append(self._image)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
from deerflow.community.aio_sandbox.local_backend import _format_container_mount
|
||||||
|
|
||||||
|
|
||||||
|
def test_format_container_mount_uses_mount_syntax_for_docker_windows_paths():
|
||||||
|
args = _format_container_mount("docker", "D:/deer-flow/backend/.deer-flow/threads", "/mnt/threads", False)
|
||||||
|
|
||||||
|
assert args == [
|
||||||
|
"--mount",
|
||||||
|
"type=bind,src=D:/deer-flow/backend/.deer-flow/threads,dst=/mnt/threads",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_format_container_mount_marks_docker_readonly_mounts():
|
||||||
|
args = _format_container_mount("docker", "/host/path", "/mnt/path", True)
|
||||||
|
|
||||||
|
assert args == [
|
||||||
|
"--mount",
|
||||||
|
"type=bind,src=/host/path,dst=/mnt/path,readonly",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_format_container_mount_keeps_volume_syntax_for_apple_container():
|
||||||
|
args = _format_container_mount("container", "/host/path", "/mnt/path", True)
|
||||||
|
|
||||||
|
assert args == [
|
||||||
|
"-v",
|
||||||
|
"/host/path:/mnt/path:ro",
|
||||||
|
]
|
||||||
Loading…
Reference in New Issue