Commit graph

187 commits

Author SHA1 Message Date
5ec888b652 test 2026-03-18 19:48:04 +00:00
196c486c24 fix: add required max_vcpus to cloud-hypervisor cpus config
cloud-hypervisor's CpusConfig requires max_vcpus when the cpus object
is present in JSON. Set it equal to boot_vcpus (no CPU hotplug).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:34:05 +00:00
dc4d9eb038 fix: use RUST_LOG env var for cloud-hypervisor log level
cloud-hypervisor doesn't support --log-level; pass the configured
log level via the RUST_LOG environment variable instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:28:49 +00:00
a90054eb2a revert: always include vmsilo-tray in guest rootfs
The guest-side tray daemon is harmless when idle and keeping it in
the rootfs allows all VMs to share the same image regardless of
tray.enable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:15:16 +00:00
2aec448e71 feat: add per-VM tray.enable option (default false)
Tray proxy was unconditionally enabled for all crosvm VMs. Add
tray.enable so it must be opted into per VM. When disabled, neither
the host-side tray service nor the guest-side tray daemon are created.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 19:13:32 +00:00
21e0a68023 fix: add missing syscalls to GPU device seccomp allowlist
The allowlist was derived from crosvm's gpu_common + gpu_device seccomp
policies, but those are applied after process startup. systemd applies
the filter before exec, so process lifecycle (execve, wait4, arch_prctl,
set_tid_address), capability management (capget, capset), and socket
server (bind, listen, accept4, socketpair) syscalls are also needed.

