Package: libvirt-instance
libvirt-instancelibvirt-instanceis a CLI tool for creating virtual machines. It uses the
Libvirt API, and is compatible with other Libvirt applications.Think of it as a more opinionated alternative tovirt-install.Project goalsMake creating Libvirt virtual machines (VMs) via the command-line interface
simpler for human operators, by providing a way to group some commonly-used
configurations as presets.Provide a convenient way to deploy cloud instances on Libvirt without the
need for a metadata service (theNoClouddata source is used to provide metadata to instances).The tool does not support deleting Libvirt resources, and there are no plans to
implement that so far. Any delete operations can be performed usingvirsh.InstallationThis package depends onlibvirt-python. Installing into a virtualenv might
require GCC, Python3 and Libvirt development OS packages to be installed.
Rundnf --enablerepo=devel install gcc python3-devel libvirt-develto install
those packages if you're using RockyLinux 9.Otherwise (when not using virtualenv), having thepython3-libvirtOS package
installed should be sufficient.libvirt-instancecan be installed by runningpip3 install libvirt-instance.
It requires Python 3.9+ to run.ShowcaseWhile both local and remote Libvirt daemons are supported, the following example
is using a local Libvirt daemon for sake of simplicity. The commands should be
executed by a user who has sufficient Libvirt access privileges.URI=qemu:///system# All operations on disks are done using the Libvirt pool APIs.# Libvirt doesn't usually come with any storage pools defined, so let's define# one named "images".virsh-c"$URI"pool-define-asimagesdir--target/var/lib/libvirt/images
virsh-c"$URI"pool-autostartimages
virsh-c"$URI"pool-startimages# Create a config file with a preset for disks from the above pool,# and a preset for network interfaces in the default Libvirt NAT network (this# network exists by default).cat<<"EOF">./libvirt-instance-config.yaml
preset:disk:local:type:volumepool:imagesbus:virtiocache:noneinterface:nat:type:networkmodel-type:virtionetwork:default
EOF# Fetch a cloud image from the Internet and upload it to Libvirt as a volume,# so we can use it as the base image for VM disks.curl-LfsS\https://download.fedoraproject.org/pub/fedora/linux/releases/37/Cloud/x86_64/images/Fedora-Cloud-Base-37-1.7.x86_64.raw.xz\|xzcat>./f37-cloud-amd64.rawimage_size=$(stat--printf="%s"./f37-cloud-amd64.raw)virsh-c"$URI"vol-create-asimagesf37-cloud-amd64.raw"${image_size}b"--formatraw
virsh-c"$URI"vol-uploadf37-cloud-amd64.raw./f37-cloud-amd64.raw--poolimages# Generate a passphraseless SSH key for this demo.ssh-keygen-fmykey-N''# Create user-data.cat<<EOF >./user-data#cloud-configssh_authorized_keys:- $(cat ./mykey.pub)packages:- nginxruncmd:- systemctl start nginxEOF# Create network-config.cat<<"EOF">./network-config
version:2ethernets:eth0:dhcp4:falsedhcp6:falseaddresses:-192.168.122.10/24gateway4:192.168.122.1nameservers:addresses:-1.1.1.1-8.8.8.8
EOF# Create the VM.# headless-server-x86_64 is a built-in domain preset.instance_id=$(libvirt-instance-c"$URI"--config-file./libvirt-instance-config.yamlcreate\--domain-presetheadless-server-x86_64\--memory2GiB\--vcpu2\--disklocal,5GiB,source=f37-cloud-amd64.raw\--nicnat\--cloud-seed-disk=local\--cloud-user-data-file./user-data\--cloud-network-config-file./network-config\myvm\|jq-er'."instance-id"')# Start the VM.virsh-c"$URI"start"$instance_id"# Wait until cloud-init has finished executing.untilssh-imykey\-oIdentitiesOnly=true\-oStrictHostKeyChecking=no\-oUserKnownHostsFile=/dev/null\fedora@192.168.122.10\cloud-initstatus--waitdosleep1done# Get a page from Nginx on the VM.curlhttp://192.168.122.10/# Cleanup.virsh-c"$URI"destroy"$instance_id"virsh-c"$URI"undefine"$instance_id"--nvram--remove-all-storageMore examplesCreating non-image-based VMs is also an option.VM with two disks and the PXE boot as the first optionlibvirt-instance-c"$URI"--config-file./libvirt-instance-config.yamlcreate\--domain-presetheadless-server-x86_64\--memory2GiB\--vcpu2\--disklocal,5GiB,boot-order=2\--disklocal,10GiB\--nicnat,boot-order=1\myvmAlternative/non-native architectures are also supported.libvirt-instancecomes
with two built-in domain presets -headless-server-x86_64andheadless-server-aarch64. More presets can be defined in a config file.Runlibvirt-instance get-configto see the currently-defined presets.VM with encrypted diskscat<<EOF >./secret.xml<secret ephemeral='no' private='yes'><uuid>8eb167eb-b3bb-4047-91f4-a3ca1eb643ab</uuid></secret>EOFvirsh-c"$URI"secret-define./secret.xml

