A terminal UI (TUI) to manage KVM/libvirt virtual machines — like lazygit or
lazydocker, but for virsh. No need to remember libvirt commands.
┌───────────────────┬────────────────────────────────┐
│ Virtual machines │ Commands (for selected VM) │
│ win10-zscaler │ Start Shutdown Force stop │
│ win11-vs2022 │ Pause Resume Reboot │
│ ... [state] │ Save state Remove saved │
│ ├────────────────────────────────┤
│ │ Snapshots (of selected VM) │
│ │ name created state current │
│ │ New Revert Delete │
└───────────────────┴────────────────────────────────┘
- Left column — every VM with its current state (running / stopped / paused / …). Move the row cursor to select a VM.
- Top-right — lifecycle commands for the selected VM. Buttons enable/disable based on the VM state.
- Bottom-right — the snapshots of the selected VM, with create / revert / delete.
State is read through the libvirt API, so it is correct regardless of system locale.
libvirt-pythoninstalled system-wide (viaapt install python3-libvirt) — already present on this machine.- Membership in the
libvirtgroup to useqemu:///systemwithoutsudo.
./setup.shThis creates .venv (with --system-site-packages so it reuses the system
libvirt-python), bootstraps pip with get-pip.py, and installs Textual into it.
No sudo/apt is required.
./run.sh # defaults to qemu:///system
./run.sh --connect qemu:///session # user session VMsYou can also switch the connection at runtime with the c key.
| Key | Action |
|---|---|
s |
Start |
S |
Shutdown (ACPI) |
x |
Force stop (destroy) |
p |
Pause / Resume (toggle) |
r |
Reboot |
w |
Save state (managedsave) |
W |
Remove saved state |
o |
Open virt-viewer (VM display) |
n |
New snapshot |
v |
Revert to selected snapshot |
d |
Delete selected snapshot |
c |
Change connection URI |
R |
Refresh now |
q |
Quit |
Destructive actions (force stop, revert, delete snapshot) ask for confirmation.
A self-contained executable can be built with PyInstaller (no Docker needed):
./build-exe.shThis bundles Python, Textual, the libvirt-python binding and libvirt.so.0 into
dist/lazyvirtmanager. Run it from a terminal (it is a TUI):
./dist/lazyvirtmanager # qemu:///system
./dist/lazyvirtmanager -c qemu:///sessionPass -i to also install the built executable to ~/.local/bin:
./build-exe.sh -iNotes about the executable:
- The bundled libvirt is only the client; it connects to the host's
libvirtd, so the invoking user must still be in thelibvirtgroup. - virt-viewer is not bundled — it stays a host dependency. The
Viewcommand works ifvirt-vieweris installed on the host; otherwise it shows an error. - Built against the build machine's glibc, so it runs on systems with an equal or newer glibc. Build on the oldest distribution you need to support for wider portability.
- Save state uses libvirt
managedSave: it saves RAM + state to a libvirt-managed file and stops the VM; the next Start resumes from that saved state. - The VM list and snapshot list auto-refresh every 2 seconds.