hoogle service: fixups

Basic hardening
- Run as nobody:nogroup with a private /tmp, /home & /run/user
- Create working directory under /run (hoogle insists on writing to cwd
and otherwise returns "something went wrong" to every query)

Option tweaks
- Provide a default for the haskellPackage option
- Set text values for defaults
- Move hoogleEnv to the top-level & simplify it

+26 -24
+26 -24
nixos/modules/services/development/hoogle.nix
··· 1 { config, lib, pkgs, ... }: 2 3 - # services.hoogle = { 4 - # enable = true; 5 - # packages = hp: with hp; [ text lens ]; 6 - # haskellPackages = pkgs.haskellPackages; 7 - # }; 8 - 9 with lib; 10 11 let 12 13 cfg = config.services.hoogle; 14 - ghcWithHoogle = pkgs.haskellPackages.ghcWithHoogle; 15 16 in { 17 18 options.services.hoogle = { 19 - enable = mkEnableOption "Hoogle Documentation service"; 20 21 port = mkOption { 22 type = types.int; ··· 28 29 packages = mkOption { 30 default = hp: []; 31 example = "hp: with hp; [ text lens ]"; 32 description = '' 33 - A function that returns a list of Haskell packages to generate 34 - documentation for. 35 36 - The argument will be a Haskell package set provided by the 37 - haskellPackages config option. 38 ''; 39 }; 40 41 haskellPackages = mkOption { 42 description = "Which haskell package set to use."; 43 - example = "pkgs.haskellPackages"; 44 - type = types.attrs; 45 }; 46 47 }; 48 49 config = mkIf cfg.enable { 50 systemd.services.hoogle = { 51 - description = "Hoogle Haskell documentation search"; 52 wantedBy = [ "multi-user.target" ]; 53 serviceConfig = { 54 Restart = "always"; 55 - ExecStart = 56 - let env = cfg.haskellPackages.ghcWithHoogle cfg.packages; 57 - hoogleEnv = pkgs.buildEnv { 58 - name = "hoogleServiceEnv"; 59 - paths = [env]; 60 - }; 61 - in '' 62 - ${hoogleEnv}/bin/hoogle server --local -p ${toString cfg.port} 63 - ''; 64 }; 65 }; 66 };
··· 1 { config, lib, pkgs, ... }: 2 3 with lib; 4 5 let 6 7 cfg = config.services.hoogle; 8 + 9 + hoogleEnv = pkgs.buildEnv { 10 + name = "hoogle"; 11 + paths = [ (cfg.haskellPackages.ghcWithHoogle cfg.packages) ]; 12 + }; 13 14 in { 15 16 options.services.hoogle = { 17 + enable = mkEnableOption "Haskell documentation server"; 18 19 port = mkOption { 20 type = types.int; ··· 26 27 packages = mkOption { 28 default = hp: []; 29 + defaultText = "hp: []"; 30 example = "hp: with hp; [ text lens ]"; 31 description = '' 32 + The Haskell packages to generate documentation for. 33 34 + The option value is a function that takes the package set specified in 35 + the <varname>haskellPackages</varname> option as its sole parameter and 36 + returns a list of packages. 37 ''; 38 }; 39 40 haskellPackages = mkOption { 41 description = "Which haskell package set to use."; 42 + default = pkgs.haskellPackages; 43 + defaultText = "pkgs.haskellPackages"; 44 }; 45 46 }; 47 48 config = mkIf cfg.enable { 49 systemd.services.hoogle = { 50 + description = "Haskell documentation server"; 51 + 52 wantedBy = [ "multi-user.target" ]; 53 + 54 serviceConfig = { 55 Restart = "always"; 56 + ExecStart = ''${hoogleEnv}/bin/hoogle server --local -p ${toString cfg.port}''; 57 + 58 + User = "nobody"; 59 + Group = "nogroup"; 60 + 61 + PrivateTmp = true; 62 + ProtectHome = true; 63 + 64 + RuntimeDirectory = "hoogle"; 65 + WorkingDirectory = "%t/hoogle"; 66 }; 67 }; 68 };