Installer les agents invités QEMU/KVM et SPICE avec un module customConfig

Si vous faites tourner GLF OS dans une machine virtuelle, deux petits services changent radicalement le confort : l'agent invité de QEMU et l'agent SPICE. Sans eux, vous travaillez dans une fenêtre figée en 1024x768, sans presse-papiers commun, et l'hôte ne sait même pas quelle adresse IP a pris l'invité. Avec eux, la machine virtuelle se comporte presque comme une application.

:information_source: Remarque
Cet article fait partie d'une série sur les modules à importer dans customConfig. Si vous n'avez jamais édité ces fichiers, lisez d'abord Ajouter vos programmes et Configuration personnalisée.

:warning: Attention
Tout ce qui suit concerne l'invité, la machine virtuelle elle-même. À ne pas confondre avec virtualisation.libvirtd.enable, qui concerne l'hôte, celui qui fait tourner les machines virtuelles.


Ce que vous obtenez

  • le presse-papiers partagé entre l'hôte et l'invité, dans les deux sens ;
  • la définition d'écran qui suit la taille de la fenêtre ;
  • l'adresse IP de l'invité visible depuis l'hôte, et l'extinction propre depuis le gestionnaire ;
  • des instantanés cohérents, parce que l'agent gèle les écritures le temps de la photo.

Le fichier

Créez /etc/nixos/customConfig/invite-vm.nix :

{ pkgs, ... }:

{
  services.qemuGuest.enable = true;
  services.spice-vdagentd.enable = true;

  systemd.user.services.spice-vdagent = {
    description = "Client SPICE (presse-papiers partagé)";
    wantedBy = [ "graphical-session.target" ];
    partOf = [ "graphical-session.target" ];
    after = [ "graphical-session.target" ];
    serviceConfig = {
      Type = "simple";
      ExecStart = "${pkgs.spice-vdagent}/bin/spice-vdagent -x";
      Restart = "on-failure";
    };
  };

  boot.initrd.availableKernelModules = [
    "virtio_pci"
    "virtio_blk"
    "virtio_net"
    "virtio_scsi"
    "virtio_balloon"
  ];
}

Ce que fait chaque morceau

services.qemuGuest fait tourner qemu-ga, qui ouvre une ligne directe entre l'invité et l'hôte, par un canal virtuel et non par le réseau. Concrètement, cela vous donne :

  • l'adresse IP de l'invité affichée dans le gestionnaire de machines virtuelles, sans avoir à ouvrir une console pour la lire ;
  • l'extinction propre quand vous cliquez sur « arrêter » : l'hôte demande poliment au système de s'éteindre, au lieu de couper l'alimentation ;
  • le gel des écritures le temps d'un instantané, ce qui évite les sauvegardes prises au milieu d'une écriture.

Depuis l'hôte, vous pouvez en profiter directement :

virsh domifaddr --source agent ma-machine
virsh shutdown ma-machine

services.spice-vdagentd est le démon système de SPICE. À lui seul, il ne suffit pas. Le presse-papiers est une affaire de session graphique : il faut donc aussi un client dans votre session, et c'est le rôle du service utilisateur déclaré juste après. C'est le point qui bloque le plus de monde, car on active le démon, on ne voit rien venir, et rien n'explique pourquoi.

Le service utilisateur. systemd.user.services décrit un service qui tourne dans votre session, pas au niveau du système. Les trois lignes wantedBy, partOf et after l'attachent à graphical-session.target : il démarre quand votre bureau démarre et s'arrête avec lui.

L'option -x demande au client de passer par X11, c'est-à-dire XWayland quand votre session est en Wayland. C'est la forme qui fonctionne le mieux aujourd'hui avec GNOME.

Les modules virtio_* dans l'initrd. Ils garantissent que le disque et la carte réseau virtuels sont reconnus dès les premières secondes du démarrage, avant même que la racine soit montée. Sans eux, un invité peut rester bloqué très tôt, avec un message sur un périphérique introuvable.

