vms: integrate virtiofsd

This commit is contained in:
Jörg Thalheim
2024-02-07 14:55:14 +01:00
parent 0dadae9087
commit d6b3e03d70
2 changed files with 57 additions and 2 deletions

View File

@@ -78,7 +78,17 @@ let
done done
''; '';
}; };
boot.initrd.systemd.emergencyAccess = true;
boot.initrd.kernelModules = [ "virtiofs" ];
virtualisation.writableStore = false;
virtualisation.fileSystems = { virtualisation.fileSystems = {
"/nix/store" = {
options = lib.mkForce [ "x-systemd.requires=systemd-modules-load.service" ];
fsType = lib.mkForce "virtiofs";
};
${config.clanCore.secretsUploadDirectory} = lib.mkForce { ${config.clanCore.secretsUploadDirectory} = lib.mkForce {
device = "secrets"; device = "secrets";
fsType = "9p"; fsType = "9p";

View File

@@ -3,8 +3,10 @@ import contextlib
import importlib import importlib
import json import json
import logging import logging
import multiprocessing
import os import os
import random import random
import shutil
import socket import socket
import subprocess import subprocess
import time import time
@@ -91,6 +93,7 @@ def qemu_command(
secrets_dir: Path, secrets_dir: Path,
rootfs_img: Path, rootfs_img: Path,
state_img: Path, state_img: Path,
virtiofsd_socket: Path,
qmp_socket_file: Path, qmp_socket_file: Path,
qga_socket_file: Path, qga_socket_file: Path,
) -> QemuCommand: ) -> QemuCommand:
@@ -115,7 +118,8 @@ def qemu_command(
"-device", "virtio-rng-pci", "-device", "virtio-rng-pci",
"-net", "nic,netdev=user.0,model=virtio", "-net", "nic,netdev=user.0,model=virtio",
"-netdev", "user,id=user.0", "-netdev", "user,id=user.0",
"-virtfs", "local,path=/nix/store,security_model=none,mount_tag=nix-store", "-chardev", f"socket,id=char0,path={virtiofsd_socket}",
"-device", "vhost-user-fs-pci,chardev=char0,tag=nix-store",
"-virtfs", f"local,path={xchg_dir},security_model=none,mount_tag=shared", "-virtfs", f"local,path={xchg_dir},security_model=none,mount_tag=shared",
"-virtfs", f"local,path={xchg_dir},security_model=none,mount_tag=xchg", "-virtfs", f"local,path={xchg_dir},security_model=none,mount_tag=xchg",
"-virtfs", f"local,path={secrets_dir},security_model=none,mount_tag=secrets", "-virtfs", f"local,path={secrets_dir},security_model=none,mount_tag=secrets",
@@ -263,6 +267,43 @@ def start_waypipe(cid: int | None, title_prefix: str) -> Iterator[None]:
with subprocess.Popen(waypipe) as proc: with subprocess.Popen(waypipe) as proc:
try: try:
while not test_vsock_port(3049): while not test_vsock_port(3049):
rc = proc.poll()
if rc is not None:
msg = f"waypipe exited unexpectedly with code {rc}"
raise ClanError(msg)
time.sleep(0.1)
yield
finally:
proc.kill()
@contextlib.contextmanager
def start_virtiofsd(socket_path: Path) -> Iterator[None]:
sandbox = "namespace"
if shutil.which("newuidmap") is None:
sandbox = "none"
virtiofsd = nix_shell(
["nixpkgs#virtiofsd"],
[
"virtiofsd",
"--socket-path",
str(socket_path),
"--cache", "always",
"--posix-acl",
"--sandbox",
sandbox,
"--xattr",
"--shared-dir",
"/nix/store",
],
)
with subprocess.Popen(virtiofsd) as proc:
try:
while not socket_path.exists():
rc = proc.poll()
if rc is not None:
msg = f"virtiofsd exited unexpectedly with code {rc}"
raise ClanError(msg)
time.sleep(0.1) time.sleep(0.1)
yield yield
finally: finally:
@@ -318,6 +359,7 @@ def run_vm(vm: VmConfig, nix_options: list[str] = []) -> None:
size="50G", size="50G",
label="state", label="state",
) )
virtiofsd_socket = Path(sockets) / "virtiofsd.sock"
qemu_cmd = qemu_command( qemu_cmd = qemu_command(
vm, vm,
nixos_config, nixos_config,
@@ -325,6 +367,7 @@ def run_vm(vm: VmConfig, nix_options: list[str] = []) -> None:
secrets_dir=secrets_dir, secrets_dir=secrets_dir,
rootfs_img=rootfs_img, rootfs_img=rootfs_img,
state_img=state_img, state_img=state_img,
virtiofsd_socket=virtiofsd_socket,
qmp_socket_file=qmp_socket_file, qmp_socket_file=qmp_socket_file,
qga_socket_file=qga_socket_file, qga_socket_file=qga_socket_file,
) )
@@ -339,7 +382,9 @@ def run_vm(vm: VmConfig, nix_options: list[str] = []) -> None:
"XDG_DATA_DIRS" "XDG_DATA_DIRS"
] = f"{remote_viewer_mimetypes}:{env.get('XDG_DATA_DIRS', '')}" ] = f"{remote_viewer_mimetypes}:{env.get('XDG_DATA_DIRS', '')}"
with start_waypipe(qemu_cmd.vsock_cid, f"[{vm.machine_name}] "): with start_waypipe(
qemu_cmd.vsock_cid, f"[{vm.machine_name}] "
), start_virtiofsd(virtiofsd_socket):
run( run(
nix_shell(packages, qemu_cmd.args), nix_shell(packages, qemu_cmd.args),
env=env, env=env,