OpenShell Compute driver for LXD
Status: Early development. The core sandbox lifecycle (create/get/list/stop/delete, token delivery, exec) works end-to-end against a real OpenShell gateway. A number of features are not yet implemented — see Known limitations below.
openshell-driver-lxd is an out-of-tree OpenShell
compute driver backed by LXD. It implements
OpenShell's compute_driver.proto contract and serves it over gRPC via a Unix
domain socket, which the OpenShell gateway connects to at startup.
OpenShell gateway
└── Unix socket (gRPC)
└── openshell-driver-lxd
└── LXD REST API
└── LXD VM
Creating an LXD-backed sandbox end to end — the driver and gateway logs on top,
the openshell CLI driving them below.
- Rust (stable, see
rust-toolchain.toml) protoc(apt install protobuf-compiler libprotobuf-dev) forcomputev1's proto codegen- LXD, initialized with a
defaultstorage pool and anlxdbr0network
This walks through building the driver, publishing the sandbox image, and wiring both up to a real OpenShell gateway so you can create a sandbox end-to-end.
-
Install and initialize LXD, if you haven't already:
sudo snap install lxd lxd init --auto
-
Build and publish the sandbox container image under the
openshell-sandboxalias (this drivesscripts/build-sandbox-image.sh):make sandbox-image
-
Build and run the driver:
make build ./target/debug/openshell-driver-lxd \ --socket /tmp/openshell-driver.sock \ --default-image openshell-sandbox \ --gateway-grpc-port 17670--gateway-grpc-portmust match the port the gateway is told to listen on below — the driver uses it to construct each sandbox'sOPENSHELL_ENDPOINT. -
Start an OpenShell gateway pointed at the driver's socket, using the out-of-tree driver flags. A plaintext gateway still enforces request authentication by default, so for local/dev use also pass a
--configfile disabling it:cat > /tmp/openshell-gateway.toml <<'EOF' [openshell.gateway.auth] allow_unauthenticated_users = true EOF openshell-gateway \ --disable-tls \ --bind-address 0.0.0.0 \ --port 17670 \ --drivers lxd \ --compute-driver-socket /tmp/openshell-driver.sock \ --db-url "sqlite:/tmp/openshell-gateway.db?mode=rwc" \ --config /tmp/openshell-gateway.toml
--bind-address 0.0.0.0is required: the default loopback-only bind is unreachable from sandboxes on LXD'slxdbr0bridge network.--disable-tlsplusallow_unauthenticated_usersare a plaintext, unauthenticated dev shortcut — not for production use; see Security limitations. -
Register the gateway with the CLI and create a sandbox:
openshell gateway add http://127.0.0.1:17670 --local --name lxd-demo openshell gateway select lxd-demo openshell sandbox create --name demo -- id openshell sandbox exec demo -- id openshell sandbox delete demo
- No default-deny egress or sandbox-to-sandbox network isolation.
Sandboxes can reach each other and the network freely today.
lxd-clienthas the Network ACL APIs needed to build this, but nothing in the driver calls them yet. security.nesting=trueis the container's trust boundary. This grants theusernscapability, relaxes/proc/sysand cgroup mount restrictions, and allows AppArmor-stacking access — independent ofsecurity.privileged, which is not set.- No seccomp/AppArmor allowlist audit yet. Sandboxes rely on LXD's
default seccomp deny list (
kexec_load,open_by_handle_at,init_module,delete_module), not a syscall allowlist scoped to what the supervisor actually needs. - Every sandbox runs the same fixed base image, regardless of
template.imagein the request — per-template image selection isn't consulted yet. Ready=Truereflects LXD container status, not confirmed supervisor-to-gateway connectivity. A sandbox can reportReady=Trueas soon as the LXD container reachesRunning, before the supervisor inside has finished booting and connecting to the gateway. Correctly wiring this needs a guest-to-driver signal that containers don't provide; the fix lands with a planned microVM +lxd-agent-over-vsock transition, not before.
- GPU requests attach every host GPU; an exact requested
countisn't honored. - No image auto-import —
make sandbox-image(or an equivalent manual import) is a prerequisite; the driver only fails fast if the alias is missing at startup, it doesn't build or fetch one. lxd-clientopens a fresh connection per request; no connection pooling.- No MicroCloud / multi-node cluster scheduling — single LXD daemon only.
- Not yet packaged as a snap for production distribution (see Snap for the local build path that exists today).
The repository ships a snap package definition in snap/snapcraft.yaml.
snapcraftSnapcraft uses LXD as its build environment — install and initialise it first if needed:
sudo snap install lxd
lxd init --auto
sudo snap install snapcraft --classicsudo snap install openshell-driver-lxd_*.snap --dangerous
sudo snap connect openshell-driver-lxd:lxd lxd
sudo openshell-driver-lxdLicensed under the GNU Affero General Public License v3.0.
See AGENTS.md for development and contribution conventions.
