Repository navigation
probe: which display does a runner without a GPU accept? #3
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: kvm-probe | |
| # Throwaway. Answers one question: can scripts/smoke.sh --boot and --install | |
| # run on a hosted runner? Delete this file and its branch once it has answered. | |
| on: | |
| push: | |
| branches: | |
| - ci-kvm-probe | |
| jobs: | |
| probe: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: resources | |
| run: | | |
| echo "nproc: $(nproc)" | |
| free -h | |
| df -h / /mnt 2>/dev/null || df -h / | |
| echo "kernel: $(uname -r)" | |
| - name: kvm device | |
| run: | | |
| ls -l /dev/kvm || echo "NO /dev/kvm" | |
| id | |
| test -r /dev/kvm && echo "readable" || echo "NOT readable" | |
| test -w /dev/kvm && echo "writable" || echo "NOT writable" | |
| grep -o -m1 -E 'vmx|svm' /proc/cpuinfo || echo "no vmx/svm flag" | |
| - name: install qemu and friends | |
| run: | | |
| start=$SECONDS | |
| sudo apt-get update -qq | |
| sudo apt-get install -y -qq qemu-system-x86 cryptsetup-bin \ | |
| mesa-utils libegl1 libegl-mesa0 libgl1-mesa-dri >/dev/null | |
| echo "apt took $((SECONDS - start))s" | |
| qemu-system-x86_64 --version | head -1 | |
| cryptsetup --version | |
| # The device is present and the CPU exposes svm; the runner user is | |
| # simply not in the kvm group. This is the whole fix. | |
| - name: grant access to /dev/kvm | |
| run: | | |
| echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ | |
| | sudo tee /etc/udev/rules.d/99-kvm.rules | |
| sudo udevadm control --reload-rules | |
| sudo udevadm trigger --name-match=kvm | |
| ls -l /dev/kvm | |
| test -w /dev/kvm && echo "PROBE: /dev/kvm now writable" \ | |
| || echo "PROBE: /dev/kvm STILL not writable" | |
| - name: qemu says kvm is enabled | |
| run: | | |
| printf 'info kvm\nquit\n' | timeout 60 qemu-system-x86_64 \ | |
| -accel kvm -display none -m 128 -S -monitor stdio 2>&1 | tee out | |
| grep -q 'kvm support: enabled' out \ | |
| && echo "PROBE: kvm ENABLED" || echo "PROBE: kvm UNAVAILABLE" | |
| - name: cpu host under kvm | |
| run: | | |
| printf 'quit\n' | timeout 60 qemu-system-x86_64 \ | |
| -accel kvm -cpu host -display none -m 128 -S -monitor stdio 2>&1 \ | |
| | tee out | |
| grep -qi 'error\|could not' out \ | |
| && echo "PROBE: -cpu host FAILED" || echo "PROBE: -cpu host ok" | |
| - name: kvm actually executes guest code | |
| run: | | |
| set +e | |
| k=$(ls /boot/vmlinuz-* 2>/dev/null | head -1) | |
| echo "kernel image: ${k:-none found}" | |
| if [ -z "$k" ]; then echo "PROBE: no kernel on runner, skipped"; exit 0; fi | |
| # Runner kernels are commonly mode 600, so read it as root. | |
| sudo cp "$k" /tmp/vmlinuz && sudo chmod a+r /tmp/vmlinuz | |
| timeout 90 qemu-system-x86_64 -accel kvm -cpu host -smp 2 -m 1024 \ | |
| -display none -serial stdio -no-reboot \ | |
| -kernel /tmp/vmlinuz -append "console=ttyS0 panic=-1" > out 2>&1 | |
| head -25 out | |
| grep -q 'Linux version' out \ | |
| && echo "PROBE: guest kernel BOOTED under kvm" \ | |
| || echo "PROBE: guest did not boot" | |
| - name: the display smoke.sh actually asks for | |
| run: | | |
| set +e | |
| LIBGL_ALWAYS_SOFTWARE=1 timeout 45 qemu-system-x86_64 \ | |
| -enable-kvm -cpu host -smp 2 -m 1024 \ | |
| -device virtio-vga-gl -display egl-headless \ | |
| -S -monitor stdio <<< 'quit' > out 2>&1 | |
| rc=$? | |
| cat out | |
| # Exit status, not a grep for scary words: qemu prints its banner | |
| # and the monitor prompt on success, and either would false-match. | |
| [ $rc -eq 0 ] && echo "PROBE: virtio-vga-gl + egl-headless ok" \ | |
| || echo "PROBE: virtio-vga-gl + egl-headless FAILED rc=$rc" | |
| # egl-headless wants a DRM render node and a hosted runner has no GPU. | |
| # smoke.sh already takes the display as $QEMU_DISPLAY, so the question | |
| # is which alternative gives the guest a DRM device to run a | |
| # compositor on. Software rendering in the guest is fine; what is not | |
| # fine is a guest with no GPU device at all. | |
| - name: display modes without a host GPU | |
| run: | | |
| set +e | |
| ls -l /dev/dri 2>/dev/null || echo "no /dev/dri on the host" | |
| sudo modprobe vgem 2>/dev/null && ls -l /dev/dri 2>/dev/null | |
| for combo in "-device virtio-vga -display none" \ | |
| "-device virtio-gpu-pci -display none" \ | |
| "-vga std -display none" \ | |
| "-device virtio-vga-gl -display egl-headless"; do | |
| timeout 30 qemu-system-x86_64 -enable-kvm -cpu host -m 512 \ | |
| $combo -S -monitor stdio <<< 'quit' > out 2>&1 | |
| rc=$? | |
| [ $rc -eq 0 ] && echo "PROBE: ok $combo" \ | |
| || echo "PROBE: FAILED $combo ($(head -1 out))" | |
| done | |
| - name: loop devices and partition scanning | |
| run: | | |
| set +e | |
| truncate -s 2G /tmp/probe.raw | |
| loop=$(sudo losetup -fP --show /tmp/probe.raw) | |
| echo "loop: $loop" | |
| sudo sgdisk -n 1:0:+100M -n 2:0:0 "$loop" >/dev/null 2>&1 \ | |
| || sudo parted -s "$loop" mklabel gpt mkpart p1 1MiB 100MiB mkpart p2 100MiB 100% | |
| sudo partprobe "$loop" 2>/dev/null | |
| sleep 1 | |
| ls -l "${loop}p1" "${loop}p2" \ | |
| && echo "PROBE: losetup -fP exposes partitions" \ | |
| || echo "PROBE: partition nodes MISSING" | |
| printf 'probe-passphrase' | sudo cryptsetup luksFormat --batch-mode \ | |
| --key-file - "${loop}p2" \ | |
| && echo "PROBE: cryptsetup luksFormat ok" \ | |
| || echo "PROBE: cryptsetup FAILED" | |
| sudo losetup -d "$loop" | |
| - name: privileged podman | |
| run: | | |
| set +e | |
| podman --version | |
| sudo podman version --format '{{.Server.Version}}' | |
| sudo podman run --rm --privileged quay.io/fedora/fedora:44 \ | |
| sh -c 'echo PROBE: privileged podman ok' 2>&1 | tail -3 |