diff --git a/tools/environments/docker.py b/tools/environments/docker.py index 496b41d38460..febefab10486 100644 --- a/tools/environments/docker.py +++ b/tools/environments/docker.py @@ -167,6 +167,7 @@ def __init__( # escalation, PID limits). The container filesystem is writable so agents # can install packages as needed. # User-configured volume mounts (from config.yaml docker_volumes) + # Supports read-only mounts: "~/.gitconfig:/root/.gitconfig:ro" volume_args = [] for vol in (volumes or []): if not isinstance(vol, str): @@ -175,11 +176,23 @@ def __init__( vol = vol.strip() if not vol: continue + # Expand ~ in host path (first segment before first colon) + parts = vol.split(":", 1) + parts[0] = os.path.expanduser(parts[0]) + vol = ":".join(parts) if ":" in vol: volume_args.extend(["-v", vol]) else: logger.warning(f"Docker volume '{vol}' missing colon, skipping") + # Auto-mount ~/.gitconfig read-only if it exists and not already mounted + gitconfig = os.path.expanduser("~/.gitconfig") + gitconfig_target = "/root/.gitconfig" + already_mounted = any(gitconfig_target in v for v in (volumes or [])) + if os.path.exists(gitconfig) and not already_mounted: + volume_args.extend(["-v", f"{gitconfig}:{gitconfig_target}:ro"]) + logger.info("Auto-mounting ~/.gitconfig into container (read-only)") + logger.info(f"Docker volume_args: {volume_args}") all_run_args = list(_SECURITY_ARGS) + writable_args + resource_args + volume_args logger.info(f"Docker run_args: {all_run_args}") @@ -260,8 +273,18 @@ def execute(self, command: str, cwd: str = "", *, if effective_stdin is not None: cmd.append("-i") cmd.extend(["-w", work_dir]) + # Load ~/.hermes/.env so secrets set via `hermes config set` are + # available inside the Docker container (os.getenv only sees shell exports). + _hermes_env: dict = {} + try: + from hermes_cli.config import get_env_path, load_env + _hermes_env = load_env() or {} + except Exception: + pass + for key in self._inner.config.forward_env: - if (value := os.getenv(key)) is not None: + value = os.getenv(key) or _hermes_env.get(key) + if value is not None: cmd.extend(["-e", f"{key}={value}"]) for key, value in self._inner.config.env.items(): cmd.extend(["-e", f"{key}={value}"])