Libvirt: Difference between revisions

Phobos (talk | contribs)
m Updated Formating
DHCP (talk | contribs)
m style fixes
 
(7 intermediate revisions by 6 users not shown)
Line 5: Line 5:
Enable libvirt daemon
Enable libvirt daemon


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


# Enable TPM emulation (optional)
# Enable TPM emulation (optional)
# install pkgs.swtpm system-wide for use in virt-manager (optional)
virtualisation.libvirtd.qemu = {
virtualisation.libvirtd.qemu = {
   swtpm.enable = true;
   swtpm.enable = true;
  ovmf.packages = [ pkgs.OVMFFull.fd ];
};
};


Line 17: Line 17:
virtualisation.spiceUSBRedirection.enable = true;
virtualisation.spiceUSBRedirection.enable = true;


</nowiki>}}
</nowiki>|name=/etc/nixos/configuration.nix|lang=nix}}


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
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>
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
Line 38: Line 38:


{{file|||<nowiki>
{{file|||<nowiki>
boot.extraModprobeConfig = "options kvm_intel nested=1";
boot.extraModprobeConfig = ''
  options kvm_intel nested=1
'';
</nowiki>|name=/etc/nixos/configuration.nix|lang=nix}}
</nowiki>|name=/etc/nixos/configuration.nix|lang=nix}}


Line 45: Line 47:
==== Default networking ====
==== Default networking ====


To utilize the default libvirt network, you will need to install the {{nixos:package|dnsmasq}} package. This is required for DNS and DCHP functionality within the network:
Enable and start the default network using the following commands:
 
{{File|3=environment.systemPackages = with pkgs; [
  dnsmasq
];|name=/etc/nixos/configuration.nix|lang=nix}}
 
Once the package is installed, enable and start the default network using the following commands:


<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
Line 58: Line 54:
</syntaxhighlight>
</syntaxhighlight>


This will configure the default network to start automatically on boot and immediately activate it.
This will configure the default network to start automatically on boot and immediately activate it. You may need to whitelist the interface for the firewall like so:
 
{{File|3=networking.firewall.trustedInterfaces = [ "virbr0" ];|name=/etc/nixos/configuration.nix|lang=nix}}


==== Bridge networking ====
==== Bridge networking ====
Line 64: Line 62:
Create a XML file called <code>virbr0.xml</code> with the definition of the bridge interface.
Create a XML file called <code>virbr0.xml</code> with the definition of the bridge interface.


<syntaxhighlight lang="bash">
<syntaxhighlight lang="xml">
<network>
<network>
   <name>virbr0</name>
   <name>virbr0</name>
Line 74: Line 72:
Add and enable bridge interface.
Add and enable bridge interface.


<syntaxhighlight lang="bash">
<syntaxhighlight lang="console">
virsh net-define virbr0.xml
# virsh net-define virbr0.xml
virsh net-start virbr0
# virsh net-start virbr0
ip link add virbr0 type bridge
# ip link add virbr0 type bridge
ip address ad dev virbr0 10.25.0.1/24
# ip address ad dev virbr0 10.25.0.1/24
ip link set dev virbr0 up
# ip link set dev virbr0 up
</syntaxhighlight>
</syntaxhighlight>


Edit the libvirt guest <code>my_guest</code> XML file and add the bridge interface to it.
Edit the libvirt guest <code>my_guest</code> XML file and add the bridge interface to it.


<syntaxhighlight lang="bash">
<syntaxhighlight lang="console">
virsh edit my_guest
$ virsh edit my_guest
</syntaxhighlight>
</syntaxhighlight>


Add:
Add:


<syntaxhighlight lang="bash">
<syntaxhighlight lang="xml">
  <devices>
<devices>
    [...]
  [...]
    <interface type='bridge'>
  <interface type='bridge'>
      <mac address='52:54:00:12:34:56'/>
    <mac address='52:54:00:12:34:56'/>
      <source bridge='virbr0'/>
    <source bridge='virbr0'/>
      <model type='virtio'/>
    <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </interface>
  </interface>
    [...]
  [...]
  </devices>
</devices>
</syntaxhighlight>
</syntaxhighlight>


Line 120: Line 118:
The host should now be able to reach the guest via the bridge interface and vice versa.
The host should now be able to reach the guest via the bridge interface and vice versa.


