at master 3.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.programs.gamemode; 10 settingsFormat = pkgs.formats.ini { listsAsDuplicateKeys = true; }; 11 configFile = settingsFormat.generate "gamemode.ini" cfg.settings; 12in 13{ 14 options = { 15 programs.gamemode = { 16 enable = lib.mkEnableOption "GameMode to optimise system performance on demand"; 17 18 enableRenice = 19 lib.mkEnableOption "CAP_SYS_NICE on gamemoded to support lowering process niceness" 20 // { 21 default = true; 22 }; 23 24 settings = lib.mkOption { 25 type = settingsFormat.type; 26 default = { }; 27 description = '' 28 System-wide configuration for GameMode (/etc/gamemode.ini). 29 See {manpage}`gamemoded(8)` man page for available settings. 30 ''; 31 example = lib.literalExpression '' 32 { 33 general = { 34 renice = 10; 35 }; 36 37 # Warning: GPU optimisations have the potential to damage hardware 38 gpu = { 39 apply_gpu_optimisations = "accept-responsibility"; 40 gpu_device = 0; 41 amd_performance_level = "high"; 42 }; 43 44 custom = { 45 start = "''${pkgs.libnotify}/bin/notify-send 'GameMode started'"; 46 end = "''${pkgs.libnotify}/bin/notify-send 'GameMode ended'"; 47 }; 48 } 49 ''; 50 }; 51 }; 52 }; 53 54 config = lib.mkIf cfg.enable { 55 environment = { 56 systemPackages = [ pkgs.gamemode ]; 57 etc."gamemode.ini".source = configFile; 58 }; 59 60 security = { 61 polkit.enable = true; 62 wrappers = lib.mkIf cfg.enableRenice { 63 gamemoded = { 64 owner = "root"; 65 group = "root"; 66 source = "${pkgs.gamemode}/bin/gamemoded"; 67 capabilities = "cap_sys_nice+ep"; 68 }; 69 }; 70 }; 71 72 systemd = { 73 packages = [ pkgs.gamemode ]; 74 user.services.gamemoded = { 75 # The upstream service already defines this, but doesn't get applied. 76 # See https://github.com/NixOS/nixpkgs/issues/81138 77 wantedBy = [ "default.target" ]; 78 79 # Use pkexec from the security wrappers to allow users to 80 # run libexec/cpugovctl & libexec/gpuclockctl as root with 81 # the the actions defined in share/polkit-1/actions. 82 # 83 # This uses a link farm to make sure other wrapped executables 84 # aren't included in PATH. 85 environment.PATH = lib.mkForce ( 86 pkgs.linkFarm "pkexec" [ 87 { 88 name = "pkexec"; 89 path = "${config.security.wrapperDir}/pkexec"; 90 } 91 ] 92 ); 93 94 serviceConfig.ExecStart = lib.mkIf cfg.enableRenice [ 95 "" # Tell systemd to clear the existing ExecStart list, to prevent appending to it. 96 "${config.security.wrapperDir}/gamemoded" 97 ]; 98 }; 99 }; 100 101 users.groups.gamemode = { }; 102 }; 103 104 meta = { 105 maintainers = with lib.maintainers; [ kira-bruneau ]; 106 }; 107}