:information_source: Remarque
Sur un système installé par nos soins dans une machine virtuelle, hardware-configuration.nix contient déjà les modules utiles. Les redéclarer ne coûte rien, les listes s'additionnent, et cela rend le module autonome si vous le recopiez ailleurs.


Activer le module

Dans /etc/nixos/customConfig/default.nix :

{
  imports = [ ./invite-vm.nix ];

  environment.systemPackages = [
  # Add your stable apps here (exemple: pkgs.btop)

Puis :

glf-update

Le service utilisateur ne démarre qu'à l'ouverture de session suivante. Déconnectez-vous et reconnectez-vous, puis vérifiez :

systemctl status qemu-guest-agent
systemctl --user status spice-vdagent

Essayez ensuite de copier un texte sur l'hôte et de le coller dans l'invité.


Le cas de la machine physique

:warning: Attention
Sur une machine physique, qemu-ga ne trouve pas son canal de communication : le service échoue au démarrage et systemd cesse de le relancer. Rien de grave, mais cela laisse une ligne rouge dans systemctl --failed, et une ligne rouge que l'on apprend à ignorer est une mauvaise habitude.

Si votre configuration sert aux deux mondes, par exemple parce que le même disque démarre en machine virtuelle et sur le matériel réel, ajoutez la condition qui va bien :

{
  systemd.services.qemu-guest-agent.unitConfig.ConditionVirtualization = "vm";
}

systemd saute alors le service quand il ne tourne pas dans une machine virtuelle, sans le marquer en échec.


Les options que vous pouvez changer

  • Partager un dossier avec l'hôte sans passer par le réseau :
    {
      services.spice-webdavd.enable = true;
    }
    
    Le dossier choisi côté hôte apparaît alors dans le gestionnaire de fichiers de l'invité. Pratique pour échanger quelques fichiers sans monter un partage réseau. Pour des échanges réguliers entre plusieurs machines, Samba reste plus adapté.
  • Suivre la taille de la fenêtre sous X11 :
    {
      services.spice-autorandr.enable = true;
    }
    
    Inutile sous Wayland, où le client s'en charge déjà.
  • Forcer une définition d'écran au démarrage, utile avec un affichage QXL qui s'obstine :
    {
      boot.kernelParams = [ "video=1920x1080" ];
    }
    
  • Choisir un meilleur affichage côté hôte. Sur une machine récente, préférez l'affichage virtio à QXL : l'accélération est meilleure et la définition suit la fenêtre sans intervention. Ce réglage se trouve dans les propriétés de la machine virtuelle, pas dans l'invité.
  • Le presse-papiers sous Wayland pur. Si vous n'utilisez pas XWayland du tout, retirez le -x et laissez le client choisir. Selon les versions, l'un ou l'autre fonctionne mieux, cela vaut la peine d'essayer les deux.

En cas de problème

  • Le presse-papiers ne passe pas. Vérifiez d'abord le client, pas le démon :
    systemctl --user status spice-vdagent
    
    Vérifiez ensuite que le canal existe côté invité :
    ls -l /dev/virtio-ports/
    
    Vous devez y voir com.redhat.spice.0. S'il manque, c'est côté hôte : la machine virtuelle n'a pas de canal SPICE déclaré dans ses périphériques.
  • La définition d'écran ne suit pas : l'affichage de la machine virtuelle n'est peut-être pas SPICE. Regardez les propriétés côté hôte, une console série ou un VNC simple ne permettent pas ce dialogue.
  • qemu-guest-agent en échec : soit vous êtes sur une machine physique, voyez la section plus haut, soit le canal org.qemu.guest_agent.0 manque dans la configuration de la machine virtuelle.
  • L'hôte ne montre pas l'adresse IP : l'agent n'est pas démarré, ou vous interrogez la mauvaise source. Précisez-la : virsh domifaddr --source agent.

Voir aussi