agentscope-ai / agentscope-ai/agentscope-java

[Bug]: DockerSandbox corrupts complex sh -c commands on Windows

Đang mở
#2,135 3 bình luận 0 reaction 0 người được giao Xem trên GitHub
area/harness bug
Ngôn ngữ chính
Java
Star
5.6k
Fork
1.3k
Merge trung bình
4 ngày 12 giờ
Pull request đã merge (30 ngày)
77

Mô tả

## Summary

On a Windows host, `DockerSandbox#doExec` passes the full shell program as the last argument of:

```text
docker exec -w sh -c
```

Commands containing command substitution and embedded quotes can be corrupted while crossing Java `ProcessBuilder` -> `docker.exe` -> container `sh -c`. This currently makes the standard Harness `write_file` path fail even for a tiny new file.

This is related to #1560 (large file content embedded in the command line), but the reproduction here is only a short preflight command and fails because of quoting, not command length.

## Environment

- Windows host
- Java 17
- Docker Desktop 29.2.0
- current `main` / AgentScope Java 2.0 Harness
- image: `ubuntu:24.04`

## Minimal reproduction

Create and start an official Docker sandbox, then attach it to `SandboxBackedFilesystem` and call:

```java
SandboxBackedFilesystem filesystem = new SandboxBackedFilesystem();
filesystem.setSandbox(sandbox);
WriteResult result = filesystem.write(
runtimeContext,
"filesystem-contract.txt",
"jcode-filesystem-contract");
```

Expected:

```text
WriteResult.success
```

Actual:

```text
Failed to write file 'filesystem-contract.txt'
```

Calling the exact preflight command directly exposes the hidden error:

```java
sandbox.exec(
runtimeContext,
"if [ -e 'filesystem-contract.txt' ]; then echo 'EXISTS'; exit 1; fi; "
+ "mkdir -p \"$(dirname 'filesystem-contract.txt')\" 2>&1",
60);
```

Actual container shell error:

```text
Command exited with code 2: 'filesystem-contract.txt') 2>&1: 1: Syntax error: end of file unexpected (expecting ")")
```

The same shell program succeeds when invoked manually inside the same `ubuntu:24.04` image.

## Source path

`BaseSandboxFilesystem.write()` creates the preflight:

```java
String checkCmd =
"if [ -e " + escapedPath + " ]; then echo 'EXISTS'; exit 1; fi; "
+ "mkdir -p \"$(dirname " + escapedPath + ")\" 2>&1";
```

`DockerSandbox#doExec()` then appends that program directly as a Windows process argument:

```java
cmd.add("sh");
cmd.add("-c");
cmd.add(command);
new ProcessBuilder(cmd).start();
```

Docker events show the `sh -c` command reaching the container with damaged quoting. `BaseSandboxFilesystem.write()` also replaces the real preflight output with the generic `Failed to write file` message, which initially hides the cause.

## Impact

- Standard Harness `write_file` fails for Docker sandbox on Windows.
- `edit_file` and other complex shell-backed filesystem operations may be affected.
- Redis/MySQL cross-replica sandbox recovery cannot complete because the writer phase cannot create the workspace file.
- The failure is unrelated to Redis, snapshot persistence, or Windows host path mapping; it also reproduces in a standalone official Docker sandbox without distributed storage.

## Suggested direction

Avoid transporting a shell program as a complex `docker.exe` command-line argument on Windows. A platform-independent approach is to stream the program through stdin, for example:

```text
docker exec -i -w sh -s
```

and write the program to process stdin. This direction also aligns with #1560 and avoids both quoting corruption and OS command-line length limits.

Separately, preserve `checkResult.output()` and exit code in the `BaseSandboxFilesystem.write()` preflight failure so future backend failures remain diagnosable.

I can prepare a focused PR with Windows/Linux tests if maintainers agree with the stdin execution direction.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.