Libvirt: Difference between revisions

imported>IgorM
m Fixed syntax highlighting
Added a note for why you won't find hooks files after switching.
 
(27 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{DISPLAYTITLE:{{#if:{{NAMESPACE}}|{{NAMESPACE}}:|}}{{lcfirst:{{PAGENAME}}}}}}
[https://libvirt.org libvirt] is a toolkit to interact with the virtualization capabilities of recent versions of Linux (and other OSes). It does so by providing a common API to different virtualization backends.
{{expansion|Only a superficial look is provided.}}


libvirt is a toolkit to interact with the virtualization capabilities of recent versions of Linux (and other OSes). It does so by providing a common API to different virtualization backends.
== Setup ==


Using the {{nixos:option|virtualisation.libvirtd}} options, libvirtd can be enabled on a NixOS machine.
Enable libvirt daemon


== Backends ==
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
virtualisation.libvirtd.enable = true;


=== QEMU/KVM ===
# Enable TPM emulation (optional)
virtualisation.libvirtd.qemu = {
  swtpm.enable = true;
  ovmf.packages = [ pkgs.OVMFFull.fd ];
};
 
# Enable USB redirection (optional)
virtualisation.spiceUSBRedirection.enable = true;
 
</nowiki>}}
 
To enable local user access to libvirt, for example by using <code>virt-manager</code> or <code>gnome-boxes</code>, add yourself to the <code>libvirtd</code> group
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
users.users.myuser = {
  extraGroups = [ "libvirtd" ];
};
</nowiki>}}
 
== Configuration ==
 
=== UEFI with OVMF ===
 
See [https://ostechnix.com/enable-uefi-support-for-kvm-virtual-machines-in-linux/ this tutorial] on how to run a guest machine in UEFI mode using <code>virt-manager</code>.


This backend works and is enabled by default. To use <code>virt-manager</code> with your user, locally and via SSH, it will be necessary to add yourself to the <code>libvirtd</code> group.
=== Nested virtualization ===


If you would like to enable nested virtualization for your guests to run KVM hypervisors inside them, you should enable it as follows:  {{nixos:option|boot.extraModprobeConfig}}, for example:
If you would like to enable nested virtualization for your guests to run KVM hypervisors inside them, you should enable it as follows:  {{nixos:option|boot.extraModprobeConfig}}, for example:


<syntaxhighlight lang="nix">
{{file|/etc/nixos/configuration.nix|xml|<nowiki>
boot.extraModprobeConfig = "options kvm_intel nested=1";
boot.extraModprobeConfig = "options kvm_intel nested=1";
</nowiki>}}
=== Bridge networking ===
Create a XML file called <code>virbr0.xml</code> with the definition of the bridge interface
<syntaxhighlight lang="bash">
<network>
  <name>virbr0</name>
  <forward mode='bridge'/>
  <bridge name='virbr0'/>
</network>
</syntaxhighlight>
Add and enable bridge interface
<syntaxhighlight lang="bash">
virsh net-define virbr0.xml
virsh net-start virbr0
ip link add virbr0 type bridge
ip address ad dev virbr0 10.25.0.1/24
ip link set dev virbr0 up
</syntaxhighlight>
Edit the libvirt guest <code>my_guest</code> XML file and add the bridge interface to it
<syntaxhighlight lang="bash">
virsh edit my_guest
</syntaxhighlight>
Add
<syntaxhighlight lang="bash">
  <devices>
    [...]
    <interface type='bridge'>
      <mac address='52:54:00:12:34:56'/>
      <source bridge='virbr0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </interface>
    [...]
  </devices>
</syntaxhighlight>
Inside the guest configure networking for the interface <code>enp1s0</code> (name might differ)
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
networking.interfaces.enp1s0 = {
  ipv4.addresses = [{
    address = "10.25.0.2";
    prefixLength = 24;
  }];
  defaultGateway = {
    address = "10.25.0.1";
    interface = "ens1s0";
  };
};
</nowiki>}}
The host should now be able to reach the guest via the bridge interface and vice versa.
=== File sharing ===
In order to share files between host and guest, one recommended way of doing this is to use <code>spice-webdavd</code>.
Shutdown the client, in this example named <code>my_guest</code>, and edit the libvirt XML file.
<syntaxhighlight lang="bash">
virsh edit my_guest
</syntaxhighlight>
</syntaxhighlight>


=== QEMU/KVM User session ===
Add the following snippet after <code><channel type='unix'>[...]</channel></code> part inside the devices subsection:


==== Enable UEFI with OVMF ====
<syntaxhighlight lang="bash">
    <channel type='spiceport'>
      <source channel='org.spice-space.webdav.0'/>
      <target type='virtio' name='org.spice-space.webdav.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='3'/>
    </channel>
</syntaxhighlight>
 
Start the guest machine. Inside the guest, add following part to your system configuration and apply it
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
services.spice-webdavd.enable = true;
</nowiki>}}


Add the following line to <code>$XDG_CONFIG_HOME/libvirt/qemu.conf</code>:
List available shares for the guest
<syntaxhighlight lang=bash>
 
# Adapted from /var/lib/libvirt/qemu.conf
<syntaxhighlight lang="bash">
# Note that AAVMF and OVMF are for Aarch64 and x86 respectively
curl localhost:9843
nvram = [ "/run/libvirt/nix-ovmf/AAVMF_CODE.fd:/run/libvirt/nix-ovmf/AAVMF_VARS.fd", "/run/libvirt/nix-ovmf/OVMF_CODE.fd:/run/libvirt/nix-ovmf/OVMF_VARS.fd" ]
</syntaxhighlight>
</syntaxhighlight>


