Commit a9822fa2 authored by Julian Stecklina's avatar Julian Stecklina
Browse files

nixos/virtualbox-host: expose option to run with KVM

parent 7dd125e9
Loading
Loading
Loading
Loading
+44 −7
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ let
  cfg = config.virtualisation.virtualbox.host;

  virtualbox = cfg.package.override {
    inherit (cfg) enableHardening headless enableWebService;
    inherit (cfg) enableHardening headless enableWebService enableKvm;
    extensionPack = if cfg.enableExtensionPack then pkgs.virtualboxExtpack else null;
  };

@@ -81,13 +81,24 @@ in
        Build VirtualBox web service tool (vboxwebsrv) to allow managing VMs via other webpage frontend tools. Useful for headless servers.
      '';
    };

    enableKvm = mkOption {
      type = types.bool;
      default = false;
      description = lib.mdDoc ''
        Enable KVM support for VirtualBox. This increases compatibility with Linux kernel versions, because the VirtualBox kernel modules
        are not required.

        This option is incompatible with `enableHardening` and `addNetworkInterface`.

        Note: This is experimental. Please check https://github.com/cyberus-technology/virtualbox-kvm/issues.
      '';
    };
  };

  config = mkIf cfg.enable (mkMerge [{
    warnings = mkIf (pkgs.config.virtualbox.enableExtensionPack or false)
      ["'nixpkgs.virtualbox.enableExtensionPack' has no effect, please use 'virtualisation.virtualbox.host.enableExtensionPack'"];
    boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ];
    boot.extraModulePackages = [ kernelModules ];
    environment.systemPackages = [ virtualbox ];

    security.wrappers = let
@@ -114,17 +125,43 @@ in

    services.udev.extraRules =
      ''
        KERNEL=="vboxdrv",    OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
        KERNEL=="vboxdrvu",   OWNER="root", GROUP="root",      MODE="0666", TAG+="systemd"
        KERNEL=="vboxnetctl", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
        SUBSYSTEM=="usb_device", ACTION=="add", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
        SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh $major $minor $attr{bDeviceClass}"
        SUBSYSTEM=="usb_device", ACTION=="remove", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
        SUBSYSTEM=="usb", ACTION=="remove", ENV{DEVTYPE}=="usb_device", RUN+="${virtualbox}/libexec/virtualbox/VBoxCreateUSBNode.sh --remove $major $minor"
      '';
  } (mkIf cfg.enableKvm {
    assertions = [
      {
        assertion = !cfg.addNetworkInterface;
        message = "VirtualBox KVM only supports standard NAT networking for VMs. Please turn off virtualisation.virtualbox.host.addNetworkInferface.";
      }

      {
        assertion = !cfg.enableHardening;
        message = "VirtualBox KVM is not compatible with hardening: Please turn off virtualisation.virtualbox.host.enableHardening.";
      }
    ];

    warnings = [
      ''
        KVM support in VirtualBox is experimental. Not all security features are available yet.
        See: https://github.com/cyberus-technology/virtualbox-kvm/issues/12
      ''
    ];
  }) (mkIf (!cfg.enableKvm) {
    boot.kernelModules = [ "vboxdrv" "vboxnetadp" "vboxnetflt" ];
    boot.extraModulePackages = [ kernelModules ];

    services.udev.extraRules =
      ''
        KERNEL=="vboxdrv",    OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
        KERNEL=="vboxdrvu",   OWNER="root", GROUP="root",      MODE="0666", TAG+="systemd"
        KERNEL=="vboxnetctl", OWNER="root", GROUP="vboxusers", MODE="0660", TAG+="systemd"
     '';

    # Since we lack the right setuid/setcap binaries, set up a host-only network by default.
  } (mkIf cfg.addNetworkInterface {
  }) (mkIf cfg.addNetworkInterface {
    systemd.services.vboxnet0 =
      { description = "VirtualBox vboxnet0 Interface";
        requires = [ "dev-vboxnetctl.device" ];