fix(runtime): stage extra-file bind mounts under the temp dir so remote docker daemons can resolve them

This commit is contained in:
Ahmed Allam 2026-08-31 18:19:50 +00:00 • committed by Ahmed Allam
parent 1df67c52e2
commit eeca404716
2 changed files with 32 additions and 3 deletions

View file

@ -6,6 +6,7 @@ import asyncio
import logging
import os
import sys
import tempfile
from pathlib import Path
from typing import TYPE_CHECKING, Any
@ -13,7 +14,6 @@ from agents.sandbox.entries import BaseEntry, File, LocalDir
from agents.sandbox.manifest import Environment, Manifest
from strix.config import load_settings
from strix.core.paths import run_dir_for, runtime_state_dir
from strix.runtime.backends import backend_supports_bind_mounts, get_backend
from strix.runtime.caido_bootstrap import bootstrap_caido
from strix.runtime.caido_handle import CaidoBootstrapHandle
@ -168,6 +168,17 @@ def build_extra_file_entries(
return entries
def extra_file_staging_dir(scan_id: str) -> Path:
"""A fresh host staging directory for a scan's extra-file bind mounts.
The docker daemon resolves bind sources in its own filesystem. With a
remote daemon (e.g. a dind sidecar) the run directory is not shared, so
staging lives under the temp dir like every other bind-mount source.
"""
safe = "".join(c if c.isalnum() or c in "-_." else "-" for c in scan_id)
return Path(tempfile.mkdtemp(prefix=f"strix-extra-files-{safe}-"))
def build_extra_file_bind_mounts(
extra_files: list[dict[str, Any]],
staging_dir: Path,
@ -284,9 +295,10 @@ async def create_or_reuse(
bind_mounts = build_bind_mounts(local_sources)
entries: dict[str | Path, BaseEntry] = {}
if extra_files:
staging_dir = runtime_state_dir(run_dir_for(scan_id)) / "extra_files"
bind_mounts.extend(
build_extra_file_bind_mounts(extra_files, staging_dir, local_sources)
build_extra_file_bind_mounts(
extra_files, extra_file_staging_dir(scan_id), local_sources
)
)
else:
bind_mounts = []

View file

@ -2,6 +2,7 @@
from __future__ import annotations
import tempfile
from pathlib import Path
from typing import Any
@ -18,6 +19,7 @@ from strix.runtime.session_manager import (
build_extra_file_bind_mounts,
build_extra_file_entries,
build_manifest_entries,
extra_file_staging_dir,
)
@ -319,6 +321,21 @@ def test_extra_file_bind_mounts_avoid_basename_collisions(tmp_path: Path) -> Non
assert mounts[0]["source"] != mounts[1]["source"]
def test_extra_file_staging_lives_under_the_temp_dir_not_the_run_dir() -> None:
staging = extra_file_staging_dir("clients-release-evisort-dev_86b7")
assert staging.is_dir()
assert staging.is_relative_to(Path(tempfile.gettempdir()))
assert "strix_runs" not in staging.parts
def test_extra_file_staging_dir_sanitizes_the_scan_id() -> None:
staging = extra_file_staging_dir("../weird id/../")
assert staging.is_dir()
assert staging.is_relative_to(Path(tempfile.gettempdir()))
def test_only_bind_mount_capable_backends_are_registered_as_such() -> None:
assert backend_supports_bind_mounts("docker")
assert not backend_supports_bind_mounts("e2b")