== Tools ==
Mount an example share called <code>myshare</code> to the mountpoint <code>myshare</code>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
services.davfs2 = {
  enable = true;
  settings.globalSection.ask_auth = 0;
};
 
fileSystems = {
  "/root/myshare" = {
    device = "http://localhost:9843/myshare";
    fsType = "davfs";
    options = [ "nofail" ];
  };
};
</nowiki>}}
 
=== Hooks ===
Libvirt allows the use of hooks to run custom scripts during specific events, such as daemon lifecycle events, domain lifecycle events, and network events. On NixOS, you can configure hooks via the NixOS module to automate the placement of hook scripts in the appropriate directories.
 
The following directories are used for placing hook scripts:
 
* '''<code>/var/lib/libvirt/hooks/daemon.d/</code>'''  Scripts here are triggered by daemon events like start, shutdown, and SIGHUP.
* '''<code>/var/lib/libvirt/hooks/qemu.d/</code>'''  Scripts for handling QEMU domain events such as begin, end, and migration.
* '''<code>/var/lib/libvirt/hooks/lxc.d/</code>'''  Scripts for LXC container events like begin and end.
* '''<code>/var/lib/libvirt/hooks/libxl.d/</code>'''  Scripts for Xen domains managed by <code>libxl</code> (begin/end events).
* '''<code>/var/lib/libvirt/hooks/network.d/</code>'''  Scripts triggered by network events such as begin and end.
 
See the [https://libvirt.org/hooks.html libvirt documentation] for more information.
 
An example config would be:<syntaxhighlight lang="nix">
{
  virtualisation.libvirtd.hooks = {
    daemon = {
      "example" = ./scripts/daemon-example.sh;
    };
    qemu = {
      "example" = ./scripts/qemu-example.sh;
    };
    network = {
      "example" = ./scripts/network-example.sh;
    };
  };
}
</syntaxhighlight>Note that after you added the configuration and switch, you'll have the following command to setup the hooks.<syntaxhighlight lang="bash">
systemctl start libvirtd-config.service
</syntaxhighlight>
 
== Clients ==


NixOS provides some packages that can make use of libvirt or are useful with libvirt.
NixOS provides some packages that can make use of libvirt or are useful with libvirt.
Line 38: Line 190:


Following are notes regarding the use of some of those tools
Following are notes regarding the use of some of those tools
==== error: cannot find any suitable libguestfs supermin ====
Use use the package libguestfs-with-appliance. See https://github.com/NixOS/nixpkgs/issues/37540
=== guestfs-tools ===
Includes virt-sysprep, used to prepare a VM image for use.  Review the manpage of virt-sysprep, virt-clone, and virt-builder.


==== <code>virt-builder</code> ====
==== <code>virt-builder</code> ====


virt-builder is installed with <code>libguestfs</code>, but has some issues from its packaging.
virt-builder is installed with <code>guestfs-tools</code>, but has some issues from its packaging.


It is possible to work around those issues without modifying the package (when a pristine nixpkgs is needed).
It is possible to work around those issues without modifying the package (when a pristine nixpkgs is needed).
Line 54: Line 216:


This will make your user use the shipped repo configurations, and works around the fact that virt-builder reads its executable name to build its configuration path. The executable being wrapped, it is named differently.
This will make your user use the shipped repo configurations, and works around the fact that virt-builder reads its executable name to build its configuration path. The executable being wrapped, it is named differently.
[[Category:Virtualization]]
==== error: cannot find any suitable libguestfs supermin ====
Use use the package libguestfs-with-appliance. See https://github.com/NixOS/nixpkgs/issues/37540


=== guestfs-tools ===
=== NixVirt ===


Includes virt-sysprep, used to prepare a VM image for use.  Review the manpage of virt-sysprep, virt-clone, and virt-builder.
[https://github.com/AshleyYakeley/NixVirt NixVirt] is a flake that provides NixOS and Home Manager modules for setting up libvirt domains, networks and pools declaratively.


=== Accessing QEMU VMs through Webbrowser ===
=== Accessing QEMU VMs through Webbrowser ===
Line 105: Line 262:
==== Get EyeOS Spice Web Client ====
==== Get EyeOS Spice Web Client ====


As said, the experience with the EyeOS Spice Web Client has been the best so far. Another client would be the [https://cgit.freedesktop.org/spice/spice-html5/ spice-html5] from freedesktop.org.
As said, the experience with the EyeOS Spice Web Client has been the best so far. Another client would be the [https://gitlab.freedesktop.org/spice/spice-html5/ spice-html5] from freedesktop.org.


1. Download the [https://github.com/eyeos/spice-web-client/ EyeOS Spice Web Client] and unpack it (if necessary) or , as example, just <code>git clone https://github.com/eyeos/spice-web-client/ /var/www/spice</code>
1. Download the [https://github.com/eyeos/spice-web-client/ EyeOS Spice Web Client] and unpack it (if necessary) or , as example, just <code>git clone https://github.com/eyeos/spice-web-client/ /var/www/spice</code>
Line 148: Line 305:


And finally you can access the VMs GUI through <code>https://mydomain.tld:4500/spice/index.html?host=mydomain.tld&port=5959</code>
And finally you can access the VMs GUI through <code>https://mydomain.tld:4500/spice/index.html?host=mydomain.tld&port=5959</code>
[[Category:Virtualization]]
[[Category:Applications]]