For the last couple of years I have been working on a SPICE protocol native proxy called Kerbside. The basic idea is to be able to provide SPICE Virtual Desktop Interface (VDI) consoles to users from cloud platforms such as Shaken Fist, OpenStack, or oVirt. Think Citrix, but for Open Source cloud platforms. SPICE is attractive here because it has some features that other more common VDI protocols like VNC don’t have — good cut and paste support, USB device pass-through, multiple monitor support, and so on. RDP has these, but RDP was not a supported VDI protocol when using qemu on Linux with KVM until incredibly recently — literally the last couple of months.
(In terms of clouds that Kerbside supports, I think it would be relatively trivial to also support Proxmox, KubeVirt, or a list of static manually created virtual machines, but there’s only so many things one Mikal can do at once…)
Some of these cloud platforms have supported SPICE consoles for a while, but generally with warts. OpenStack for example only exposes them as HTML5 transcoded sessions with reduced functionality. oVirt exposes them via a “proxy” which is just squid (or equivalent), but its fairly dumb — it exposes the underlying hypervisor details to the client for example. I thought I could do better than that.
The proxy itself has worked for a while. I haven’t eliminated the possibility that the proxy will need to be re-written in something more performant that Python, but Python is convenient for rapid prototyping and that’s a Future Mikal problem. The proxy is not perfect, but has been a lower priority while I landed supporting code in OpenStack. Now that OpenStack Epoxy (2025.1) includes most of the supporting code, its time to circle back to the proxy itself.
In the intervening time, the pinned requirements for Kerbside have bit rotted, so its time to take CI seriously so that I can have something like Renovate walk those dependencies forwards. I feel its important to have good CI before turning on something like Renovate, because otherwise how can you tell if the dependency version increment changes broke things?
But… CI testing for graphical consoles seems fiddly to me. I can do some naive things such as testing if I receive a SPICE protocol banner from the hypervisor via the proxy, but its not great. This is the approach taken with OpenStack Tempest testing for now, but its definitely a stop gap solution. To that end, I’ve been working an a simple command line SPICE client which will help me validate that a session works. However, that presents another layer of engineering to do… How do I provide an instance with well defined graphical console behavior?
Simply put, I want very defined behaviour for the instance being used as the test target. It should be small. It should boot quickly. It should never lock or blank the screen. It should have graphical output which makes it easy to determine a state change (for example when a key press occurs). Obviously, its time to write a UEFI binary to be the test target and not bother with an operating system at all. Its entirely a coincidence that I think UEFI binaries are quite interesting and have had them on the todo list for a while.

Now, this YouTube playlist from the excellently named Queso Fuego is a nice introduction to UEFI programming, a thing I had not done before:
However, the punch line is that the bare minimum we need is a disk image with:
- Protective Master Boot Record (MBR)
- Primary and secondary GUID Partition Table (GPT) headers
- Primary and secondary GPT partition entries
- An EFI System Partition (ESP) formatted as FAT32 and containing a UEFI binary at /EFI/BOOT/BOOTX64.EFI
- A Basic Data Partition (BSP) formatted as FAT32, but not requiring any content.
Luckily, Mr Fuego provides a tool which does all of this at https://github.com/queso-fuego/UEFI-GPT-image-creator which makes this part much easier. I’m not entirely sure that watching someone else write code is a great use of my time, but on the other hand if you don’t have anyone in your life that understands UEFI, it is a way to be walked through the topic — especially when the UEFI specification is over 2,300 pages long and the book I bought on the topic isn’t actually the most gripping reading. Overall I don’t regret watching the video series.
For the disk image we basically want this:

So that’s the disk image. Inside the partitions we’ll need a FAT32 file system, which is well described by Wikipedia and also handled by Mr Fuego’s tooling.
Next of course need an actual program to run as well though. Based heavily on the code from the tutorial series, I present the snappily named uefi-latency-guest. This is available as a pre-built qcow2 image at https://images.shakenfist.com/testimages/uefi-latency-guest.qcow2 as well.
This post is long enough as it is, so we can talk more about these matters again later.