=== File sharing ===
=== File sharing via virtiofs mount ===
One of the best ways to share a host directory with the guest OS is with [https://virtio-fs.gitlab.io/ virtiofs]. On the host system, install the <code>virtiofsd</code> package:<syntaxhighlight lang="nix">
environment.systemPackages = with pkgs; [
  guestfs-tools
  virtiofsd
];
</syntaxhighlight>Next, a few sections of the XML must be edited, which can be done manually or via virt-manager in the guest configuration GUI. If using virt-manager, first navigate on the toolbar to Edit > Preferences > General, and click "Enable XML Editing". Next, open the virtual machine and under the hardware configuration, navigate to Memory and check the box "Enable shared memory". This will add an "access" block to the XML for you, similar to this:<syntaxhighlight lang="xml">
<memory unit="KiB">1638400</memory>
<currentMemory unit="KiB">1638400</currentMemory>
<memoryBacking>
  <source type="memfd"/>
  <access mode="shared"/>
</memoryBacking>
</syntaxhighlight>While still in the hardware configuration, click "Add Hardware" and select "Filesystem". For driver, select "virtiofs". For source path, input the folder on the host machine you wish to share, no trailing slash. For target path, don't put a path but instead a tag/label that is easily identifiable. It will be used in the mount options in the guest OS setup shortly. Once done, you should have a new Filesystem device configuration similar to this:<syntaxhighlight lang="xml">
<filesystem type="mount" accessmode="passthrough">
  <driver type="virtiofs"/>
  <binary path="/run/current-system/sw/bin/virtiofsd"/>
  <source dir="/media"/>
  <target dir="my_host_media_share"/>
  <alias name="fs0"/>
  <address type="pci" domain="0x0000" bus="0x07" slot="0x00" function="0x0"/>
</filesystem>
</syntaxhighlight>If your guest system is using NixOS, you can boot the system and add the new filesystem entry to auto-mount on boot and you're done:<syntaxhighlight lang="nix">
fileSystems."/media" = {
  device = "my_host_media_share";
  fsType = "virtiofs";
};
</syntaxhighlight>If the system fails to fully reboot after applying the changes, ensure the filesystem device matches the "Target path" in your XML exactly.
 
==== Error starting domain: internal error: Child process (/run/current-system/sw/bin/virtiofsd --print-capabilities) unexpected exit status 127: libvirt:  error : cannot execute binary /run/current-system/sw/bin/virtiofsd: No such file or directory ====
This error means virtiofsd was not installed on the host system. Ensure the system package was installed before making changes in virt-manager.
 
==== Error starting domain: operation failed: Unable to find a satisfying virtiofsd ====
The virtiofsd binary path needs to be specified in the filesystem configuration. virt-manager doesn't add this by default and instead assumes a default path that doesn't exist under NixOS. Open the guest machine's hardware details page, click on the passthrough filesystem created earlier, open the XML tab and inside the `<filesystem>...</filesystem>` add the following element to tell virtio where to find the virtiofsd binary:<syntaxhighlight lang="xml">
<binary path="/run/current-system/sw/bin/virtiofsd"/>
</syntaxhighlight>
 
=== File sharing via WebDAV ===


In order to share files between host and guest, one recommended way is to use <code>spice-webdavd</code>.
Another recommended way to share files between host and guest is to use <code>spice-webdavd</code>.


Shutdown the client, in this example named <code>my_guest</code>, and edit the libvirt XML file.
Shutdown the client, in this example named <code>my_guest</code>, and edit the libvirt XML file.


<syntaxhighlight lang="bash">
<syntaxhighlight lang="console">
virsh edit my_guest
$ virsh edit my_guest
</syntaxhighlight>
</syntaxhighlight>


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


<syntaxhighlight lang="bash">
<syntaxhighlight lang="xml">
    <channel type='spiceport'>
<channel type='spiceport'>
      <source channel='org.spice-space.webdav.0'/>
  <source channel='org.spice-space.webdav.0'/>
      <target type='virtio' name='org.spice-space.webdav.0'/>
  <target type='virtio' name='org.spice-space.webdav.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='3'/>
  <address type='virtio-serial' controller='0' bus='0' port='3'/>
    </channel>
</channel>
</syntaxhighlight>
</syntaxhighlight>


Line 148: Line 183:
List available shares for the guest.
List available shares for the guest.


<syntaxhighlight lang="bash">
<syntaxhighlight lang="console">
curl localhost:9843
$ curl localhost:9843
</syntaxhighlight>
</syntaxhighlight>


Line 196: Line 231:
   };
   };
}
}
</syntaxhighlight>Note that after you added the configuration and switch, you'll have the following command to setup the hooks.<syntaxhighlight lang="bash">
</syntaxhighlight>Note that after you added the configuration and switch, you'll have the following command to setup the hooks.<syntaxhighlight lang="console">
systemctl start libvirtd-config.service
$ systemctl start libvirtd-config.service
</syntaxhighlight>
</syntaxhighlight>


Line 213: Line 248:


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 ====
==== error: cannot find any suitable libguestfs supermin ====
Line 281: Line 314:


Also, I use letsencrypt dns mode to get https cert and key. Nginx i nixos can get the certs on its own. Since I use the same certs also for other things, I just put them in the root (/) folder. Use what is best for you.
Also, I use letsencrypt dns mode to get https cert and key. Nginx i nixos can get the certs on its own. Since I use the same certs also for other things, I just put them in the root (/) folder. Use what is best for you.


==== Get EyeOS Spice Web Client ====
==== Get EyeOS Spice Web Client ====