evmctl published exhibition-vm-controller

Chapter 5 · 5 of 6

Under the hood — for builders

Optional, for anyone who wants to deploy or extend evmctl. A host controller drives the virtual machine; small agents inside the guest prove the work is alive; a plugin system adapts the core to each artwork — you do not need any of this to use the tool.

For implementers This chapter is for people setting up or extending evmctl — conservators can happily skip it. Everything above describes what the system does; here is how it is put together.

At heart evmctl separates the host — the real computer, which orchestrates, snapshots, and recovers — from the guest — the artwork’s virtual machine, the conservation object that is never modified after setup. The two talk over a simple HTTP heartbeat and the QEMU guest agent.

Physical host (Linux) · libvirt + QEMU/KVM Host controller (FastAPI) VM lifecycle · snapshots · monitor · REST /api/v1 · plugins Kiosk display Openbox + virt-viewer --kiosk · autostart Virtual machine (QEMU/KVM) — the conservation object Guest OS (Windows XP, Mac OS 9, …) QEMU guest agent (guest-ping) Monitoring scripts (AutoIT / AppleScript) Artwork · heartbeat every ~1 s HTTP heartbeat + QEMU guest agent
Figure 1. The two sides of evmctl. A host controller (FastAPI) owns the VM’s lifecycle, snapshots, and a plugin-extensible REST API; a kiosk display shows the guest full-screen. Inside the VM, a guest agent and small monitoring scripts prove the artwork is alive and signal trouble — everything the host needs to keep it running.

Host controller

A Python service (FastAPI) owns the VM’s lifecycle — start, stop, restart — together with snapshot creation and revert, heartbeat tracking, and a REST API (a web interface other programs can call) under /api/v1/ for control and management. For presentation it runs the guest full-screen through Openbox and virt-viewer --kiosk — a minimal desktop that shows nothing but the artwork — launched automatically on boot so the installation comes up unattended.

Inside the guest

Every guest carries a QEMU guest agent (for liveness checks at the level of the hypervisor — the virtualization software itself — independent of the network) and small monitoring scripts — AutoIT on Windows, AppleScript on Mac, shell scripts on Linux — that send the heartbeat, watch for idle, and verify the critical application is running. The artwork itself is never altered.

A plugin system for each artwork

Artwork-specific logic lives in plugins that hook into the core rather than forking it:

Signal handlers
React to events from guest scripts (/api/v1/signal/{event}) — a reset button, a crash, an idle timeout.
Poll providers
Expose state for guest scripts to poll (/api/v1/poll/{resource}).
State & events
Contribute to the aggregated /api/v1/state endpoint and push live updates over Server-Sent Events.
Lifecycle hooks
Pre/post-restart and startup/shutdown hooks, plus the option to serve artwork-specific web content.

Plugins auto-load from a directory, so a new work is an addition, not a rewrite. The research controller was factored onto a shared core, vmctl-core, with a common plugin spec; bringing evmctl onto that same core — so a plugin built in the workbench promotes straight into the exhibition runner — is the planned convergence, not yet shipped.

That is the whole of it: a host that keeps a verified machine alive, a guest that proves it, and plugins that adapt the two to each work. The last chapter is where to get it.