at 24.11-pre 5.8 kB view raw
1{ config, pkgs, lib, ... }: 2 3let 4 cfg = config.virtualisation.vmware.host; 5 wrapperDir = "/run/vmware/bin"; # Perfectly fits as /usr/local/bin 6 parentWrapperDir = dirOf wrapperDir; 7 vmwareWrappers = # Needed as hardcoded paths workaround 8 let mkVmwareSymlink = 9 program: 10 '' 11 ln -s "${config.security.wrapperDir}/${program}" $wrapperDir/${program} 12 ''; 13 in 14 [ 15 (mkVmwareSymlink "pkexec") 16 (mkVmwareSymlink "mount") 17 (mkVmwareSymlink "umount") 18 ]; 19in 20{ 21 options = with lib; { 22 virtualisation.vmware.host = { 23 enable = mkEnableOption "VMware" // { 24 description = '' 25 This enables VMware host virtualisation for running VMs. 26 27 ::: {.important} 28 `vmware-vmx` will cause kcompactd0 due to 29 `Transparent Hugepages` feature in kernel. 30 Apply `[ "transparent_hugepage=never" ]` in 31 option {option}`boot.kernelParams` to disable them. 32 ::: 33 34 ::: {.note} 35 If that didn't work disable `TRANSPARENT_HUGEPAGE`, 36 `COMPACTION` configs and recompile kernel. 37 ::: 38 ''; 39 }; 40 package = mkPackageOption pkgs "vmware-workstation" { }; 41 extraPackages = mkOption { 42 type = with types; listOf package; 43 default = with pkgs; [ ]; 44 description = "Extra packages to be used with VMware host."; 45 example = "with pkgs; [ ntfs3g ]"; 46 }; 47 extraConfig = mkOption { 48 type = types.lines; 49 default = ""; 50 description = "Add extra config to /etc/vmware/config"; 51 example = '' 52 # Allow unsupported device's OpenGL and Vulkan acceleration for guest vGPU 53 mks.gl.allowUnsupportedDrivers = "TRUE" 54 mks.vk.allowUnsupportedDevices = "TRUE" 55 ''; 56 }; 57 }; 58 }; 59 60 config = lib.mkIf cfg.enable { 61 boot.extraModulePackages = [ config.boot.kernelPackages.vmware ]; 62 boot.extraModprobeConfig = "alias char-major-10-229 fuse"; 63 boot.kernelModules = [ "vmw_pvscsi" "vmw_vmci" "vmmon" "vmnet" "fuse" ]; 64 65 environment.systemPackages = [ cfg.package ] ++ cfg.extraPackages; 66 services.printing.drivers = [ cfg.package ]; 67 68 environment.etc."vmware/config".text = '' 69 ${builtins.readFile "${cfg.package}/etc/vmware/config"} 70 ${cfg.extraConfig} 71 ''; 72 73 environment.etc."vmware/bootstrap".source = "${cfg.package}/etc/vmware/bootstrap"; 74 environment.etc."vmware/icu".source = "${cfg.package}/etc/vmware/icu"; 75 environment.etc."vmware-installer".source = "${cfg.package}/etc/vmware-installer"; 76 77 # SUID wrappers 78 79 security.wrappers = { 80 vmware-vmx = { 81 setuid = true; 82 owner = "root"; 83 group = "root"; 84 source = "${cfg.package}/lib/vmware/bin/.vmware-vmx-wrapped"; 85 }; 86 }; 87 88 # Services 89 90 systemd.services."vmware-wrappers" = { 91 description = "Create VMVare Wrappers"; 92 wantedBy = [ "multi-user.target" ]; 93 before = [ 94 "vmware-authdlauncher.service" 95 "vmware-networks-configuration.service" 96 "vmware-networks.service" 97 "vmware-usbarbitrator.service" 98 ]; 99 after = [ "systemd-sysusers.service" ]; 100 serviceConfig.Type = "oneshot"; 101 serviceConfig.RemainAfterExit = true; 102 script = '' 103 mkdir -p "${parentWrapperDir}" 104 chmod 755 "${parentWrapperDir}" 105 # We want to place the tmpdirs for the wrappers to the parent dir. 106 wrapperDir=$(mktemp --directory --tmpdir="${parentWrapperDir}" wrappers.XXXXXXXXXX) 107 chmod a+rx "$wrapperDir" 108 ${lib.concatStringsSep "\n" (vmwareWrappers)} 109 if [ -L ${wrapperDir} ]; then 110 # Atomically replace the symlink 111 # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/ 112 old=$(readlink -f ${wrapperDir}) 113 if [ -e "${wrapperDir}-tmp" ]; then 114 rm --force --recursive "${wrapperDir}-tmp" 115 fi 116 ln --symbolic --force --no-dereference "$wrapperDir" "${wrapperDir}-tmp" 117 mv --no-target-directory "${wrapperDir}-tmp" "${wrapperDir}" 118 rm --force --recursive "$old" 119 else 120 # For initial setup 121 ln --symbolic "$wrapperDir" "${wrapperDir}" 122 fi 123 ''; 124 }; 125 126 systemd.services."vmware-authdlauncher" = { 127 description = "VMware Authentication Daemon"; 128 serviceConfig = { 129 Type = "forking"; 130 ExecStart = [ "${cfg.package}/bin/vmware-authdlauncher" ]; 131 }; 132 wantedBy = [ "multi-user.target" ]; 133 }; 134 135 systemd.services."vmware-networks-configuration" = { 136 description = "VMware Networks Configuration Generation"; 137 unitConfig.ConditionPathExists = "!/etc/vmware/networking"; 138 serviceConfig = { 139 UMask = "0077"; 140 ExecStart = [ 141 "${cfg.package}/bin/vmware-networks --postinstall vmware-player,0,1" 142 ]; 143 Type = "oneshot"; 144 RemainAfterExit = "yes"; 145 }; 146 wantedBy = [ "multi-user.target" ]; 147 }; 148 149 systemd.services."vmware-networks" = { 150 description = "VMware Networks"; 151 after = [ "vmware-networks-configuration.service" ]; 152 requires = [ "vmware-networks-configuration.service" ]; 153 serviceConfig = { 154 Type = "forking"; 155 ExecCondition = [ "${pkgs.kmod}/bin/modprobe vmnet" ]; 156 ExecStart = [ "${cfg.package}/bin/vmware-networks --start" ]; 157 ExecStop = [ "${cfg.package}/bin/vmware-networks --stop" ]; 158 }; 159 wantedBy = [ "multi-user.target" ]; 160 }; 161 162 systemd.services."vmware-usbarbitrator" = { 163 description = "VMware USB Arbitrator"; 164 serviceConfig = { 165 ExecStart = [ "${cfg.package}/bin/vmware-usbarbitrator -f" ]; 166 }; 167 wantedBy = [ "multi-user.target" ]; 168 }; 169 }; 170}