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 1 { config, lib, pkgs, ... }: 2 2 3 - # services.hoogle = { 4 - # enable = true; 5 - # packages = hp: with hp; [ text lens ]; 6 - # haskellPackages = pkgs.haskellPackages; 7 - # }; 8 - 9 3 with lib; 10 4 11 5 let 12 6 13 7 cfg = config.services.hoogle; 14 - ghcWithHoogle = pkgs.haskellPackages.ghcWithHoogle; 8 + 9 + hoogleEnv = pkgs.buildEnv { 10 + name = "hoogle"; 11 + paths = [ (cfg.haskellPackages.ghcWithHoogle cfg.packages) ]; 12 + }; 15 13 16 14 in { 17 15 18 16 options.services.hoogle = { 19 - enable = mkEnableOption "Hoogle Documentation service"; 17 + enable = mkEnableOption "Haskell documentation server"; 20 18 21 19 port = mkOption { 22 20 type = types.int; ··· 28 26 29 27 packages = mkOption { 30 28 default = hp: []; 29 + defaultText = "hp: []"; 31 30 example = "hp: with hp; [ text lens ]"; 32 31 description = '' 33 - A function that returns a list of Haskell packages to generate 34 - documentation for. 32 + The Haskell packages to generate documentation for. 35 33 36 - The argument will be a Haskell package set provided by the 37 - haskellPackages config option. 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. 38 37 ''; 39 38 }; 40 39 41 40 haskellPackages = mkOption { 42 41 description = "Which haskell package set to use."; 43 - example = "pkgs.haskellPackages"; 44 - type = types.attrs; 42 + default = pkgs.haskellPackages; 43 + defaultText = "pkgs.haskellPackages"; 45 44 }; 46 45 47 46 }; 48 47 49 48 config = mkIf cfg.enable { 50 49 systemd.services.hoogle = { 51 - description = "Hoogle Haskell documentation search"; 50 + description = "Haskell documentation server"; 51 + 52 52 wantedBy = [ "multi-user.target" ]; 53 + 53 54 serviceConfig = { 54 55 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 - ''; 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"; 64 66 }; 65 67 }; 66 68 };