| feat(start-os): manifest-gated /dev/kvm access for service workloads (#3787) A service that runs its own virtual machines — QEMU/KVM, Firecracker, an Android emulator — could only interpret the guest in software, because /dev/kvm is not among the devices StartOS passes into a service container. Add `hardwareVirtualization` to the manifest, alongside the existing `hardwareAcceleration` / `userspaceFilesystems` / `virtualNetworking` grants, and route /dev/kvm through the same `handle_devices` pass-through. A dedicated flag rather than widening `hardwareAcceleration`: that flag means GPU access throughout the docs and the SDK, and the split of `nestedRuntime` into two narrow flags set the precedent that each device class opts in on its own. The grant is the device and nothing else — no capabilities, no VM management API; the service stays unprivileged, userns-mapped and AppArmor-confined. On a host without KVM `handle_devices` matches nothing and the service starts as before. The granted node keeps the host's permissions and belongs to the container's root, which on /dev/kvm's 0660 means the process opening it must run as root, as the GPU packages already do for `hardwareAcceleration`. Making a group-owned device reachable by a non-root service is a separate problem: it spans /dev/kvm, /dev/dri and /dev/kfd alike, and the node's inode lives in the overlay upperdir under /var/tmp/startos, so widening its mode without moving that directory's own would expose it to every host user. Tracked in #3790 rather than bolted on here. Collapse the per-flag pass-through blocks in `LxcContainer::new` into `LxcConfig::granted_device_paths`, so the flag-to-device wiring is one table a test can read, and extract the pattern matcher as `match_device_patterns`. Tests cover which devices each device class grants, that a package opting into nothing is granted none, the flag-to-device wiring for every flag, and that a host without /dev/kvm is granted nothing. Correct the v2 manifest field table in s9pk-structure.md, which listed v1's `wrapperRepo` / `marketingSite` / `supportSite` and a `docsUrl` that exists nowhere, and glossed `satisfies` as holding version ranges when it holds concrete versions. Closes #3637 | 15 天前 |