How do you fake the net devices to a NixOS VM specialization that is simply built with standard Nixos module system components:
nix build .\#nixosConfigurations.deploy-test-roble\
.config.system.build.vm
It's stuck until timeout on this startup:
This is my current qemu flag setting:
QEMU_KERNEL_PARAMS=console=ttyS0 \
QEMU_NET_OPTS="hostfwd=tcp:127.0.0.1:80-:80,hostfwd=tcp:127.0.0.1:443-:433" \
sudo ./result/bin/run-roble-vm -nographic; reset
Added qemu expert question: why don't I see the boot sequence when run with sudo
despite QEMU_KERNEL_PARAMS=console=ttyS0
?
These env variables are NixOS specific, yes? I wasn't able to find anything on the QEMU_KERNEL_PARAMS
variable. But I would say that QEMU_KERNEL_PARAMS=console=ttyS0
looks odd without quotation marks. Shouldn't it be like QEMU_KERNEL_PARAMS="console=ttyS0"
?
Yes, these are a way to inject into the nixos-specific bash wrapper:
#! /nix/store/r9h133c9m8f6jnlsqzwf89zg9w0w78s8-bash-5.2-p15/bin/bash
export PATH=/nix/store/rk067yylvhyb7a360n8k1ps4lb4xsbl3-coreutils-9.3/bin${PATH:+:}$PATH
set -e
# Create an empty ext4 filesystem image. A filesystem image does not
# contain a partition table but just a filesystem.
createEmptyFilesystemImage() {
local name=$1
local size=$2
local temp=$(mktemp)
/nix/store/vvgmw7dmbpfzli5bbcks63j08ajdrl83-qemu-host-cpu-only-8.1.5/bin/qemu-img create -f raw "$temp" "$size"
/nix/store/l9sv8g6xlv06wwbsmqxx4hwpa22q7nq0-e2fsprogs-1.47.0-bin/bin/mkfs.ext4 -L nixos "$temp"
/nix/store/vvgmw7dmbpfzli5bbcks63j08ajdrl83-qemu-host-cpu-only-8.1.5/bin/qemu-img convert -f raw -O qcow2 "$temp" "$name"
rm "$temp"
}
NIX_DISK_IMAGE=$(readlink -f "${NIX_DISK_IMAGE:-./roble.qcow2}") || test -z "$NIX_DISK_IMAGE"
if test -n "$NIX_DISK_IMAGE" && ! test -e "$NIX_DISK_IMAGE"; then
echo "Disk image do not exist, creating the virtualisation disk image..."
createEmptyFilesystemImage "$NIX_DISK_IMAGE" "1024M"
echo "Virtualisation disk image created."
fi
# Create a directory for storing temporary data of the running VM.
if [ -z "$TMPDIR" ] || [ -z "$USE_TMPDIR" ]; then
TMPDIR=$(mktemp -d nix-vm.XXXXXXXXXX --tmpdir)
fi
# Create a directory for exchanging data with the VM.
mkdir -p "$TMPDIR/xchg"
cd "$TMPDIR"
# Start QEMU.
exec /nix/store/vvgmw7dmbpfzli5bbcks63j08ajdrl83-qemu-host-cpu-only-8.1.5/bin/qemu-kvm -cpu max \
-name roble \
-m 1024 \
-smp 1 \
-device virtio-rng-pci \
-net nic,netdev=user.0,model=virtio -netdev user,id=user.0,"$QEMU_NET_OPTS" \
-virtfs local,path=/nix/store,security_model=none,mount_tag=nix-store \
-virtfs local,path="${SHARED_DIR:-$TMPDIR/xchg}",security_model=none,mount_tag=shared \
-virtfs local,path="$TMPDIR"/xchg,security_model=none,mount_tag=xchg \
-drive cache=writeback,file="$NIX_DISK_IMAGE",id=drive1,if=none,index=1,werror=report -device virtio-blk-pci,bootindex=1,drive=drive1,serial=root \
-device virtio-keyboard \
-usb \
-device usb-tablet,bus=usb-bus.0 \
-kernel ${NIXPKGS_QEMU_KERNEL_roble:-/nix/store/w13hckxyqaqjaf9xxx7s889mbfhnv5iq-nixos-system-roble-23.11pre-git/kernel} \
-initrd /nix/store/ayvzq5hpdx552w092k0mbmr1qfia9inb-initrd-linux-6.6.19/initrd \
-append "$(cat /nix/store/w13hckxyqaqjaf9xxx7s889mbfhnv5iq-nixos-system-roble-23.11pre-git/kernel-params) init=/nix/store/w13hckxyqaqjaf9xxx7s889mbfhnv5iq-nixos-system-roble-23.11pre-git/init regInfo=/nix/store/xss2c6kv0rjjawcwf7vwjhcnlda8wq5q-closure-info/registration console=ttyS0,115200n8 console=tty0 $QEMU_KERNEL_PARAMS" \
$QEMU_OPTS \
"$@"
Looking at this wrapper, console=ttyS0,115200n8 console=tty0
appears to be the default, right? So you wouldn't have to set this yourself?
I figured it out -- under virtualisation.vmVariant
one can modify the vm variant.
And similarly, I could modify the network interfaces.
virtualisation.vmVariant.networking.useDHCP = lib.mkForce true;
virtualisation.vmVariant.networking.interfaces = lib.mkForce {};
David Arnold has marked this topic as resolved.
Alright, would you care posting a snippet of the whole working thing @David Arnold ? I wanna play with it maybe in the coming days. Is it possible to create Non-NixOS VMs this way?
Yep, any NixOS is also a VM under config.system.build.vm
...
It's just that virtualisation.vmVariant.*
is made so that under that namespace, you can override any other option that would otherwise be set in the "main" NixOS.
I'm currently using this for testing a Frappix deployment, but the deployment itself is private, so I can't share too much. I try to sketch some domain-specific gotchas in the docs, though.
Last updated: Nov 15 2024 at 13:04 UTC