virsh-c"$URI"secret-set-value8eb167eb-b3bb-4047-91f4-a3ca1eb643ab--interactive# Enter new value for secret:# encryption-secret could also be specified in a preset in libvirt-instance-config.yaml.libvirt-instance-c"$URI"--config-file./libvirt-instance-config.yamlcreate\--domain-presetheadless-server-x86_64\--memory2GiB\--vcpu2\--disklocal,5GiB,encryption-secret=8eb167eb-b3bb-4047-91f4-a3ca1eb643ab\--disklocal,10GiB,encryption-secret=8eb167eb-b3bb-4047-91f4-a3ca1eb643ab\--nicnat\myvmARM cloud image-based Fedora VM on a non-ARM KVM hostcurl-LfsS\https://download.fedoraproject.org/pub/fedora/linux/releases/37/Cloud/aarch64/images/Fedora-Cloud-Base-37-1.7.aarch64.raw.xz\|xzcat>./f37-cloud-arm64.rawimage_size=$(stat--printf="%s"./f37-cloud-arm64.raw)virsh-c"$URI"vol-create-asimagesf37-cloud-arm64.raw"${image_size}b"--formatraw
virsh-c"$URI"vol-uploadf37-cloud-arm64.raw./f37-cloud-arm64.raw--poolimages

