1# Module for VirtualBox guests.
2
3{ config, lib, pkgs, ... }:
4
5with lib;
6
7let
8
9 cfg = config.virtualisation.virtualbox.guest;
10 kernel = config.boot.kernelPackages;
11
12in
13
14{
15
16 ###### interface
17
18 options.virtualisation.virtualbox.guest = {
19 enable = mkOption {
20 default = false;
21 type = types.bool;
22 description = "Whether to enable the VirtualBox service and other guest additions.";
23 };
24
25 x11 = mkOption {
26 default = true;
27 type = types.bool;
28 description = "Whether to enable x11 graphics";
29 };
30 };
31
32 ###### implementation
33
34 config = mkIf cfg.enable (mkMerge [{
35 assertions = [{
36 assertion = pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64;
37 message = "Virtualbox not currently supported on ${pkgs.stdenv.hostPlatform.system}";
38 }];
39
40 environment.systemPackages = [ kernel.virtualboxGuestAdditions ];
41
42 boot.extraModulePackages = [ kernel.virtualboxGuestAdditions ];
43
44 boot.supportedFilesystems = [ "vboxsf" ];
45 boot.initrd.supportedFilesystems = [ "vboxsf" ];
46
47 users.groups.vboxsf.gid = config.ids.gids.vboxsf;
48
49 systemd.services.virtualbox =
50 { description = "VirtualBox Guest Services";
51
52 wantedBy = [ "multi-user.target" ];
53 requires = [ "dev-vboxguest.device" ];
54 after = [ "dev-vboxguest.device" ];
55
56 unitConfig.ConditionVirtualization = "oracle";
57
58 serviceConfig.ExecStart = "@${kernel.virtualboxGuestAdditions}/bin/VBoxService VBoxService --foreground";
59 };
60
61 services.udev.extraRules =
62 ''
63 # /dev/vboxuser is necessary for VBoxClient to work. Maybe we
64 # should restrict this to logged-in users.
65 KERNEL=="vboxuser", OWNER="root", GROUP="root", MODE="0666"
66
67 # Allow systemd dependencies on vboxguest.
68 SUBSYSTEM=="misc", KERNEL=="vboxguest", TAG+="systemd"
69 '';
70 } (mkIf cfg.x11 {
71 services.xserver.videoDrivers = mkOverride 50 [ "virtualbox" "modesetting" ];
72
73 services.xserver.config =
74 ''
75 Section "InputDevice"
76 Identifier "VBoxMouse"
77 Driver "vboxmouse"
78 EndSection
79 '';
80
81 services.xserver.serverLayoutSection =
82 ''
83 InputDevice "VBoxMouse"
84 '';
85
86 services.xserver.displayManager.sessionCommands =
87 ''
88 PATH=${makeBinPath [ pkgs.gnugrep pkgs.which pkgs.xorg.xorgserver.out ]}:$PATH \
89 ${kernel.virtualboxGuestAdditions}/bin/VBoxClient-all
90 '';
91 })]);
92
93}