Repository navigation
feat: native Linux compute driver (openshell-driver-oci) #2255
Description
Activity
- addedstate:triage-neededOpened without agent diagnostics and needs triageOpened without agent diagnostics and needs triage
on Jul 14, 2026 This would be interesting. I would have the following quick questions:
- Why bundle
runcinstead of allowing users to supply their own OCI-compliant low-level runtime? - Apart from the detection issues / possibly misaligned API (i.e. the docker API) what other problems does this solve? Does the additional maintenance and testing burden justify the benefits?
- Would it make sense to implement this as an "External driver"?
Reacted by alangou- Why bundle
This would be interesting. I would have the following quick questions:
- Why bundle
runcinstead of allowing users to supply their own OCI-compliant low-level runtime?
Agree we can make it configurable... It's just runc is by far the most deployed one docker, containerd, CRI-O, etc. Although crun that podman uses is great.
But bundling runc make installation a bit more seamless... We could do both maybe? Bundling and configurable?
- Apart from the detection issues / possibly misaligned API (i.e. the docker API) what other problems does this solve? Does the additional maintenance and testing burden justify the benefits?
Performance and scale... Usability I guess (things like GPU via CDI directly), because we can tailor specifically to OpenShell usecases... FWIW, I think this is probably a more pragmatic proposal than bubblewrap... The authors of bubblewrap have even moved away from it for new solutions, like @cgwalters @alexlarsson (just tagging them to keep me honest).
Maybe native is the wrong name, maybe it should be runc, etc.
- Would it make sense to implement this as an "External driver"?
Personally I wouldn't have interest in implementing if it wasn't a first class citizen, but maybe others would.
- Why bundle
Extend the Docker/Podman driver's heuristics further. Keeps the host dependency and only patches the current symptom (Sandbox stuck in Provisioning on macOS with Podman (libkrun): docker driver resolves host-gateway to unreachable bridge
On MacOS, it's just required to have a Linux VM which is an inherent part of this skew.
I have a very strong opinion related to this, see https://blog.verbum.org/2026/03/23/agent-security-is-just-security/ - which is an argument against OpenShell having its own agent-specific way to run containers.
I don't think having a new "native" driver would help here if we still need to support podman/docker - and I think we do for a very important reason - we should support a flow like
docker|podman build-> run with openshell, and if we have a different container storage, that becomes an impediment.- removedstate:triage-neededOpened without agent diagnostics and needs triageOpened without agent diagnostics and needs triage
on Jul 14, 2026 - added a commit that references this issue
on Jul 16, 2026 I think @jmabry should look at this, with a few tweaks I think it can solve the issues in:
Working off direct Linux primitives instead of
bwrapseems fine. From #1393, the ability to support NFS mounts, rootless configuration for running on HPC nodes are the most important requirements. Be aware many HPC environments stuck on Rocky 8 so development should be against these older OS's. @ericcurtinReacted by Eric CurtinI think @jmabry should look at this, with a few tweaks I think it can solve the issues in:
#1393Working off direct Linux primitives instead of
bwrapseems fine. From #1393, the ability to support NFS mounts, rootless configuration for running on HPC nodes are the most important requirements. Be aware many HPC environments stuck on Rocky 8 so development should be against these older OS's. @ericcurtinRocky 8 is useful information, can be done, that might need CI to ensure we stay compatible with older linux bases.
Reacted by JOSHUA MABRY- added 2 commits that reference this issue
on Jul 17, 2026 - changed the title
[-]feat: native Linux compute driver (openshell-driver-native)[/-][+]feat: native Linux compute driver (openshell-driver-oci)[/+]on Jul 21, 2026 - added 6 commits that reference this issue
on Jul 21, 2026 Following up on the discussion around #2312, I think this issue should be scoped as an extension-driver-first OCI/runc implementation.
Proposed direction:
- Use refactor(vm): separate rootfs materialization #2388 as prerequisite design cleanup for image acquisition vs runtime-specific rootfs materialization.
- Keep rootfs preparation inside the external OCI driver process.
- Do not extend the gateway/driver RPC API to pass prepared rootfs artifacts.
- The gateway should continue to pass image refs through
CreateSandbox. - Implement
openshell-driver-ocias a standaloneComputeDriverservice over a protected Unix socket. - Use the current
compute_driver.protofor v1; defer richer capability negotiation until the first implementation proves which fields are needed.
Initial release acceptance criteria:
- opt-in extension driver only
- direct
runclifecycle - containerd/rootfs use only for image/snapshot preparation, not process execution
- correct token and TLS callback handling
- netns/veth/nftables isolation
- durable local state and restart discovery
- idempotent create/delete cleanup
- clear rejection for unsupported features
Non-goals for the first release:
- rootless mode
- GPU/CDI support
- custom bind/volume/tmpfs mounts
- local image builds
- image-based supervisor injection
- SELinux/AppArmor support
- push-based watch
- HA coordination
This issue has had no activity for 14 days and is now marked stale. It may be closed in 7 days if there is no further activity. Comment or remove the state:stale label to keep it open.
- addedstate:staleInactive item at risk of automatic closure.Inactive item at risk of automatic closure.
on Aug 28, 2026
Problem Statement
OpenShell's four compute drivers (
openshell-driver-docker,openshell-driver-podman,openshell-driver-kubernetes,openshell-driver-vm) all translate OpenShell sandbox policy into a third party's API: a container engine daemon, a cluster control plane, or libkrun. Each translation seam is a place where semantics can drift from what OpenShell actually intends:uses_host_gateway_alias()fingerprinting Docker Desktop, Colima, Lima, Rancher Desktop, and OrbStack by daemon OS string/hostname/labels, with no pattern for a Podman-backed Docker-compatible API on macOS —host.openshell.internalresolved to an unreachable bridge IP and sandboxes stuck inProvisioning. This is a structural cost, not a one-off bug: the "Docker-compatible API" is several different runtimes with divergent networking realities that need continual fingerprinting./etc/subuidfriction, and virtualization overhead where it isn't wanted.IsolationBackendcontract precisely because embedding it inline couples policy enforcement to whichever engine happens to be underneath, and blocks restricted/multi-tenant clusters that reject the elevated capabilities inline construction needs (feat: Support restricted SecurityContextConstraints for managed Kubernetes platforms #899).Proposed Design
Add a fifth compute driver,
openshell-driver-native, that constructs the sandbox from kernel primitives directly instead of delegating to an external engine. Scope, informed by what the codebase already has:Isolation via the kernel, not a re-implementation of one. Use Linux namespaces (user, mount, PID, net, UTS, IPC, cgroup), cgroups v2 for the CPU/memory limits the gateway already accepts, and seccomp +
no_new_privs. Generate an OCI runtime-specconfig.jsonfrom policy and drive a bundledruncthrough the standardcreate/start/state/deleteCLI contract — the same integration pattern containerd/CRI-O/Podman already use — rather than hand-rolling namespace/pivot_rootorchestration or linking a runtime in-process (forking inside the gateway/driver's own multithreaded async process is a hazard regardless of which runtime is chosen, so every option here ends up out-of-process).runcwas chosen over youki (Rust-native, faster per its own benchmarks, but far less production exposure and security review) because the isolation-critical path is the wrong place to prefer toolchain uniformity over the OCI reference implementation's much larger adversarial track record; the differentiated work here is mapping OpenShell policy directly onto primitives, not re-debugging a decade of container-runtime edge cases.Isolation logic implemented as an
IsolationBackend, not duplicated supervisor code. RFC 0012 explicitly anticipates a component implementing both the compute-driver and isolation-backend roles together (its "Extend the compute-driver contract" alternative calls this "natural for topologies such as MXC").openshell-driver-nativeshould be the Linux-native counterpart to that pattern rather than adding another one-off namespace-construction branch inside the supervisor — this is a hard dependency on RFC 0012 landing, not an optional nice-to-have. Doing anything else recreates exactly the coupling problem RFC 0012 was written to close.Reuse the VM driver's OCI image and network machinery instead of rebuilding it.
openshell-driver-vmalready downloads registry layers into a valid OCI layout with a content-addressed cache under its state directory (crates/openshell-driver-vm/src/driver.rs), and already generates a per-sandbox nftables ruleset with NAT, default-deny forwarding, and an input chain scoped to the gateway port (crates/openshell-driver-vm/src/nft_ruleset.rs) — today gated behind the QEMU/GPU-passthrough path only. A native driver should extract the OCI-pull/cache logic into a shared crate and reuse it with overlayfs assembly in place of ext4 conversion, and generalize the existing nftables ruleset generator to a veth-based default path instead of writing either from scratch.GPU via CDI directly. Apply CDI device nodes/mounts from the local CDI inventory when constructing the mount namespace, the same source Docker/Podman already read from — no translation layer needed.
Process model matching the existing driver pattern.
ComputeDriveris a gRPC service (proto/compute_driver.proto), not an in-process trait; drivers are separate processes. Follow theopenshell-driver-vmprecedent exactly: gateway spawns the driver binary over a private Unix socket, passing its own PID so the driver can validate the peer (crates/openshell-server/src/compute/vm.rs).Rootless by default. User namespaces with
newuidmap, no root requirement, no long-running daemon.Alternatives Considered
docker ps,docker logs) and defers the engineering cost, at the price of a permanent host dependency and translated-not-constructed policy enforcement.Non-goals
runc) through its standard CLI contract.Agent Investigation
Grounded against
origin/main:uses_host_gateway_alias()—crates/openshell-driver-docker/src/lib.rs:2456-2486; no Podman pattern; feedsdocker_gateway_route_for_host(lib.rs:2420-2442) anddocker_extra_hosts(lib.rs:2488-2499).crates/openshell-driver-vm/src/driver.rs:4293-4353(layout writers),driver.rs:3623-3746(digest-verified blob download),driver.rs:4273-4390(cache root/keying), rooted underconfig.state_dir(driver.rs:440-446).extract_layer_blob_to_dir(driver.rs:3795) and converted to ext4 viacrates/openshell-driver-vm/src/rootfs.rs:83-129.crates/openshell-driver-vm/src/nft_ruleset.rs:18-61— currently wired only throughsetup_tap_networking(crates/openshell-driver-vm/src/runtime.rs:402), called only from the QEMU/GPU path (runtime.rs:77-131); the default libkrun path uses agvproxysocket instead and does not install this ruleset (runtime.rs:654-813,crates/openshell-driver-vm/src/lifecycle.rs:109-111).crates/openshell-server/src/compute/vm.rs:452-489; enforced viacrates/openshell-driver-vm/src/main.rs:269-271andmain.rs:426-448.ComputeDriveris tonic-generated fromproto/compute_driver.proto:18-43, not a hand-written Rust trait; concrete implementations are separate processes (e.g.crates/openshell-driver-podman/src/grpc.rs:32-152).