libvirt-instance-c"$URI"--config-file./libvirt-instance-config.yamlcreate\--domain-presetheadless-server-aarch64\--cpu-modelcortex-a57\--domain-typeqemu\--memory2GiB\--vcpu2\--disklocal,5GiB,source=f37-cloud-arm64.raw\--nicnat\--cloud-seed-disk=local\--cloud-user-data-file./user-data\--cloud-network-config-file./network-config\myvmConfiguration fileSome defaults and presets are already built in. Configuration file is a way to
add more presets, or override existing presets and settings.Three types of presets are currently supported:domain,disk, andinterface.The default location of the config file is/etc/libvirt-instance-config.yaml.
The--config-fileCLI argument provides a way to override that.Runlibvirt-instance get-configto see the current config.Domain presetsExample config snippet:preset:domain:windows-server:arch-name:x86_64machine-type:pcxml-file:/path/to/windows-server-base.xmlThe above preset can be selected on the CLI using--domain-preset windows-serverwhen creating a new VM.arch-namecan be any arhitecture (e.g.x86_64,aarch64) supported by the
target host.machine-typecan be any machine type (e.g.pc,q35,virt) supported by
the chosen architecture.xml-filespecifies a file containing somedomain XMLused as the foundation for
the VM being created. The tool will fill in the architecture, domain and
machine type, CPU (count and model), memory size, network interface,
disk (including any necessary SCSI controllers) entries into the base XML
automatically using the information from presets and CLI arguments.Domain XML may alternatively be provided inline via thexmlkey.Disk presetsAll operations on disks are done using Libvirt pool APIs, so disk presets may
only reference Libvirt pools.Currentlydir,logical, andrbdpools are supported.Example config snippet:preset:disk:ceph-ssd:type:volumepool:ceph-rbd-ssdbus:scsicache:writebackceph-hdd:type:volumepool:ceph-rbdbus:virtiocache:writebacklocal-secure:type:volumepool:imagesbus:virtiocache:noneencryption-format:luksencryption-secret:8eb167eb-b3bb-4047-91f4-a3ca1eb643abencryption-cipher:aes-256-cbc-sha256encryption-ivgen:essiv-sha256x86worker:type:volumepool:imagesbus:virtiocache:nonesource:fedora37-cloud-amd64.rawsource-pool:ceph-rbdCLI examples for the above:--disk ceph-ssd,16GiB --disk ceph-hdd,1TiB,--disk x86worker,32GiB.The only supported value fortypeisvolumeat the moment.poolspecifies a target Libvirt pool for the volumes. This pool will also be
used to pull any information about volumes when adding disk devices to the
domain XML.bus(optional) is eithervirtiofor virtio-blk disks, orscsifor
virtio-scsi disks. Defaults tovirtio.cache(optional) specifies any disk cache mode supported by Libvirt.
defaults tonone.source(optional) specifies a Libvirt volume containing the base image for
disks.source-pool(optional) specifies the Libvirt pool for thesourceimage.
Defaults to the same value aspoolwhen not specified.boot-order(optional) sets the device position in the boot order.encryption-secret(optional) specified a Libvirt secret UUID, and enables
disk encryption when set.encryption-format(optional) sets encryption format (default isluks).encryption-cipher(optional) specifies encryption cipher details. Format
isname-size-mode-hash, for exampleaes-128-cbc-sha256.encryption-ivgen(optional) specifies the initialization vector generation
algorithm. Format isname-hash, for exampleessiv-sha256.SeeLibvirt Storage volume encryption XML format documentationfor more details about encryption parameters.In most cases, the resulting disk device description in the domain XML will be a
volume reference (<disk type="volume">). Some pool types (rbdfor instance)
do not support backing volume disks yet
(seedomain_conf.c#L29929-L29939.
When adding disks from such pools,libvirt-instancewill transparently inline
the disk definition into the domain XML using the information (MONs, auth)
from the pool.Interface presetsCurrentlybridgeandnetworktype interfaces are supported.Example config snippet:preset:interface:nat:type:networkmodel-type:virtionetwork:defaultdmz:type:bridgemodel-type:virtiobridge:br0storage:type:bridgemodel-type:virtiobridge:br1mtu:9000CLI examples for the above:--nic nat,--nic dmz --nic storage.model-type(optional) specifies any model type supported by Libvirt
(e.g.virtio,e1000,rtl8139, etc). Defaults tovirtio.networkspecifies the Libvirt network name fortype: networkinterfaces.bridgespecifies the name of an existing network bridge fortype: bridgeinterfaces.mtu(optional) sets the MTU on the host-side TAP interface.
Note, the MTU also needs to be configured inside the guest.boot-order(optional) sets the device position in the boot order.Technically,mac-address(optional) can also be specified in an interface
preset, but it makes more sense to specify any MAC addresses on the command line
(e.g.--nic nat,mac-address=00:11:22:33:44:55:66).CLI optionsSeelibvirt-instance --helpandlibvirt-instance create --helpfor the full
list of CLI options.
There are also some examples in the "Showcase" and "More examples" sections
illustrating how different options work together.--disk <SPEC>may be specified more than once to attach multiple disks to a
VM. Disks are created using the<VM-NAME>-disk<N>naming scheme. If a volume
with the same name already exists in the target pool -libvirt-instancewill
exit with an error.
Disks are attached to the instance in the same order as specified on the command
line.Thepool,bus,cache,source,source-pool, andboot-orderoptions
may be included in the disk spec, taking precedence over any corresponding
options from the chosen preset.
For example:--disk local,10GiB,bus=scsi,cache=writeback,source=jammy-server-cloudimg-amd64.img.--nic <SPEC>may also be specified more than once. Themac-address,model-type,network,bridge,mtu, andboot-orderoptions are supported
by--nic, similar to--diskoptions.--cloud-seed-diskenables the cloud-init support and is required when
either--cloud-user-data-fileor--cloud-network-config-filehave been
specified.
It works like--diskwithout the size part.--cloud-seed-diskspecifies
which disk preset to use when creating theNoCloudseed disk.
The naming pattern for the seed disk is<VM-NAME>-seed.
Example:--cloud-seed-disk local,bus=scsi.DevelopingSeeDEVELOPING.md