Skip to content

Bubblewrap

minisweagent.environments.extra.bubblewrap

Bubblewrap is a low-level, unprivileged sandboxing tool for Linux that enables running applications in isolated environments with restricted access to the operating system and user data. This environment uses bubblewrap to execute commands in a sandboxed environment.

Warning

This environment is experimental.

Warning

This environment is not supported on Windows.

BubblewrapEnvironmentConfig

Bases: BaseModel

cwd class-attribute instance-attribute

cwd: str = ''

Working directory for the sandbox.

env class-attribute instance-attribute

env: dict[str, str] = {}

Dictionary of environment variables to set in the sandbox.

timeout class-attribute instance-attribute

timeout: int = 30

Timeout for the command in seconds.

executable class-attribute instance-attribute

executable: str = getenv(
    "MSWEA_BUBBLEWRAP_EXECUTABLE", "bwrap"
)

Path to the bubblewrap executable.

wrapper_args class-attribute instance-attribute

wrapper_args: list[str] = [
    "--unshare-user-try",
    "--ro-bind",
    "/usr",
    "/usr",
    "--ro-bind",
    "/bin",
    "/bin",
    "--ro-bind",
    "/lib",
    "/lib",
    "--ro-bind",
    "/lib64",
    "/lib64",
    "--ro-bind",
    "/etc",
    "/etc",
    "--tmpfs",
    "/tmp",
    "--proc",
    "/proc",
    "--dev",
    "/dev",
    "--new-session",
    "--setenv",
    "PATH",
    "/usr/local/bin:/usr/sbin:/usr/bin:/bin",
]

Arguments to pass to the bubblewrap executable.

BubblewrapEnvironment

BubblewrapEnvironment(
    *,
    config_class: type = BubblewrapEnvironmentConfig,
    logger: Logger | None = None,
    **kwargs,
)

This class executes bash commands in a bubblewrap environment and a separate working directory for each environment. See BubblewrapEnvironmentConfig for kwargs.

Source code in src/minisweagent/environments/extra/bubblewrap.py
67
68
69
70
71
72
73
74
75
76
def __init__(
    self, *, config_class: type = BubblewrapEnvironmentConfig, logger: logging.Logger | None = None, **kwargs
):
    """This class executes bash commands in a bubblewrap environment and a separate working
    directory for each environment. See `BubblewrapEnvironmentConfig` for kwargs.
    """
    self.logger = logger or logging.getLogger("minisweagent.environment")
    self.config = config_class(**kwargs)
    self.working_dir = Path(tempfile.gettempdir()) / f"minisweagent-{uuid.uuid4().hex[:8]}"
    self.working_dir.mkdir(parents=True)

logger instance-attribute

logger = logger or getLogger('minisweagent.environment')

config instance-attribute

config = config_class(**kwargs)

working_dir instance-attribute

working_dir = Path(gettempdir()) / f"minisweagent-{hex[:8]}"

execute

execute(
    command: str,
    cwd: str = "",
    *,
    timeout: int | None = None,
) -> dict[str, Any]

Execute a command in the bubblewrap environment and return the result as a dict.

Source code in src/minisweagent/environments/extra/bubblewrap.py
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def execute(self, command: str, cwd: str = "", *, timeout: int | None = None) -> dict[str, Any]:
    """Execute a command in the bubblewrap environment and return the result as a dict."""
    cwd = cwd or self.config.cwd or str(self.working_dir)

    cmd = [self.config.executable] + self.config.wrapper_args + ["--bind", cwd, cwd, "--chdir", cwd]

    # Add environment variables
    for key, value in self.config.env.items():
        cmd.extend(["--setenv", key, value])

    cmd.extend(["bash", "-c", command])

    result = subprocess.run(
        cmd,
        text=True,
        timeout=timeout or self.config.timeout,
        encoding="utf-8",
        errors="replace",
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
    )
    return {"output": result.stdout, "returncode": result.returncode}

cleanup

cleanup()
Source code in src/minisweagent/environments/extra/bubblewrap.py
101
102
103
def cleanup(self):
    if self.working_dir.exists():
        shutil.rmtree(self.working_dir)

get_template_vars

get_template_vars() -> dict[str, Any]
Source code in src/minisweagent/environments/extra/bubblewrap.py
109
110
def get_template_vars(self) -> dict[str, Any]:
    return self.config.model_dump() | platform.uname()._asdict()