Also create a shader cache directory at /run/vmsilo/<name>/gpu/cache and
set __GL_SHADER_DISK_CACHE_PATH so the GPU device backend doesn't fail
trying to create /home for shader cache in the sandboxed mount namespace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 18:57:52 +00:00
6657f943fc feat: create /run/vmsilo runtime dirs in ExecStartPre
Ensure each service unit creates its own runtime directory before
starting, as a safety net independent of tmpfiles. GPU and sound
services use install -d with correct user ownership so they can
create their sockets.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 18:09:27 +00:00
ba3813ae87 style: nix fmt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:53:21 +00:00
2729e89ab4 docs: update README for cloud-hypervisor options, remove vm-start-debug
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:51:11 +00:00
239e603c25 feat: add cloud-hypervisor assertions (USB passthrough, schedulerIsolation warning)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:48:42 +00:00
d618eb2031 fix: make USB cleanup conditional on crosvm hypervisor
Also guard tray proxy to crosvm VMs only (kernel vsock required).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:47:20 +00:00
a1f4c6ca93 feat: wire up mkVmScript dispatcher, CH proxy, vm-shell --ssh for CH
- mkVmScript dispatches to mkCrosvmVmScript or mkCloudHypervisorVmScript
- Add mkChVsockConnectScript: unix socket + CONNECT handshake vsock proxy
- Proxy script uses kernel vsock for crosvm, unix socket + CONNECT for CH
- vm-shell --ssh uses ProxyCommand for cloud-hypervisor VMs
- Remove vm-start-debug script
- vmsilo-usb errors on cloud-hypervisor VMs (conditionally, only when CH VMs exist)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:45:01 +00:00
3849968ec0 feat: add mkCloudHypervisorVmScript for cloud-hypervisor VMs
Generates a two-step launch script: starts cloud-hypervisor VMM,
waits for API socket, pushes JSON VM config via ch-remote, boots.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:39:57 +00:00
4b55d77634 refactor: mkCrosvmVmScript — remove built-in GPU, use vhost-user GPU device
Remove --wayland-security-context, --gpu=, --gpu-render-server from
the crosvm command. The GPU is now provided by the external crosvm
device gpu service via --vhost-user type=gpu.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:37:00 +00:00
df0c79dfce feat: add GPU device backend service with systemd sandboxing
Runs crosvm device gpu as a separate sandboxed service per GPU VM,
with TemporaryFileSystem, DeviceAllow, CapabilityBoundingSet=,
and syscall filter derived from crosvm gpu_common + gpu_device policies.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:35:12 +00:00
f32e79e314 feat: add vmsilo-wayland-seccontext systemd service per GPU VM
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:31:45 +00:00
d79fcc002f refactor: migrate runtime sockets to per-VM subdirectory layout
Move all sockets from /run/vmsilo/<name>-*.socket to
/run/vmsilo/<name>/*.socket for cleaner organization and
future sandboxing support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:28:11 +00:00
61abef2d97 feat: add cloud-hypervisor options, remove nvidiaWeakenSandbox/gpu.vulkan
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 16:25:05 +00:00
8888250b69 Increase ALSA headroom for guest virtio-snd to reduce underruns
The virtio transport adds latency jitter that the default 256-sample
ALSA headroom can't absorb, causing frequent XRUNs (1-3 per second).
Increase headroom to 1024 samples (~23ms at 44100Hz) so PipeWire
refills the buffer much earlier, giving the virtio path more room.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 12:06:11 +00:00
463f73d274 Add PAM limits for guest PipeWire realtime scheduling
xdg-desktop-portal 1.20.3's Realtime portal intercepts PipeWire's RT
scheduling requests but fails silently: it calls fstatat(pidfd, "ns/pid")
to check the caller's PID namespace, which returns ENOTDIR because pidfds
don't support being used as directory FDs on current kernels (6.18/6.19).
PipeWire uses fire-and-forget D-Bus and never sees the error.

Fix by granting the @audio group PAM limits (rtprio=95, nice=-19,
memlock=unlimited) so PipeWire's module-rt can call sched_setscheduler
directly, bypassing both the broken portal and rtkit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 11:35:15 +00:00
b876265793 Reduce default core isolation from "full" to "vm"
Full isolation has too much impact to be a default. Even on an almost
unloaded machine with a couple of VMs running it results in audio buffer
underruns due to the significant scheduling latency.

This change is fine because with vmsilo, the trust domain is the VM. There
isn't much reason to protect apps from other apps running in the same VM.
Better to run those apps in separate VMs in that case.
2026-03-18 11:35:10 +00:00
804e5e72a0 Set RUST_BACKTRACE=full for vhost-device-sound services
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 20:12:48 +00:00
17a3b825dc Fix sound service socket path to use user runtime dir
/run/vmsilo is root-owned; the sound service runs as the configured user
and cannot create sockets there. Move the socket to /run/user/<uid>/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 20:01:08 +00:00
eda15f16f8 Update options and docs for vhost-device-sound
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 18:45:22 +00:00
cd9c24e6c1 Format with nixfmt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 18:42:12 +00:00
ebc3dbfe4b Replace --virtio-snd with --vhost-user sound
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 18:41:51 +00:00
e19757816b Add vhost-device-sound systemd service per VM
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 18:41:22 +00:00
f82e4121d3 Wire vhost-device-sound into flake and module _internal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 18:41:00 +00:00
7dabe5a0d2 Format with nixfmt
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:11:36 +00:00
40f726ffcc Add vmsilo-usb to bash completion
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:09:35 +00:00
5126a16ffd Add USB systemd services: attach/detach templates, persistent attach, cleanup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:08:45 +00:00
3b4d90bcca Add vmsilo-usb CLI script for runtime USB attach/detach/list
User-facing script that lists USB devices, attaches them to VMs, or
detaches them. Attach/detach dispatch through systemd oneshot templates
for polkit authorization; listing reads sysfs directly (no root needed).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:04:28 +00:00
609eccae4a Add USB helper library for state management and crosvm interaction
Sourced by the vmsilo-usb CLI, systemd oneshot services, and persistent
USB attach service. Provides sysfs enumeration, flock-based state file
management, and crosvm usb attach/detach wrappers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:03:57 +00:00
4ef549b981 Add assertion for duplicate USB device assignments across VMs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:58:38 +00:00
22259e187f Add usbDevices option for USB device passthrough
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 12:57:33 +00:00
0f52236f80 Disable systemd-networkd-wait-online.service
systemd-networkd-wait-online interacts badly with non-routable interfaces. It
ends up slowing down system config activation waiting for routes that never
appear. Ignoring interfaces does not reliably fix this. Just disable the damn
thing until I find a better solution.
2026-03-17 11:20:26 +00:00
ebf28dfc00 Fix TAP interfaces stuck in "configuring" by enabling ConfigureWithoutCarrier
When a VM is not running, its TAP interface has no carrier, so networkd
refuses to assign static addresses (hostAddress) and the link gets stuck
in "configuring" state. This causes systemd-networkd-wait-online to block
for 2 minutes. Setting ConfigureWithoutCarrier=yes lets networkd assign
addresses immediately regardless of carrier state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 02:20:08 +00:00
0a07f7f14e Switch ephemeral overlay from qcow2 to raw sparse image
qcow2 causes O_DIRECT failures on ext4 due to crosvm doing unaligned
access when parsing the qcow2 header. Since we don't use any qcow2
features (the disk is created fresh and deleted on stop), a raw sparse
file via truncate works just as well and also removes the qemu package
dependency from the VM service.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 00:49:44 +00:00
b8646f3020 Fix networkd wait-online by setting RequiredForOnline=no on vmsilo units
The previous --ignore approach (6a28576) didn't prevent the timeout
because bridges stayed in "configuring" setup state waiting for IPv6
autoconfiguration that never arrives. Set RequiredForOnline=no,
IPv6AcceptRA=no and LinkLocalAddressing=no directly in the networkd
.network units for all vmsilo TAP and bridge interfaces.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 20:19:15 +00:00
6a285760cd Exclude vmsilo interfaces from networkd wait-online
Prevents systemd-networkd-wait-online.service from timing out when
vmsilo TAP/bridge interfaces are not up (VMs not running), which
was causing long delays during nixos-rebuild switch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:44:29 +00:00
1a1b368c46 Add colored borders for VM app and menu icons 2026-03-07 17:33:48 +00:00
12ba119ad6 desktop: pass vm.color as-is instead of resolving to hex
KDE natively supports both named colors and hex, so no need to
resolve on the Nix side.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:22:51 +00:00
91692c709b desktop: add X-VmSilo-Color to .desktop files
Emit the resolved VM color as an X-VmSilo-Color attribute in all
generated .desktop and .directory files, for kicker to draw colored
icon borders in the application menu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:21:34 +00:00
a188977d38 Remove dead code and simplify helpers
- Remove unused ifIndexToIfName and sanitizeName from helpers.nix
- Deduplicate normalizeBdfLocal in extractBdf (reuse module-level normalizeBdf)
- Remove unused sharedHomePath variable in scripts.nix
- Fix "Packate" typo in overlay.nix comment

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:34:52 +00:00
3b640b1662 netvm: support network.netvm = "host" for host-routed networking
Route VM traffic through the host directly instead of requiring a
separate netvm VM. Uses the same nftables NAT and forward firewall
rules as VM-based netvms, applied on the host using TAP interface
names. Removes the hostNetworking.nat options in favor of the
unified netvm approach.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 15:28:47 +00:00
61f6a746bf services: add implicit dependsOn for netvm
VMs with network.netvm now automatically pull in their netvm via
Wants=, ensuring the netvm starts when the client VM is started.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 14:39:01 +00:00
f66a97a29d Use networkd for networking.* on host
Making VM network changes doesn't reliably update bridge config with the old
scripted NixOS networking.
2026-03-07 14:31:39 +00:00
d36ff56de4 networking: add bridge interfaces to networking.interfaces for networkd
Under networkd, networking.bridges only generates .netdev and member
.network files but not a .network file for the bridge device itself.
Without a matching .network unit, networkd won't bring the bridge link
up. Add empty networking.interfaces entries for each bridge so networkd
manages them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 14:25:28 +00:00
bb1ab85237 netvm: add network.netvm/isNetvm convenience layer for auto VM-to-VM links
Adds network.netvm / network.isNetvm options that auto-configure
point-to-point VM networking (host bridge, TAP interfaces, guest IPs,
default routes, masquerade NAT, and forward firewall rules) without
manual interface configuration.

New options:
  programs.vmsilo.netvmRange         — IP pool for /31 auto-allocation (default 10.200.0.0/16)
  vm.network.isNetvm                  — mark VM as a network gateway
  vm.network.netvm                    — route this VM through a named netvm
  vm.network.netvmSubnet              — override auto-allocated /31 (pin specific address)

Architecture:
  modules/netvm.nix computes all (netvm, client) pairs and writes to
  _internal.netvmInjections to avoid infinite recursion in the module
  system. networking.nix, scripts.nix, and services.nix each have a
  getEffectiveInterfaces helper that merges user-configured and
  injected interfaces transparently.

  Guest nftables config (masquerade NAT, forward isolation between
  clients, ip_forward sysctl) is injected via _generatedGuestConfig
  and merged into the rootfs build in scripts.nix.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 14:21:38 +00:00
1f8a628052 services: Start bridge netdev units before VM service
When a bridge is added to the config and nixos-rebuild switch is run,
the per-bridge netdev service is not started automatically because
network-setup.service is already active (RemainAfterExit). Add Wants
and After dependencies on <bridge>-netdev.service for each bridge used
by a VM's TAP interfaces so systemd starts it on demand when the VM
service starts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 23:26:24 +00:00