vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / virtualisation / vmware-host.nix
blob5fac2a4a8e8d430062371dee988f68a14b8c5656
1 { config, pkgs, lib, ... }:
3 let
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     ];
21   options = with lib; {
22     virtualisation.vmware.host = {
23       enable = mkEnableOption "VMware" // {
24         description = ''
25           This enables VMware host virtualisation for running VMs.
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           :::
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   };
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" ];
65     environment.systemPackages = [ cfg.package ] ++ cfg.extraPackages;
66     services.printing.drivers = [ cfg.package ];
68     environment.etc."vmware/config".text = ''
69       ${builtins.readFile "${cfg.package}/etc/vmware/config"}
70       ${cfg.extraConfig}
71     '';
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";
77     # SUID wrappers
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     };
88     # Services
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     };
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     };
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     };
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     };
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   };