Files
Florent BENOIT a4c848adbd feat(vm): add host bind mount support via virtiofs (libkrun) (#3463)
* feat(vm): add host bind mount support via virtiofs (libkrun)

Introduce host directory bind mounts for libkrun VM sandboxes using
the virtiofs4 API with simplified permission semantics. The gateway
accepts `enable_bind_mounts` in the `[openshell.drivers.vm]` TOML
table and forwards it to the VM driver subprocess.

Mounts are specified per-sandbox in driver_config.mounts[] with
source, target, optional read_only (default: read-only), and an
optional `type` that must be `bind`, so Docker and Podman bind entries
(without `selinux_label`) parse unchanged.

At sandbox validation the driver rejects mounts unless bind mounts
are enabled and resource admission is disabled. It rejects GPU and
other QEMU launches, sources with control characters, and more mounts
than libkrun has interrupt lines for (32 on aarch64, 3 on x86_64), and
checks targets against reserved VM-internal directories and each other
(no nested targets). The QEMU check runs again once the launch backend
is resolved.

Host source directories are checked at provisioning, before image
preparation, so a briefly missing source fails provisioning visibly
instead of denying recovery of a persisted sandbox. Missing,
inaccessible, symlinked, non-directory, and unreadable sources are
rejected: libkrun does not follow a final symlink, and on macOS it
panics during guest boot when it cannot open the share root.

The driver generates virtiofs tags and always writes a guest-side
manifest into the overlay disk, together with the init drop-ins, so an
image-supplied manifest can never drive guest mounts. The launcher
parses its tab-separated --vm-mount arguments from the right, so a
source can never shift the tag or mode, and the driver logs each
shared directory at launch.

Guest init mounts the shares after every /sandbox ownership fixup
and the init drop-ins, so recursive chowns never reach host files.
It refuses targets that traverse symlinks in the image, hands newly
created mount point parents under /sandbox to the sandbox user, and
skips an empty manifest.

krun_add_virtiofs4 is resolved optionally, so older libkrun runtimes
still boot sandboxes without mounts.

The kernel config lists CONFIG_FUSE_FS and CONFIG_VIRTIO_FS
explicitly; the pinned libkrunfw base config already enables both.

A vm_bind_mount e2e test checks a read-write share round-trips data
with the host, accepts a new file, directory, and nested file that the
host then sees, and that a read-only share rejects writes. libkrun on
rootless Linux refuses file creation by a guest user whose UID/GID
differ from its own, so the VM e2e gateway runs the sandbox as the
gateway user there. It enables bind mounts like the Docker and Podman
e2e gateways.

The runtimes docs cover the mount limit, the symlink restriction, the
guest-kernel exposure, and the rootless Linux UID/GID note. The
debug-openshell-cluster skill lists VM bind mount checks.

Signed-off-by: Florent Benoit <fbenoit@redhat.com>

* fix(nix): refresh vm-runtime hashes to the libkrun v1.19.4 runtime

The Nix vm-runtime package fetches the rolling vm-runtime release with
fixed hashes pinned on 2026-09-16. The release was rebuilt on
2026-09-21 after the libkrun v1.19.4 / libkrunfw v5.6.1 bump (#3451),
but the hashes were not updated, so CI kept substituting the
2026-09-15 runtime (libkrun v1.17.4) from the binary cache.

That libkrun lacks krun_add_virtiofs4, which VM bind mounts need.
Point the hashes at the current release assets.

Signed-off-by: Florent Benoit <fbenoit@redhat.com>

---------

Signed-off-by: Florent Benoit <fbenoit@redhat.com>
2026-10-16 07:56:32 +00:00
..

VM Driver Runtime

Status: Experimental. VM support is under active development and may change.

This directory owns the pinned runtime inputs for openshell-driver-vm:

runtime/
  pins.env
  kernel/
    openshell.kconfig

openshell-driver-vm embeds libkrun, libkrunfw, umoci for guest-side OCI image unpacking, and the portable capability-free openshell-sandbox role. VMs do not attach a guest NIC. The boundary carries control, mediated network, and DNS streams over the authenticated vsock channel.

Why

The stock libkrunfw kernel does not include every cgroup, seccomp, and Landlock feature the sandbox needs inside each microVM. kernel/openshell.kconfig extends the libkrunfw kernel so VM sandboxes retain guest-local process, network-syscall, and filesystem enforcement while the supervisor runs on the host.

Build Scripts

Script Platform Purpose
tasks/scripts/vm/build-libkrun.sh Linux Builds libkrunfw and libkrun from source with the custom kernel config
tasks/scripts/vm/build-libkrun-macos.sh macOS Builds portable libkrunfw and libkrun from a prebuilt kernel.c
tasks/scripts/vm/package-vm-runtime.sh Any Packages vm-runtime-<platform>.tar.zst with libraries, umoci, and provenance
tasks/scripts/vm/download-kernel-runtime.sh Any Downloads runtime tarballs from the vm-runtime release and stages compressed files

Local Flow

# Download the current pre-built runtime and stage compressed artifacts
mise run vm:setup

# Build the portable Linux guest sandbox and static guest-init helper
mise run vm:supervisor

# Build the gateway, native host supervisor, and VM driver
OPENSHELL_VM_RUNTIME_COMPRESSED_DIR=$PWD/target/vm-runtime-compressed \
  cargo build -p openshell-gateway -p openshell-supervisor -p openshell-driver-vm

Use FROM_SOURCE=1 mise run vm:setup to build the runtime from source instead of downloading vm-runtime-<platform>.tar.zst.

CI Ownership

release-vm-kernel.yml is the on-demand producer for:

  • vm-runtime-linux-aarch64.tar.zst
  • vm-runtime-linux-x86_64.tar.zst
  • vm-runtime-darwin-aarch64.tar.zst

Those artifacts stay on the rolling vm-runtime release. Normal dev and v* release workflows download them, embed them into openshell-driver-vm, and publish the driver binary next to openshell-gateway.

Provenance

package-vm-runtime.sh writes provenance.json into each runtime tarball with the platform, libkrunfw commit, kernel version, and umoci version, GitHub SHA, and build time. The driver logs this metadata when it extracts and loads a runtime bundle.

The release workflow also publishes GitHub artifact attestations for each runtime tarball. Verify a downloaded runtime with:

gh attestation verify vm-runtime-linux-x86_64.tar.zst -R NVIDIA/OpenShell