Andrew Mercer
on this page

kvm-adm

Part of the KVM overview. kvm-adm is a single Rust CLI that wraps the everyday virsh, virt-install, virt-clone, qemu-img and libguestfs commands documented in this section, so you do not have to remember them.

It shells out to the real tools, so everything it does can be reproduced by hand, and --dry-run shows the exact commands. The only crate dependency is clap.

Install

tar xzf kvm-adm-0.1.0.tar.gz
cd kvm-adm-0.1.0
cargo install --path . --root ~/.local
kvm-adm host doctor            # check tools, /dev/kvm, CPU flags, libvirt connectivity

Later releases: drop the newer kvm-adm-X.Y.Z.tar.gz in update_dir and run kvm-adm update.

Configuration

~/.kvm-adm.conf, one key = value per line, # for comments. kvm-adm config prints the effective values.

Key Default Meaning
connect qemu:///system libvirt URI (qemu:///session for per-user VMs)
images_dir /var/lib/libvirt/images Where new disk images are created
bridge empty Default bridge for new VMs and NICs; empty means use network
network default Default libvirt network
os_variant generic Default --os-variant (search with kvm-adm os-variants)
sudo false Prefix every command with sudo
tmpdir empty TMPDIR for libguestfs when /tmp is too small
update_dir ~/Downloads Where kvm-adm update looks for tarballs
install_root ~/.local cargo install --root used by update

Global flags

Flag Effect
-n, --dry-run Print the commands that would change something instead of running them. Read-only queries (state checks, listings) still run, because later steps depend on them.
-y, --yes Answer yes to confirmation prompts (delete, snap delete)
-c, --connect URI Override connect for this run

VM commands

Command What it does Raw equivalent
ls [-r] List VMs (-r: running only) virsh list --all
start VM Start virsh start
stop VM [-f] ACPI shutdown; -f forces off virsh shutdown / destroy
reboot VM Reboot virsh reboot
autostart VM [--off] Enable or disable start on host boot virsh autostart [--disable]
info VM State, resources, disks and interfaces dominfo, domblklist, domiflist
ip VM Find the IP: guest agent, then DHCP lease, then ARP virsh domifaddr --source ...
console VM Serial console (Ctrl+] to leave) virsh console
edit VM Edit the domain XML virsh edit
stats VM Runtime stats and vCPU placement domstats, vcpuinfo
clone SRC NAME [--file F ...] Clone a shut-off VM; default --auto-clone, or one --file per disk virt-clone
delete VM [--keep-storage] Confirm, force off if needed, undefine including managed-save, snapshot metadata and NVRAM, delete disks virsh undefine --remove-all-storage ...
rename OLD NEW [--rename-disks] Rename a shut-off VM; optionally rename disk files whose names contain the old name and update the XML domrename, mv, virsh define
mem VM SIZE Set max and current memory persistently (8G, 4096M); applies on next boot setmaxmem + setmem --config
vcpus VM N Set max and current vCPUs persistently setvcpus --maximum --config + --config
backup-xml VM [-o FILE] Save the domain XML to a timestamped file virsh dumpxml
lint FILE Validate a domain XML file xmllint --noout, virt-xml-validate
os-variants [FILTER] Search valid --os-variant values osinfo-query os

create

kvm-adm create NAME [options]

Either --location (install) or --import (boot an existing image) is required.

Option Default Meaning
-m, --memory 2048 MiB
--vcpus 2 vCPU count
-d, --disk 20 New disk size in GiB (qcow2, created in images_dir, virtio)
--os-variant from config osinfo short id
--bridge B / --network N from config Attach to a host bridge or a libvirt network (mutually exclusive)
--mac generated Fixed MAC; must differ from the host's
-l, --location ISO path or URL tree
--kickstart URL Adds inst.sshd inst.ks=URL ip=dhcp to the installer arguments
--preseed URL Adds the Debian preseed arguments and hostname
--import DISK Boot an existing image (--import --noautoconsole)
--host-cpu off --cpu host-passthrough, needed for nested virtualization
--no-autostart off Skip --autostart
--description Stored in the domain XML

create always uses --graphics none with a serial console, so it suits Linux guests and installers that support text mode. For Windows or graphical installers, run virt-install directly (Create VMs).

kvm-adm create web01 -l ~/isos/rhel-9.iso --kickstart http://192.0.2.50:8000/ks.cfg --os-variant rhel9.0
kvm-adm create web02 -l ~/isos/debian-12.iso --preseed http://192.0.2.50:8000/preseed.cfg --disk 40 -m 4096
kvm-adm create web03 --import ./web03.qcow2 --bridge br0

disk

