Files
homelab/active/software_virsh/virsh.md
ducoterra b97f41eb70
All checks were successful
Podman DDNS Image / build-and-push-ddns (push) Successful in 58s
fedora updates and systemd renames
2025-10-30 22:51:53 -04:00

7.3 KiB

Virsh

Virtual Machine Management

Before you Begin

  1. Add yourself to the qemu and libvirt groups: usermod -aG libvirt,qemu ducoterra
  2. Change the images ownership to qemu: chown -R qemu:qemu /var/lib/libvirt/images
  3. Change the iso ownership to qemu: chown -R qemu:qemu /var/lib/libvirt/iso
  4. Allow group write access to images: chmod 770 /var/lib/libvirt/images
  5. Allow group write access to iso: chmod 770 /var/lib/libvirt/iso
  6. Tell virsh to connect to your root system rather than your user: export LIBVIRT_DEFAULT_URI='qemu:///system'
  7. Export your editor so virsh knows what to use: export EDITOR=vim

Useful Virsh Commands

# Show node info
virsh nodeinfo

# List OS variants
osinfo-query os

# List all current machines
virsh list --all

# Connect to console VM
virsh console fedora42-test

# Connect to graphical VM
virt-viewer --wait fedora42-test

# Get leased IP Addresses for the default network
virsh net-dhcp-leases default

# Reboot a VM
virsh reboot <domain>

# Shutdown a VM
virsh shutdown <domain>

# Force shutdown a VM
virsh destroy <domain>

# Remove a VM
virsh undefine <domain>

# Remove a VM including storage
virsh undefine <domain> --remove-all-storage

Virsh Networking

Create a Virtual Network

Creating a new network will require an XML configuration file. To see the default network's configuration, use

virsh net-dumpxml default > virbr0.xml

To create a dual-stack network, use the following. (Note, I generated a unique local ipv6 address here).

<network>
  <name>dual-stack</name>
  <forward mode="nat"/>
  <domain name="dual-stack"/>
  <ip address="192.168.100.1" netmask="255.255.255.0">
    <dhcp>
      <range start="192.168.100.2" end="192.168.100.254"/>
    </dhcp>
  </ip>
  <ip family="ipv6" address="fd4d:58e7:17f6:1::1" prefix="64"/>
</network>

I've already defined this network in active/software_virsh/dual-stack-dhcp.xml. Install it with

# Define and autostart the network
virsh net-define active/software_virsh/dual-stack-dhcp.xml
virsh net-start dual-stack-dhcp
virsh net-autostart dual-stack-dhcp

# List networks to ensure it created
virsh net-list --all

# Get the UUID of the created network
virsh net-uuid dual-stack-dhcp

Attach a New Virtual Network

export VM_NAME=my_vm
virsh attach-interface \
--type bridge \
--source virbr1 \
--model virtio \
--config \
--live \
--domain ${VM_NAME}

Set a Static IP

To set a static IP, run virsh net-edit default and add the following between <dhcp> and </dhcp>

<host mac='xx:xx:0x:xx:xx:1x' name='virtual_machine' ip='1xx.1xx.1xx.xx'/>

Then run

# `--location /path/to/image.iso` supplies a disk installer. (Remove `--import`)
# `--import` skips the installation process.
# `--graphics spice --video qxl --channel spicevmc` installs graphics
# `--console pty,target.type=virtio` adds a console connection
# For any command, use `virt-install --arg=?` to see all available options
virsh net-destroy default
virsh net-start default
virsh shutdown virtual_machine
systemctl restart libvirtd
virsh start virtual_machine

Creating VMs

If you have an osbuild image you can run the following to generate a qcow2 disk image. Then you can create a VM with an existing qcow2 disk and skip the installation process altogether.

sudo systemctl start osbuild-composer.socket
composer-cli compose list
composer-cli compose image --filename /var/lib/libvirt/images/fedora-42-test.qcow2 image-uuid

Create VM with No Graphics and use an Existing QCOW2 Disk

# Start the  default network if it isn't already
virsh net-start --network default

# `--location /path/to/image.iso` supplies a disk installer. (Remove `--import`)
# `--import` skips the installation process.
# `--graphics spice --video qxl --channel spicevmc` installs graphics
# `--console pty,target.type=virtio` adds a console connection
# For any command, use `virt-install --arg=?` to see all available options
export VM_NAME="fedora42-test"
export VM_DESCRIPTION="Test VM with Fedora42"
export VM_DISK_PATH="/var/lib/libvirt/images/fedora-42-test.qcow2"
virt-install \
--name "${VM_NAME}" \
--description "${DESCRIPTION}" \
--boot uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no \
--cpu host-passthrough --vcpus sockets=1,cores=8,threads=2 \
--ram=8192 \
--os-variant=fedora41 \
--network bridge:virbr0 \
--graphics none \
--console pty,target.type=virtio \
--import --disk "path=${VM_DISK_PATH},bus=virtio"

Create VM with Graphics using an ISO Installation Disk

# `--cdrom /path/to/image.iso` supplies a disk installer. (Remove `--import`)
# `--import` skips the installation process.
# `--graphics spice --video qxl --channel spicevmc` installs graphics
# `--console pty,target.type=virtio` adds a console connection
# For any command, use `virt-install --arg=?` to see all available options
export VM_NAME="fedora43-kinoite-test"
export VM_DESCRIPTION="Test VM with Fedora43 Kinoite"
export VM_DISK_PATH="/var/lib/libvirt/images/fedora-43-kinoite.qcow2"
export VM_ISO_PATH="/var/lib/libvirt/iso/Fedora-Kinoite-ostree-x86_64-43-1.6.iso"
virt-install \
--name "${VM_NAME}" \
--description "${DESCRIPTION}" \
--boot uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no \
--cpu host-passthrough --vcpus sockets=1,cores=8,threads=2 \
--ram=8192 \
--os-variant=fedora41 \
--network bridge:virbr0 \
--graphics spice --video qxl --channel spicevmc \
--cdrom ${VM_ISO_PATH} \
--disk "path=${VM_DISK_PATH},size=64,bus=virtio,format=qcow2"

Create VM using Host Device as Disk

# `--cdrom /path/to/image.iso` supplies a disk installer. (Remove `--import`)
# `--import` skips the installation process.
# `--graphics spice --video qxl --channel spicevmc` installs graphics
# `--console pty,target.type=virtio` adds a console connection
# `--hostdev 0x1234:0x5678` adds a block storage device
# For any command, use `virt-install --arg=?` to see all available options
export VM_NAME="usb-linux"
export VM_DESCRIPTION="Linux running 0x13fe:0x6500 as the boot drive"
virt-install \
--name "${VM_NAME}" \
--description "${DESCRIPTION}" \
--boot uefi,firmware.feature0.name=secure-boot,firmware.feature0.enabled=no \
--import \
--cpu host-passthrough --vcpus sockets=1,cores=8,threads=2 \
--ram=8192 \
--os-variant=fedora41 \
--network bridge:virbr0 \
--graphics spice --video qxl --channel spicevmc \
--hostdev 0x13fe:0x6500,boot.order=1 \
--disk none

Snapshots

See qemu qcow2 snapshots