about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorSandro <sandro.jaeckel@gmail.com>2022-05-04 14:13:12 +0200
committerGitHub <noreply@github.com>2022-05-04 14:13:12 +0200
commitaacb7ef4a6bcc963a1c340eb3c831d9180e5fa3b (patch)
tree366b7410c49bf72ab5318fbb47e65145bcb5e743 /nixos
parent9b3cfba4ba88b79d0fc91ba76938ea1df8c87460 (diff)
parent3e8e52bb91d0da2a06c24ae70975f8ba309eb214 (diff)
Merge pull request #169966 from deinferno/vmware-host
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/module-list.nix1
-rw-r--r--nixos/modules/virtualisation/vmware-host.nix166
2 files changed, 167 insertions, 0 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index d1cda0d84e96b..9d9f2e9057cc0 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -1256,6 +1256,7 @@
   ./virtualisation/virtualbox-guest.nix
   ./virtualisation/virtualbox-host.nix
   ./virtualisation/vmware-guest.nix
+  ./virtualisation/vmware-host.nix
   ./virtualisation/waydroid.nix
   ./virtualisation/xen-dom0.nix
   ./virtualisation/xe-guest-utilities.nix
diff --git a/nixos/modules/virtualisation/vmware-host.nix b/nixos/modules/virtualisation/vmware-host.nix
new file mode 100644
index 0000000000000..faa0d455c9d6b
--- /dev/null
+++ b/nixos/modules/virtualisation/vmware-host.nix
@@ -0,0 +1,166 @@
+{ config, pkgs, lib, ... }:
+
+let
+  cfg = config.virtualisation.vmware.host;
+  wrapperDir = "/run/vmware/bin"; # Perfectly fits as /usr/local/bin
+  parentWrapperDir = dirOf wrapperDir;
+  vmwareWrappers = # Needed as hardcoded paths workaround
+    let mkVmwareSymlink =
+      program:
+      ''
+        ln -s "${config.security.wrapperDir}/${program}" $wrapperDir/${program}
+      '';
+    in
+    [
+      (mkVmwareSymlink "pkexec")
+      (mkVmwareSymlink "mount")
+      (mkVmwareSymlink "umount")
+    ];
+in
+{
+  options = with lib; {
+    virtualisation.vmware.host = {
+      enable = mkEnableOption "VMware" // {
+        description = ''
+          This enables VMware host virtualisation for running VMs.
+
+          <important><para>
+          <literal>vmware-vmx</literal> will cause kcompactd0 due to
+          <literal>Transparent Hugepages</literal> feature in kernel.
+          Apply <literal>[ "transparent_hugepage=never" ]</literal> in
+          option <option>boot.kernelParams</option> to disable them.
+          </para></important>
+
+          <note><para>
+          If that didn't work disable <literal>TRANSPARENT_HUGEPAGE</literal>,
+          <literal>COMPACTION</literal> configs and recompile kernel.
+          </para></note>
+        '';
+      };
+      package = mkOption {
+        type = types.package;
+        default = pkgs.vmware-workstation;
+        defaultText = literalExpression "pkgs.vmware-workstation";
+        description = "VMware host virtualisation package to use";
+      };
+      extraPackages = mkOption {
+        type = with types; listOf package;
+        default = with pkgs; [ ];
+        description = "Extra packages to be used with VMware host.";
+        example = "with pkgs; [ ntfs3g ]";
+      };
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = "Add extra config to /etc/vmware/config";
+        example = ''
+          # Allow unsupported device's OpenGL and Vulkan acceleration for guest vGPU
+          mks.gl.allowUnsupportedDrivers = "TRUE"
+          mks.vk.allowUnsupportedDevices = "TRUE"
+        '';
+      };
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+    boot.extraModulePackages = [ config.boot.kernelPackages.vmware ];
+    boot.extraModprobeConfig = "alias char-major-10-229 fuse";
+    boot.kernelModules = [ "vmw_pvscsi" "vmw_vmci" "vmmon" "vmnet" "fuse" ];
+
+    environment.systemPackages = [ cfg.package ] ++ cfg.extraPackages;
+    services.printing.drivers = [ cfg.package ];
+
+    environment.etc."vmware/config".text = ''
+      ${builtins.readFile "${cfg.package}/etc/vmware/config"}
+      ${cfg.extraConfig}
+    '';
+
+    environment.etc."vmware/bootstrap".source = "${cfg.package}/etc/vmware/bootstrap";
+    environment.etc."vmware/icu".source = "${cfg.package}/etc/vmware/icu";
+    environment.etc."vmware-installer".source = "${cfg.package}/etc/vmware-installer";
+
+    # SUID wrappers
+
+    security.wrappers = {
+      vmware-vmx = {
+        setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${cfg.package}/lib/vmware/bin/.vmware-vmx-wrapped";
+      };
+    };
+
+    ###### wrappers activation script
+
+    system.activationScripts.vmwareWrappers =
+      lib.stringAfter [ "specialfs" "users" ]
+        ''
+          mkdir -p "${parentWrapperDir}"
+          chmod 755 "${parentWrapperDir}"
+          # We want to place the tmpdirs for the wrappers to the parent dir.
+          wrapperDir=$(mktemp --directory --tmpdir="${parentWrapperDir}" wrappers.XXXXXXXXXX)
+          chmod a+rx "$wrapperDir"
+          ${lib.concatStringsSep "\n" (vmwareWrappers)}
+          if [ -L ${wrapperDir} ]; then
+            # Atomically replace the symlink
+            # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/
+            old=$(readlink -f ${wrapperDir})
+            if [ -e "${wrapperDir}-tmp" ]; then
+              rm --force --recursive "${wrapperDir}-tmp"
+            fi
+            ln --symbolic --force --no-dereference "$wrapperDir" "${wrapperDir}-tmp"
+            mv --no-target-directory "${wrapperDir}-tmp" "${wrapperDir}"
+            rm --force --recursive "$old"
+          else
+            # For initial setup
+            ln --symbolic "$wrapperDir" "${wrapperDir}"
+          fi
+        '';
+
+    # Services
+
+    systemd.services."vmware-authdlauncher" = {
+      description = "VMware Authentification Daemon";
+      serviceConfig = {
+        Type = "forking";
+        ExecStart = [ "${cfg.package}/bin/vmware-authdlauncher" ];
+      };
+      wantedBy = [ "multi-user.target" ];
+    };
+
+    systemd.services."vmware-networks-configuration" = {
+      description = "VMware Networks Configuration Generation";
+      unitConfig.ConditionPathExists = "!/etc/vmware/networking";
+      serviceConfig = {
+        UMask = "0077";
+        ExecStart = [
+          "${cfg.package}/bin/vmware-networks --postinstall vmware-player,0,1"
+        ];
+        Type = "oneshot";
+        RemainAfterExit = "yes";
+      };
+      wantedBy = [ "multi-user.target" ];
+    };
+
+    systemd.services."vmware-networks" = {
+      description = "VMware Networks";
+      after = [ "vmware-networks-configuration.service" ];
+      requires = [ "vmware-networks-configuration.service" ];
+      serviceConfig = {
+        Type = "forking";
+        ExecCondition = [ "${pkgs.kmod}/bin/modprobe vmnet" ];
+        ExecStart = [ "${cfg.package}/bin/vmware-networks --start" ];
+        ExecStop = [ "${cfg.package}/bin/vmware-networks --stop" ];
+      };
+      wantedBy = [ "multi-user.target" ];
+    };
+
+    systemd.services."vmware-usbarbitrator" = {
+      description = "VMware USB Arbitrator";
+      serviceConfig = {
+        ExecStart = [ "${cfg.package}/bin/vmware-usbarbitrator -f" ];
+      };
+      wantedBy = [ "multi-user.target" ];
+    };
+  };
+}