commit
5cdb38bb16
4 changed files with 110 additions and 19 deletions
|
@ -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" ];
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
pkgs ? import ../.. { inherit system config; },
|
||||
debug ? false,
|
||||
enableUnfree ? false,
|
||||
enableKvm ? false,
|
||||
use64bitGuest ? true
|
||||
}:
|
||||
|
||||
|
@ -340,7 +341,7 @@ let
|
|||
testExtensionPack.vmFlags = enableExtensionPackVMFlags;
|
||||
};
|
||||
|
||||
mkVBoxTest = useExtensionPack: vms: name: testScript: makeTest {
|
||||
mkVBoxTest = vboxHostConfig: vms: name: testScript: makeTest {
|
||||
name = "virtualbox-${name}";
|
||||
|
||||
nodes.machine = { lib, config, ... }: {
|
||||
|
@ -349,14 +350,23 @@ let
|
|||
vmConfigs = mapAttrsToList mkVMConf vms;
|
||||
in [ ./common/user-account.nix ./common/x11.nix ] ++ vmConfigs;
|
||||
virtualisation.memorySize = 2048;
|
||||
virtualisation.qemu.options = ["-cpu" "kvm64,svm=on,vmx=on"];
|
||||
virtualisation.virtualbox.host.enable = true;
|
||||
|
||||
virtualisation.qemu.options = let
|
||||
# IvyBridge is reasonably ancient to be compatible with recent
|
||||
# Intel/AMD hosts and sufficient for the KVM flavor.
|
||||
guestCpu = if config.virtualisation.virtualbox.host.enableKvm then "IvyBridge" else "kvm64";
|
||||
in ["-cpu" "${guestCpu},svm=on,vmx=on"];
|
||||
|
||||
test-support.displayManager.auto.user = "alice";
|
||||
users.users.alice.extraGroups = let
|
||||
inherit (config.virtualisation.virtualbox.host) enableHardening;
|
||||
in lib.mkIf enableHardening (lib.singleton "vboxusers");
|
||||
virtualisation.virtualbox.host.enableExtensionPack = useExtensionPack;
|
||||
nixpkgs.config.allowUnfree = useExtensionPack;
|
||||
in lib.mkIf enableHardening [ "vboxusers" ];
|
||||
|
||||
virtualisation.virtualbox.host = {
|
||||
enable = true;
|
||||
} // vboxHostConfig;
|
||||
|
||||
nixpkgs.config.allowUnfree = config.virtualisation.virtualbox.host.enableExtensionPack;
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
|
@ -390,7 +400,7 @@ let
|
|||
};
|
||||
};
|
||||
|
||||
unfreeTests = mapAttrs (mkVBoxTest true vboxVMsWithExtpack) {
|
||||
unfreeTests = mapAttrs (mkVBoxTest { enableExtensionPack = true; } vboxVMsWithExtpack) {
|
||||
enable-extension-pack = ''
|
||||
create_vm_testExtensionPack()
|
||||
vbm("startvm testExtensionPack")
|
||||
|
@ -409,7 +419,24 @@ let
|
|||
'';
|
||||
};
|
||||
|
||||
in mapAttrs (mkVBoxTest false vboxVMs) {
|
||||
kvmTests = mapAttrs (mkVBoxTest {
|
||||
enableKvm = true;
|
||||
|
||||
# Once the KVM version supports these, we can enable them.
|
||||
addNetworkInterface = false;
|
||||
enableHardening = false;
|
||||
} vboxVMs) {
|
||||
kvm-headless = ''
|
||||
create_vm_headless()
|
||||
machine.succeed(ru("VBoxHeadless --startvm headless >&2 & disown %1"))
|
||||
wait_for_startup_headless()
|
||||
wait_for_vm_boot_headless()
|
||||
shutdown_vm_headless()
|
||||
destroy_vm_headless()
|
||||
'';
|
||||
};
|
||||
|
||||
in mapAttrs (mkVBoxTest {} vboxVMs) {
|
||||
simple-gui = ''
|
||||
# Home to select Tools, down to move to the VM, enter to start it.
|
||||
def send_vm_startup():
|
||||
|
@ -519,4 +546,6 @@ in mapAttrs (mkVBoxTest false vboxVMs) {
|
|||
destroy_vm_test1()
|
||||
destroy_vm_test2()
|
||||
'';
|
||||
} // (optionalAttrs enableUnfree unfreeTests)
|
||||
}
|
||||
// (optionalAttrs enableKvm kvmTests)
|
||||
// (optionalAttrs enableUnfree unfreeTests)
|
||||
|
|
|
@ -17,9 +17,13 @@
|
|||
, headless ? false
|
||||
, enable32bitGuests ? true
|
||||
, enableWebService ? false
|
||||
, enableKvm ? false
|
||||
, extraConfigureFlags ? ""
|
||||
}:
|
||||
|
||||
# See https://github.com/cyberus-technology/virtualbox-kvm/issues/12
|
||||
assert enableKvm -> !enableHardening;
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
|
@ -27,6 +31,10 @@ let
|
|||
# Use maintainers/scripts/update.nix to update the version and all related hashes or
|
||||
# change the hashes in extpack.nix and guest-additions/default.nix as well manually.
|
||||
version = "7.0.14";
|
||||
|
||||
# The KVM build is not compatible to VirtualBox's kernel modules. So don't export
|
||||
# modsrc at all.
|
||||
withModsrc = !enableKvm;
|
||||
in stdenv.mkDerivation {
|
||||
pname = "virtualbox";
|
||||
inherit version;
|
||||
|
@ -36,7 +44,7 @@ in stdenv.mkDerivation {
|
|||
sha256 = "45860d834804a24a163c1bb264a6b1cb802a5bc7ce7e01128072f8d6a4617ca9";
|
||||
};
|
||||
|
||||
outputs = [ "out" "modsrc" ];
|
||||
outputs = [ "out" ] ++ optional withModsrc "modsrc";
|
||||
|
||||
nativeBuildInputs = [ pkg-config which docbook_xsl docbook_xml_dtd_43 yasm glslang ]
|
||||
++ optional (!headless) wrapQtAppsHook;
|
||||
|
@ -103,7 +111,17 @@ in stdenv.mkDerivation {
|
|||
++ optional (!headless && enableHardening) (substituteAll {
|
||||
src = ./qt-env-vars.patch;
|
||||
qtPluginPath = "${qtbase.bin}/${qtbase.qtPluginPrefix}:${qtsvg.bin}/${qtbase.qtPluginPrefix}:${qtwayland.bin}/${qtbase.qtPluginPrefix}";
|
||||
})
|
||||
})
|
||||
# While the KVM patch should not break any other behavior if --with-kvm is not specified,
|
||||
# we don't take any chances and only apply it if people actually want to use KVM support.
|
||||
++ optional enableKvm (fetchpatch
|
||||
(let
|
||||
patchVersion = "20240226";
|
||||
in {
|
||||
name = "virtualbox-${version}-kvm-dev-${patchVersion}.patch";
|
||||
url = "https://github.com/cyberus-technology/virtualbox-kvm/releases/download/dev-${patchVersion}/virtualbox-${version}-kvm-dev-${patchVersion}.patch";
|
||||
hash = "sha256-3YT1ZN/TwoNWNb2eqOcPF8GTrVGfOPaPb8vpGoPNISY=";
|
||||
}))
|
||||
++ [
|
||||
./qt-dependency-paths.patch
|
||||
# https://github.com/NixOS/nixpkgs/issues/123851
|
||||
|
@ -165,6 +183,7 @@ in stdenv.mkDerivation {
|
|||
${optionalString (!enable32bitGuests) "--disable-vmmraw"} \
|
||||
${optionalString enableWebService "--enable-webservice"} \
|
||||
${optionalString (open-watcom-bin != null) "--with-ow-dir=${open-watcom-bin}"} \
|
||||
${optionalString (enableKvm) "--with-kvm"} \
|
||||
${extraConfigureFlags} \
|
||||
--disable-kmods
|
||||
sed -e 's@PKG_CONFIG_PATH=.*@PKG_CONFIG_PATH=${libIDL}/lib/pkgconfig:${glib.dev}/lib/pkgconfig ${libIDL}/bin/libIDL-config-2@' \
|
||||
|
@ -224,7 +243,9 @@ in stdenv.mkDerivation {
|
|||
ln -sv $libexec/nls "$out/share/virtualbox"
|
||||
''}
|
||||
|
||||
cp -rv out/linux.*/${buildType}/bin/src "$modsrc"
|
||||
${optionalString withModsrc ''
|
||||
cp -rv out/linux.*/${buildType}/bin/src "$modsrc"
|
||||
''}
|
||||
|
||||
mkdir -p "$out/share/virtualbox"
|
||||
cp -rv src/VBox/Main/UnattendedTemplates "$out/share/virtualbox"
|
||||
|
|
|
@ -35866,6 +35866,10 @@ with pkgs;
|
|||
inherit (gnome2) libIDL;
|
||||
};
|
||||
|
||||
virtualboxKvm = lowPrio (virtualbox.override {
|
||||
enableKvm = true;
|
||||
});
|
||||
|
||||
virtualboxHardened = lowPrio (virtualbox.override {
|
||||
enableHardening = true;
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue