at 17.09-beta 6.3 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.virtualisation.libvirtd; 8 vswitch = config.virtualisation.vswitch; 9 configFile = pkgs.writeText "libvirtd.conf" '' 10 unix_sock_group = "libvirtd" 11 unix_sock_rw_perms = "0770" 12 auth_unix_ro = "none" 13 auth_unix_rw = "none" 14 ${cfg.extraConfig} 15 ''; 16 qemuConfigFile = pkgs.writeText "qemu.conf" '' 17 ${optionalString cfg.qemuOvmf '' 18 nvram = ["/run/libvirt/nix-ovmf/OVMF_CODE.fd:/run/libvirt/nix-ovmf/OVMF_VARS.fd"] 19 ''} 20 ${cfg.qemuVerbatimConfig} 21 ''; 22 23in { 24 25 ###### interface 26 27 options = { 28 29 virtualisation.libvirtd.enable = mkOption { 30 type = types.bool; 31 default = false; 32 description = '' 33 This option enables libvirtd, a daemon that manages 34 virtual machines. Users in the "libvirtd" group can interact with 35 the daemon (e.g. to start or stop VMs) using the 36 <command>virsh</command> command line tool, among others. 37 ''; 38 }; 39 40 virtualisation.libvirtd.enableKVM = mkOption { 41 type = types.bool; 42 default = true; 43 description = '' 44 This option enables support for QEMU/KVM in libvirtd. 45 ''; 46 }; 47 48 virtualisation.libvirtd.extraConfig = mkOption { 49 type = types.lines; 50 default = ""; 51 description = '' 52 Extra contents appended to the libvirtd configuration file, 53 libvirtd.conf. 54 ''; 55 }; 56 57 virtualisation.libvirtd.qemuVerbatimConfig = mkOption { 58 type = types.lines; 59 default = '' 60 namespaces = [] 61 ''; 62 description = '' 63 Contents written to the qemu configuration file, qemu.conf. 64 Make sure to include a proper namespace configuration when 65 supplying custom configuration. 66 ''; 67 }; 68 69 virtualisation.libvirtd.qemuOvmf = mkOption { 70 type = types.bool; 71 default = true; 72 description = '' 73 Allows libvirtd to take advantage of OVMF when creating new 74 QEMU VMs with UEFI boot. 75 ''; 76 }; 77 78 virtualisation.libvirtd.extraOptions = mkOption { 79 type = types.listOf types.str; 80 default = [ ]; 81 example = [ "--verbose" ]; 82 description = '' 83 Extra command line arguments passed to libvirtd on startup. 84 ''; 85 }; 86 87 virtualisation.libvirtd.onShutdown = mkOption { 88 type = types.enum ["shutdown" "suspend" ]; 89 default = "suspend"; 90 description = '' 91 When shutting down / restarting the host what method should 92 be used to gracefully halt the guests. Setting to "shutdown" 93 will cause an ACPI shutdown of each guest. "suspend" will 94 attempt to save the state of the guests ready to restore on boot. 95 ''; 96 }; 97 98 }; 99 100 101 ###### implementation 102 103 config = mkIf cfg.enable { 104 105 environment.systemPackages = with pkgs; [ libvirt netcat-openbsd qemu_kvm ]; 106 107 boot.kernelModules = [ "tun" ]; 108 109 users.extraGroups.libvirtd.gid = config.ids.gids.libvirtd; 110 111 systemd.packages = [ pkgs.libvirt ]; 112 113 systemd.services.libvirtd = { 114 description = "Libvirt Virtual Machine Management Daemon"; 115 116 wantedBy = [ "multi-user.target" ]; 117 after = [ "systemd-udev-settle.service" ] 118 ++ optional vswitch.enable "vswitchd.service"; 119 120 environment = { 121 LIBVIRTD_ARGS = ''--config "${configFile}" ${concatStringsSep " " cfg.extraOptions}''; 122 }; 123 124 path = with pkgs; [ 125 bridge-utils 126 dmidecode 127 dnsmasq 128 ebtables 129 ] 130 ++ optional vswitch.enable vswitch.package; 131 132 preStart = '' 133 mkdir -p /var/log/libvirt/qemu -m 755 134 rm -f /var/run/libvirtd.pid 135 136 mkdir -p /var/lib/libvirt 137 mkdir -p /var/lib/libvirt/dnsmasq 138 139 chmod 755 /var/lib/libvirt 140 chmod 755 /var/lib/libvirt/dnsmasq 141 142 # Copy default libvirt network config .xml files to /var/lib 143 # Files modified by the user will not be overwritten 144 for i in $(cd ${pkgs.libvirt}/var/lib && echo \ 145 libvirt/qemu/networks/*.xml libvirt/qemu/networks/autostart/*.xml \ 146 libvirt/nwfilter/*.xml ); 147 do 148 mkdir -p /var/lib/$(dirname $i) -m 755 149 cp -npd ${pkgs.libvirt}/var/lib/$i /var/lib/$i 150 done 151 152 # Copy generated qemu config to libvirt directory 153 cp -f ${qemuConfigFile} /var/lib/libvirt/qemu.conf 154 155 # stable (not GC'able as in /nix/store) paths for using in <emulator> section of xml configs 156 mkdir -p /run/libvirt/nix-emulators 157 ln -s --force ${pkgs.libvirt}/libexec/libvirt_lxc /run/libvirt/nix-emulators/ 158 ${optionalString pkgs.stdenv.isAarch64 "ln -s --force ${pkgs.qemu}/bin/qemu-system-aarch64 /run/libvirt/nix-emulators/"} 159 ${optionalString cfg.enableKVM "ln -s --force ${pkgs.qemu_kvm}/bin/qemu-kvm /run/libvirt/nix-emulators/"} 160 161 ${optionalString cfg.qemuOvmf '' 162 mkdir -p /run/libvirt/nix-ovmf 163 ln -s --force ${pkgs.OVMF.fd}/FV/OVMF_CODE.fd /run/libvirt/nix-ovmf/ 164 ln -s --force ${pkgs.OVMF.fd}/FV/OVMF_VARS.fd /run/libvirt/nix-ovmf/ 165 ''} 166 ''; 167 168 serviceConfig = { 169 Type = "notify"; 170 KillMode = "process"; # when stopping, leave the VMs alone 171 Restart = "no"; 172 }; 173 restartIfChanged = false; 174 }; 175 176 systemd.services.libvirt-guests = { 177 wantedBy = [ "multi-user.target" ]; 178 path = with pkgs; [ coreutils libvirt gawk ]; 179 restartIfChanged = false; 180 }; 181 182 systemd.sockets.virtlogd = { 183 description = "Virtual machine log manager socket"; 184 wantedBy = [ "sockets.target" ]; 185 listenStreams = [ "/run/libvirt/virtlogd-sock" ]; 186 }; 187 188 systemd.services.virtlogd = { 189 description = "Virtual machine log manager"; 190 serviceConfig.ExecStart = "@${pkgs.libvirt}/sbin/virtlogd virtlogd"; 191 restartIfChanged = false; 192 }; 193 194 systemd.sockets.virtlockd = { 195 description = "Virtual machine lock manager socket"; 196 wantedBy = [ "sockets.target" ]; 197 listenStreams = [ "/run/libvirt/virtlockd-sock" ]; 198 }; 199 200 systemd.services.virtlockd = { 201 description = "Virtual machine lock manager"; 202 serviceConfig.ExecStart = "@${pkgs.libvirt}/sbin/virtlockd virtlockd"; 203 restartIfChanged = false; 204 }; 205 }; 206}