ocaml-qemu#
OCaml library for managing QEMU virtual machines via QMP (QEMU Machine Protocol).
Overview#
ocaml-qemu provides typed bindings to QEMU's machine control protocol, enabling OCaml applications to spawn, configure, and manage virtual machines programmatically. The library handles QMP message encoding and decoding through jsont, with Eio providing asynchronous socket communication.
Features#
- Typed QMP protocol -- JSON messages use jsont for compile-time type checking
- VM lifecycle management -- spawn, connect, pause, resume, shutdown
- Flexible configuration -- CPUs, memory, disks, networking, display, direct kernel boot
- Eio-based I/O -- efficient socket communication without blocking
Installation#
Install with opam:
$ opam install qemu
If opam cannot find the package, it may not yet be released in the public
opam-repository. Add the overlay repository, then install it:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install qemu
Usage#
open Eio.Std
let run env =
let net = Eio.Stdenv.net env in
let proc_mgr = Eio.Stdenv.process_mgr env in
Switch.run @@ fun sw ->
let config =
Qemu.Vm.Config.default ~name:"test-vm"
|> Qemu.Vm.Config.with_memory_mb 1024
|> Qemu.Vm.Config.with_disk "/path/to/disk.img"
|> Qemu.Vm.Config.with_kernel "/path/to/vmlinuz"
|> Qemu.Vm.Config.with_cmdline "console=ttyS0"
in
let vm = Qemu.Vm.spawn ~sw ~proc_mgr config in
match Qemu.Vm.connect ~sw ~net vm with
| Error e -> failwith e
| Ok () ->
(match Qemu.Vm.query_status vm with
| Ok status -> Fmt.pr "Status: %a@." Qemu.Qmp.Status.pp status
| Error e -> Fmt.pr "Error: %s@." e);
ignore (Qemu.Vm.shutdown vm)
Configuration#
The Config module provides a builder interface for VM settings:
let config =
Qemu.Vm.Config.default ~name:"my-vm"
|> Qemu.Vm.Config.with_cpus 4
|> Qemu.Vm.Config.with_memory_mb 4096
|> Qemu.Vm.Config.with_disk ~format:`Qcow2 "/path/to/disk.qcow2"
|> Qemu.Vm.Config.with_network Qemu.Vm.Config.User
|> Qemu.Vm.Config.with_display (Qemu.Vm.Config.Vnc { port = 0 })
|> Qemu.Vm.Config.with_kvm true
Direct Kernel Boot#
For unikernel or embedded Linux testing, the library supports direct kernel boot without a bootloader:
let config =
Qemu.Vm.Config.default ~name:"unikernel"
|> Qemu.Vm.Config.with_kernel "/path/to/vmlinuz"
|> Qemu.Vm.Config.with_initrd "/path/to/initrd.cpio"
|> Qemu.Vm.Config.with_cmdline "console=ttyS0 root=/dev/vda"
|> Qemu.Vm.Config.with_disk "/path/to/rootfs.img"
QMP Commands#
The library exposes common QMP commands as typed values:
let lifecycle_commands =
[ Qemu.Qmp.Command.query_status
; Qemu.Qmp.Command.stop
; Qemu.Qmp.Command.cont
; Qemu.Qmp.Command.system_powerdown
; Qemu.Qmp.Command.quit
]
Custom commands can be constructed with Command.make:
let cmd =
let arguments =
let open Json.Value in
object' [ (name "command-line", string "info status") ]
in
Qemu.Qmp.Command.make "human-monitor-command" ~arguments
Architecture#
┌──────────────┐ ┌─────────────┐ ┌──────────┐
│ Application │────▶│ ocaml-qemu │────▶│ QEMU │
│ │ │ │ │ │
│ Qemu.Vm.* │ │ QMP/JSON │ │ QMP │
│ │ │ Unix sock │ │ socket │
└──────────────┘ └─────────────┘ └──────────┘
Dependencies#
| Library | Purpose |
|---|---|
| eio | Asynchronous I/O |
| jsont | Type-safe JSON encoding |
| bytesrw | Byte stream handling |
| vlog | Structured logging |
| tty | Terminal output |
References#
- QMP Specification
- QMP Reference Manual
- xapi-project/ocaml-qmp -- alternative QMP client using yojson
Licence#
ISC