Implement bubblewrap for lightweight process container on Linux#314
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a feasibility/implementation plan document for introducing a Bubblewrap (bwrap) backend as a lightweight Linux process container for MXC.
Changes:
- Adds a new design/feasibility evaluation document describing a Bubblewrap backend architecture
- Outlines planned schema/model/parser updates, a new
bwrap_commoncrate, and SDK/platform detection changes - Documents intended policy mappings (filesystem/network) and proposed test additions
Show a summary per file
| File | Description |
|---|---|
| docs/bwrap-support/bubblewrap-backend-plan.md | New planning document describing approach, integration points, and test/docs follow-ups for a Bubblewrap backend |
Copilot's findings
- Files reviewed: 1/1 changed files
- Comments generated: 7
| | Aspect | LXC | Bubblewrap | | ||
| |--------|-----|------------| | ||
| | Privileges | Root required | Unprivileged (user namespaces) | | ||
| | Rootfs | Downloads distro rootfs | Bind-mounts host filesystem | | ||
| | Startup | Create → Start → Attach | Single `bwrap` exec | | ||
| | Network isolation | iptables + veth | `--unshare-net` (no network stack) | | ||
| | Network filtering | Per-host allow/block via iptables | `--unshare-net` for full block; iptables (reuses `NetworkIptablesManager`) for per-host filtering | | ||
| | Filesystem policy | LXC mount entries | `--ro-bind`, `--bind`, `--tmpfs` | | ||
| | Signal cleanup | Kill container on SIGTERM | Process dies with parent | | ||
| | Dependencies | `lxc-*` tools, rootfs templates | Single `bwrap` binary | |
| No backend-specific config block for now. Bubblewrap will use only the shared | ||
| cross-backend fields (`filesystem`, `network`, `process`, `lifecycle`, `ui`). Backend-specific | ||
| knobs (e.g., namespace sharing, device bindings) can be added later under `experimental.bubblewrap` | ||
| if needed. |
| No `BubblewrapConfig` struct needed for now — the runner uses only the shared | ||
| `ContainerPolicy` fields on `CodexRequest` (filesystem paths, network policy, env, etc.). | ||
| A backend-specific config can be added later under `ExperimentalConfig` if needed. |
| - `src/wxc_common/src/models.rs` — add `Bubblewrap` variant, `BubblewrapConfig` struct, wire into `ExperimentalConfig` and `CodexRequest` | ||
| - `src/wxc_common/src/config_parser.rs` — add `RawBubblewrap`, parsing, containment match arm | ||
|
|
||
| ### Schema (modify) | ||
| - `schemas/dev/mxc-config.schema.0.6.0-dev.json` — add `"bubblewrap"` to enum, add config block |
| - `src/wxc_common/src/models.rs` — add `Bubblewrap` variant, `BubblewrapConfig` struct, wire into `ExperimentalConfig` and `CodexRequest` | ||
| - `src/wxc_common/src/config_parser.rs` — add `RawBubblewrap`, parsing, containment match arm | ||
|
|
||
| ### Schema (modify) | ||
| - `schemas/dev/mxc-config.schema.0.6.0-dev.json` — add `"bubblewrap"` to enum, add config block |
| @@ -0,0 +1,358 @@ | |||
| # Bubblewrap (bwrap) Backend for MXC — Feasibility Evaluation | |||
| | Network isolation | iptables + veth | `--unshare-net` (no network stack) | | ||
| | Network filtering | Per-host allow/block via iptables | `--unshare-net` for full block; iptables (reuses `NetworkIptablesManager`) for per-host filtering | | ||
| | Filesystem policy | LXC mount entries | `--ro-bind`, `--bind`, `--tmpfs` | | ||
| | Signal cleanup | Kill container on SIGTERM | Process dies with parent | |
| //! spawns the `bwrap` binary. | ||
|
|
||
| pub mod bwrap_command; | ||
| pub mod bwrap_runner; |
There was a problem hiding this comment.
Yes — I gated bwrap_runner at the module export with #[cfg(target_os = "linux")] in src/bwrap_common/src/lib.rs so only Linux builds include it. Addressed in bed4be3.
|
@copilot resolve the merge conflicts in this pull request |
Agent-Logs-Url: https://github.com/microsoft/mxc/sessions/31b3d621-4b94-4cb1-ba58-07be3d1b1d88 Co-authored-by: huzaifa-d <16077119+huzaifa-d@users.noreply.github.com>
Merge conflicts are resolved by merging |
|
Found the following while manually testing the runtime end-to-end. build_args in bwrap_command.rs emits arguments in this order:
Because bwrap applies mounts in order with later mounts overriding at the same path, step 3's hard-coded --tmpfs /tmp obscures all the subdirs; in every policy mount in step 2 whose target lives under /tmp - /tmp/, /tmp/, /tmp/ all disappear inside the sandbox. Repro mkdir -p /tmp/bwrap-rw /tmp/bwrap-ro /tmp/bwrap-denied cat > /tmp/repro.json <<'JSON' src/target/release/lxc-exec --experimental /tmp/repro.json Observed: cat: /tmp/bwrap-ro/test.txt: No such file or directory Expected: the RO bind serves the file; the RW write succeeds and lands on the host. I will push out the fix. |
|
@copilot resolve the merge conflicts in this pull request |
Implement bubblewrap for lightweight process container on Linux.
📖 Description
This adds support for the Bubblewrap based process container on Linux.
🔍 Validation
The full PR will have complete validation tests.
✅ Checklist
📋 Issue Type
Microsoft Reviewers: Open in CodeFlow