ov/skills/libvirt/SKILL.md
libvirt-RPC test commands — `ov test libvirt <vm> …` for VM info, framebuffer screenshots, send-key, passwd, QMP, qemu-guest-agent client, snapshots, events.
npx skillsauth add overthinkos/overthink-plugins ov:libvirtInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
MUST be invoked before any work involving: ov test libvirt commands,
libvirt RPC-based VM inspection/management, qemu-guest-agent probing,
VM snapshots, domain event watching, or any task that needs
VM-introspection surfaces beyond what ov vm (lifecycle) provides.
Top-level:
ov test libvirt list # all domains on the session
ov test libvirt info <vm> # state + graphics + uptime + agent
ov test libvirt screenshot <vm> [FILE] [--screen N] # libvirt DomainScreenshot → PNG
ov test libvirt send-key <vm> KEYS… # keyboard injection (Linux keycode set)
ov test libvirt passwd <vm> [PASSWORD] # live graphics password patch
ov test libvirt qmp <vm> COMMAND [JSON_ARGS] # QMP passthrough
ov test libvirt domain-xml <vm> # dump live XML
ov test libvirt console <vm> # (stub) serial console — use `virsh console`
ov test libvirt events [<vm>] # poll lifecycle state transitions
Remote libvirt via --uri. Every verb accepts --uri qemu+ssh://[user@]host/session (also honored as OV_LIBVIRT_URI). When
set, ov opens an SSH connection to the remote host, discovers the
remote virtqemud session socket via id -u, and forwards it over the
SSH channel — so DomainScreenshot, DomainSendKey, QMP, etc. all
work against the remote hypervisor. Example:
ov test libvirt info arch --uri qemu+ssh://o.atrawog.org/session
ov test libvirt screenshot arch --uri qemu+ssh://o.atrawog.org/session - > /tmp/shot.png
<file> args accept - for stdout. Alternatively, run ov on the
remote machine with the top-level --host flag: ov --host o test libvirt info arch.
guest subgroup — qemu-guest-agent client:
ov test libvirt guest ping <vm>
ov test libvirt guest info <vm> # agent capability list
ov test libvirt guest os-info <vm> # distro/kernel
ov test libvirt guest time <vm> # guest clock + host delta
ov test libvirt guest hostname <vm>
ov test libvirt guest users <vm>
ov test libvirt guest interfaces <vm> # IPs + MACs + stats
ov test libvirt guest disks <vm> # block devices
ov test libvirt guest fsinfo <vm> # mounted filesystems
ov test libvirt guest vcpus <vm> # guest-side online state
ov test libvirt guest exec <vm> -- CMD ARGS…
ov test libvirt guest file read <vm> PATH # cat a guest file
ov test libvirt guest file write <vm> PATH # read stdin, write to guest
ov test libvirt guest fsfreeze status|freeze|thaw <vm>
ov test libvirt guest fstrim <vm>
snapshot subgroup:
ov test libvirt snapshot list <vm>
ov test libvirt snapshot create <vm> NAME [--desc] [--disk-only]
ov test libvirt snapshot info <vm> NAME
ov test libvirt snapshot revert <vm> NAME
ov test libvirt snapshot delete <vm> NAME
Every verb maps to one go-libvirt RPC (plus, for guest *, the
QEMUDomainAgentCommand passthrough). The command name mirrors the
libvirt/virsh vocabulary so skills translate cleanly. Design
choices:
ov test spice: vms.yml entity
name → libvirt domain → live XML via libvirtxml.Domain. Errors
are the same across both commands.DomainScreenshot —
QEMU's VNC framebuffer capture, returned as PPM, decoded in-process
and re-encoded as PNG. Independent of whichever graphics protocol
(SPICE or VNC) the VM exposes on the wire.DomainSendKey. Friendly
keyname map in ov/libvirt_ops.go covers letters/digits/modifiers/
arrows/function keys. Supports chord notation ("ctrl+alt+F2").<graphics type="spice|vnc" passwd="…">
attribute via libvirtxml, then calls
DomainUpdateDeviceFlags(LIVE). --persistent also writes to the
inactive config.guest-exec + polls guest-exec-status until
exit. stdout/stderr are base64-decoded from the agent reply and
written to the CLI's stdout/stderr.# Sanity.
ov test libvirt list
ov test libvirt info arch
# Framebuffer capture (independent of SPICE wire state).
ov test libvirt screenshot arch /tmp/fb.png
# Keyboard injection via libvirt (alternate path to `ov test spice key`).
ov test libvirt send-key arch ctrl+alt+F2
# Live graphics password update.
ov test libvirt passwd arch hunter2
# QMP escape hatch.
ov test libvirt qmp arch query-status
# qemu-guest-agent (only if the guest has qemu-guest-agent installed).
ov test libvirt guest ping arch
ov test libvirt guest exec arch -- uname -a
# Transactional testing: freeze → snapshot → thaw.
ov test libvirt guest fsfreeze freeze arch
ov test libvirt snapshot create arch pre-exp
ov test libvirt guest fsfreeze thaw arch
# … exercise something destructive …
ov test libvirt snapshot revert arch pre-exp
ov test libvirt snapshot delete arch pre-exp
guest * subcommands require qemu-guest-agent installed and
running in the guest AND a <channel type='unix' ... name='org.qemu.guest_agent.0'/>
in the domain XML. The overthink layer qemu-guest-agent drops
this in for bootc VMs; cloud-image VMs need to add it to
cloud_init.packages: explicitly.
Use ov test libvirt info <vm> — if Agent: false, the agent is
not reachable.
ov test spice)ov test libvirt — libvirt RPC only. Every byte goes to
libvirtd. Works regardless of the VM's graphics protocol.ov test spice — SPICE wire only. Proves the SPICE protocol
path is alive end-to-end.For ambiguous tests, run both and diff the results.
ov/libvirt_cmd.go — Kong command tree + all verb implementations.ov/libvirt_ops.go — shared helpers (screenshot PPM→PNG decode,
key-name → Linux keycode map).ov/libvirt_guest_agent.go — typed client over
QEMUDomainAgentCommand with methods for every QGA command in use.ov/vm_target.go — shared target resolution; VmTarget.XML
gives you the live libvirtxml.Domain for fast field lookups.github.com/digitalocean/go-libvirt — pure-Go libvirt RPC client.libvirt.org/go/libvirtxml — typed domain XML parsing/generation.libvirt Arch package (libvirtd, session socket) is already a
hard dep of the ov-git PKGBUILD.development
Claude Code multi-agent support in Overthink — sub-agents, dynamic workflows, and agent teams, and how each drives the existing `ov eval` disposable beds to test and verify. MUST be invoked before authoring or invoking an ov sub-agent / dynamic workflow / agent team, wiring agent-lifecycle hooks, or asking "which primitive should drive the R10 beds?".
tools
Mounts a virtiofs share tagged `workspace` at /workspace inside a VM guest via a systemd .mount unit. Use when a kind:vm entity shares a host directory into the guest and you need it auto-mounted (and re-mounted at every boot).
development
MUST be invoked before any work involving: the `kind: android` schema kind, a `target: android` deploy, the `apk:` layer package format (installing Android apps declaratively), AndroidDeployTarget, an in-pod emulator OR a remote/physical adb-endpoint device, or nested `pod → android` deployment. The first-class Android device + app surface that sits above `ov eval adb`/`appium`.
tools
Use when committing, branching, pushing, merging, tagging, creating PRs, or approving/merging PRs with gh — the feat/-branch, R10-gated, never-force-push landing workflow across the main repo + the plugins submodule + image/<distro> submodules. Covers sync-to-upstream, branch/worktree pruning, the fork+PR path for contributors without write access, and cross-repo @github landing order.