diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix index 748ef369bc1e..9206f0daa75d 100644 --- a/nixos/modules/virtualisation/libvirtd.nix +++ b/nixos/modules/virtualisation/libvirtd.nix @@ -1,5 +1,3 @@ -# Systemd services for libvirtd. - { config, lib, pkgs, ... }: with lib; @@ -16,71 +14,59 @@ let ${cfg.extraConfig} ''; -in +in { -{ ###### interface options = { - virtualisation.libvirtd.enable = - mkOption { - type = types.bool; - default = false; - description = - '' - This option enables libvirtd, a daemon that manages - virtual machines. Users in the "libvirtd" group can interact with - the daemon (e.g. to start or stop VMs) using the - virsh command line tool, among others. - ''; - }; + virtualisation.libvirtd.enable = mkOption { + type = types.bool; + default = false; + description = '' + This option enables libvirtd, a daemon that manages + virtual machines. Users in the "libvirtd" group can interact with + the daemon (e.g. to start or stop VMs) using the + virsh command line tool, among others. + ''; + }; - virtualisation.libvirtd.enableKVM = - mkOption { - type = types.bool; - default = true; - description = - '' - This option enables support for QEMU/KVM in libvirtd. - ''; - }; + virtualisation.libvirtd.enableKVM = mkOption { + type = types.bool; + default = true; + description = '' + This option enables support for QEMU/KVM in libvirtd. + ''; + }; - virtualisation.libvirtd.extraConfig = - mkOption { - type = types.lines; - default = ""; - description = - '' - Extra contents appended to the libvirtd configuration file, - libvirtd.conf. - ''; - }; + virtualisation.libvirtd.extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra contents appended to the libvirtd configuration file, + libvirtd.conf. + ''; + }; - virtualisation.libvirtd.extraOptions = - mkOption { - type = types.listOf types.str; - default = [ ]; - example = [ "--verbose" ]; - description = - '' - Extra command line arguments passed to libvirtd on startup. - ''; - }; - - virtualisation.libvirtd.onShutdown = - mkOption { - type = types.enum ["shutdown" "suspend" ]; - default = "suspend"; - description = - '' - When shutting down / restarting the host what method should - be used to gracefully halt the guests. Setting to "shutdown" - will cause an ACPI shutdown of each guest. "suspend" will - attempt to save the state of the guests ready to restore on boot. - ''; - }; + virtualisation.libvirtd.extraOptions = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "--verbose" ]; + description = '' + Extra command line arguments passed to libvirtd on startup. + ''; + }; + virtualisation.libvirtd.onShutdown = mkOption { + type = types.enum ["shutdown" "suspend" ]; + default = "suspend"; + description = '' + When shutting down / restarting the host what method should + be used to gracefully halt the guests. Setting to "shutdown" + will cause an ACPI shutdown of each guest. "suspend" will + attempt to save the state of the guests ready to restore on boot. + ''; + }; }; @@ -95,65 +81,66 @@ in boot.kernelModules = [ "tun" ]; - systemd.services.libvirtd = - { description = "Libvirt Virtual Machine Management Daemon"; + users.extraGroups.libvirtd.gid = config.ids.gids.libvirtd; - wantedBy = [ "multi-user.target" ]; - after = [ "systemd-udev-settle.service" ] - ++ optional vswitch.enable "vswitchd.service"; + systemd.services.libvirtd = { + description = "Libvirt Virtual Machine Management Daemon"; - path = [ - pkgs.bridge-utils - pkgs.dmidecode - pkgs.dnsmasq - pkgs.ebtables - ] - ++ optional cfg.enableKVM pkgs.qemu_kvm - ++ optional vswitch.enable vswitch.package; + wantedBy = [ "multi-user.target" ]; + after = [ "systemd-udev-settle.service" ] + ++ optional vswitch.enable "vswitchd.service"; - preStart = - '' - mkdir -p /var/log/libvirt/qemu -m 755 - rm -f /var/run/libvirtd.pid + path = [ + pkgs.bridge-utils + pkgs.dmidecode + pkgs.dnsmasq + pkgs.ebtables + ] + ++ optional cfg.enableKVM pkgs.qemu_kvm + ++ optional vswitch.enable vswitch.package; - mkdir -p /var/lib/libvirt - mkdir -p /var/lib/libvirt/dnsmasq + preStart = '' + mkdir -p /var/log/libvirt/qemu -m 755 + rm -f /var/run/libvirtd.pid - chmod 755 /var/lib/libvirt - chmod 755 /var/lib/libvirt/dnsmasq + mkdir -p /var/lib/libvirt + mkdir -p /var/lib/libvirt/dnsmasq - # Copy default libvirt network config .xml files to /var/lib - # Files modified by the user will not be overwritten - for i in $(cd ${pkgs.libvirt}/var/lib && echo \ - libvirt/qemu/networks/*.xml libvirt/qemu/networks/autostart/*.xml \ - libvirt/nwfilter/*.xml ); - do - mkdir -p /var/lib/$(dirname $i) -m 755 - cp -npd ${pkgs.libvirt}/var/lib/$i /var/lib/$i - done + chmod 755 /var/lib/libvirt + chmod 755 /var/lib/libvirt/dnsmasq - # libvirtd puts the full path of the emulator binary in the machine - # config file. But this path can unfortunately be garbage collected - # while still being used by the virtual machine. So update the - # emulator path on each startup to something valid (re-scan $PATH). - for file in /etc/libvirt/qemu/*.xml /etc/libvirt/lxc/*.xml; do - test -f "$file" || continue - # get (old) emulator path from config file - emulator=$(grep "^[[:space:]]*" "$file" | sed 's,^[[:space:]]*\(.*\).*,\1,') - # get a (definitely) working emulator path by re-scanning $PATH - new_emulator=$(PATH=${pkgs.libvirt}/libexec:$PATH command -v $(basename "$emulator")) - # write back - sed -i "s,^[[:space:]]*.*, $new_emulator ," "$file" - done - ''; # */ + # Copy default libvirt network config .xml files to /var/lib + # Files modified by the user will not be overwritten + for i in $(cd ${pkgs.libvirt}/var/lib && echo \ + libvirt/qemu/networks/*.xml libvirt/qemu/networks/autostart/*.xml \ + libvirt/nwfilter/*.xml ); + do + mkdir -p /var/lib/$(dirname $i) -m 755 + cp -npd ${pkgs.libvirt}/var/lib/$i /var/lib/$i + done - serviceConfig = { - ExecStart = ''@${pkgs.libvirt}/sbin/libvirtd libvirtd --config "${configFile}" --daemon ${concatStringsSep " " cfg.extraOptions}''; - Type = "notify"; - KillMode = "process"; # when stopping, leave the VMs alone - Restart = "on-failure"; - }; + # libvirtd puts the full path of the emulator binary in the machine + # config file. But this path can unfortunately be garbage collected + # while still being used by the virtual machine. So update the + # emulator path on each startup to something valid (re-scan $PATH). + for file in /etc/libvirt/qemu/*.xml /etc/libvirt/lxc/*.xml; do + test -f "$file" || continue + # get (old) emulator path from config file + emulator=$(grep "^[[:space:]]*" "$file" | sed 's,^[[:space:]]*\(.*\).*,\1,') + # get a (definitely) working emulator path by re-scanning $PATH + new_emulator=$(PATH=${pkgs.libvirt}/libexec:$PATH command -v $(basename "$emulator")) + # write back + sed -i "s,^[[:space:]]*.*, $new_emulator ," "$file" + done + ''; # */ + + serviceConfig = { + ExecStart = ''@${pkgs.libvirt}/sbin/libvirtd libvirtd --config "${configFile}" --daemon ${concatStringsSep " " cfg.extraOptions}''; + Type = "notify"; + KillMode = "process"; # when stopping, leave the VMs alone + Restart = "on-failure"; }; + }; systemd.sockets.virtlogd = { description = "Virtual machine log manager socket"; @@ -176,8 +163,5 @@ in description = "Virtual machine lock manager"; serviceConfig.ExecStart = "@${pkgs.libvirt}/sbin/virtlockd virtlockd"; }; - - users.extraGroups.libvirtd.gid = config.ids.gids.libvirtd; - }; }