Command What it does
disk ls VM Targets and source files
disk create PATH SIZE [-f FORMAT] [--preallocate] Standalone image (qemu-img create)
disk add VM SIZE [-f FORMAT] [-t TARGET] [--name FILE] Create an image and attach it persistently; picks the next free vdX; passes --subdriver so qcow2 is not attached as raw
disk detach VM TARGET Detach (the file is kept)
disk resize VM TARGET SIZE Running VM: blockresize to an absolute size. Shut-off VM: qemu-img resize, where +10G also works. Prints the guest-side steps afterwards
disk info PATH / disk check PATH qemu-img info --backing-chain / qemu-img check
disk convert SRC DST [--from F] [--to F] [-z] qemu-img convert -p; -z compresses qcow2
disk sparsify PATH virt-sparsify --in-place (VM must be off)

See Resize a disk for the guest-side half of a resize.

net

Command What it does
net ls List networks
net leases [--network N] [-w] DHCP leases; -w refreshes every second
net ensure-default Define, autostart and start the default NAT network if missing
net ifaces VM List NICs
net add-iface VM [--bridge B \| --network N] [--mac M] Add a virtio NIC persistently, and live if the VM is running
net del-iface VM MAC [--type bridge\|network] Remove a NIC by MAC

snap

snap create VM NAME [-d DESC], snap ls VM, snap revert VM NAME [--running], snap delete VM NAME (asks first). See Snapshots.

image (offline, libguestfs)

Shut the VM down first. All image commands set LIBGUESTFS_BACKEND=direct (and TMPDIR from tmpdir), which avoids the two most common libguestfs failures (Troubleshooting).

Command What it does
image passwd IMAGE [--password-file F] Set the root password; random (and printed) unless a file is given
image install IMAGE PKG... [--selinux-relabel] Install packages
image edit IMAGE FILE EXPR Perl-expression edit of a file inside the image
image copy-in IMAGE LOCAL DESTDIR Copy a file or directory in
image ls IMAGE [PATH] / image cat IMAGE FILE Browse and read files
image sysprep IMAGE Strip host-specific state before using it as a template
image templates virt-builder --list
image build TEMPLATE [-o OUT] [--size 20G] [--ssh-key FILE] virt-builder to qcow2 with a random root password

pool, host, and maintenance

Command What it does
pool ls / pool info NAME List pools / show details
pool create-dir NAME PATH Define, build, start and autostart a directory pool; prints the SELinux labelling hint
host doctor Check required tools, CPU virtualization flag, /dev/kvm, libvirt connection
host validate virt-host-validate qemu
host nested Report whether nested virtualization is enabled and how to enable it
config Show effective configuration
update Reinstall from the newest kvm-adm-*.tar.gz in update_dir

Raw command equivalents

Task Raw command kvm-adm
List VMs virsh list --all kvm-adm ls
Start / stop / force off virsh start / shutdown / destroy kvm-adm start vm01, stop vm01, stop -f vm01
VM summary virsh dominfo + domblklist + domiflist kvm-adm info vm01
Find IP virsh domifaddr --source agent (or lease, arp) kvm-adm ip vm01
Create from ISO / kickstart virt-install ... --extra-args ... kvm-adm create vm01 -l os.iso --kickstart URL
Import an image virt-install --import kvm-adm create vm01 --import disk.qcow2
Clone virt-clone --auto-clone kvm-adm clone vm01 vm02
Delete with storage virsh undefine --remove-all-storage ... kvm-adm delete vm01
Rename (and disks) domrename, mv, virsh edit kvm-adm rename vm01 vm02 --rename-disks
Memory / vCPUs setmaxmem + setmem, setvcpus kvm-adm mem vm01 8G, kvm-adm vcpus vm01 4
Add disk qemu-img create + attach-disk --subdriver kvm-adm disk add vm01 10G
Resize disk blockresize / qemu-img resize kvm-adm disk resize vm01 vda 50G
Convert image qemu-img convert kvm-adm disk convert a.img b.qcow2 --from raw
Add / remove NIC attach-interface / detach-interface kvm-adm net add-iface vm01, net del-iface vm01 MAC
DHCP leases virsh net-dhcp-leases kvm-adm net leases --watch
Snapshots snapshot-create-as etc. kvm-adm snap create / ls / revert / delete
Storage pool pool-define-as + build/start/autostart kvm-adm pool create-dir NAME PATH
Root password in image virt-customize --root-password kvm-adm image passwd disk.qcow2
Install packages in image virt-customize --install kvm-adm image install disk.qcow2 vim tmux
Build from template virt-builder kvm-adm image build fedora-40
Host checks virt-host-validate, /sys/module/kvm_*/parameters/nested kvm-adm host doctor, host nested