diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix index 7dd2a481004a..462575f17e81 100644 --- a/nixos/modules/misc/documentation.nix +++ b/nixos/modules/misc/documentation.nix @@ -228,6 +228,10 @@ in (mkRenamedOptionModule [ "programs" "info" "enable" ] [ "documentation" "info" "enable" ]) (mkRenamedOptionModule [ "programs" "man" "enable" ] [ "documentation" "man" "enable" ]) (mkRenamedOptionModule [ "services" "nixosManual" "enable" ] [ "documentation" "nixos" "enable" ]) + (mkRenamedOptionModule + [ "documentation" "man" "generateCaches" ] + [ "documentation" "man" "cache" "enable" ] + ) (mkRemovedOptionModule [ "documentation" "nixos" @@ -261,7 +265,7 @@ in ''; }; - man.generateCaches = mkOption { + man.cache.enable = mkOption { type = types.bool; default = false; description = '' @@ -273,6 +277,16 @@ in ''; }; + man.cache.generateAtRuntime = mkOption { + type = types.bool; + default = false; + description = '' + Whether to generate the manual page index caches at runtime using + a systemd service. Note that this is currently only supported by the + man-db module. + ''; + }; + info.enable = mkOption { type = types.bool; default = true; diff --git a/nixos/modules/misc/man-db.nix b/nixos/modules/misc/man-db.nix index bb5a412dc7e0..bd5969770c1f 100644 --- a/nixos/modules/misc/man-db.nix +++ b/nixos/modules/misc/man-db.nix @@ -7,13 +7,14 @@ let cfg = config.documentation.man.man-db; + cfgm = config.documentation.man; in { options = { documentation.man.man-db = { enable = lib.mkEnableOption "man-db as the default man page viewer" // { - default = config.documentation.man.enable; + default = cfgm.enable; defaultText = lib.literalExpression "config.documentation.man.enable"; example = false; }; @@ -39,7 +40,7 @@ in }; defaultText = lib.literalMD "all man pages in {option}`config.environment.systemPackages`"; description = '' - The manual pages to generate caches for if {option}`documentation.man.generateCaches` + The manual pages to generate caches for if {option}`documentation.man.cache.enable` is enabled. Must be a path to a directory with man pages under `/share/man`; see the source for an example. Advanced users can make this a content-addressed derivation to save a few rebuilds. @@ -65,41 +66,79 @@ in ) ]; - config = lib.mkIf cfg.enable { - environment.systemPackages = [ cfg.package ]; - environment.etc."man_db.conf".text = - let - # We unfortunately can’t use the customized `cfg.package` when - # cross‐compiling. Instead we detect that situation and work - # around it by using the vanilla one, like the OpenSSH module. - buildPackage = - if pkgs.stdenv.buildPlatform.canExecute pkgs.stdenv.hostPlatform then + config = lib.mkIf cfg.enable ( + lib.mkMerge [ + { + environment.systemPackages = [ cfg.package ]; + environment.etc."man_db.conf".text = + let + # We unfortunately can’t use the customized `cfg.package` when + # cross‐compiling. Instead we detect that situation and work + # around it by using the vanilla one, like the OpenSSH module. + buildPackage = + if pkgs.stdenv.buildPlatform.canExecute pkgs.stdenv.hostPlatform then + cfg.package + else + pkgs.buildPackages.man-db; + + manualCache = + if (!cfgm.cache.generateAtRuntime) then + pkgs.runCommand "man-cache" + { + nativeBuildInputs = [ buildPackage ]; + preferLocalBuild = true; + } + '' + echo "MANDB_MAP ${cfg.manualPages}/share/man $out" > man.conf + mandb -C man.conf -pscq + '' + else + "/var/cache/man/nixos-mandb"; + in + '' + # Manual pages paths for NixOS + MANPATH_MAP /run/current-system/sw/bin /run/current-system/sw/share/man + MANPATH_MAP /run/wrappers/bin /run/current-system/sw/share/man + + ${lib.optionalString cfgm.cache.enable '' + # Manual pages caches for NixOS + MANDB_MAP /run/current-system/sw/share/man ${manualCache} + ''} + ''; + } + + (lib.mkIf (cfgm.enable && cfgm.cache.generateAtRuntime) { + users.users.mandb = { + isSystemUser = true; + group = "mandb"; + }; + users.groups.mandb = { }; + + systemd.services.mandb = { + path = [ cfg.package - else - pkgs.buildPackages.man-db; + pkgs.rsync + ]; + script = '' + rsync \ + --checksum --recursive --copy-links --delete --no-times --no-perms --chmod=+w \ + ${cfg.manualPages}/share/man/ "$CACHE_DIRECTORY/nixos-manpages" - manualCache = - pkgs.runCommand "man-cache" - { - nativeBuildInputs = [ buildPackage ]; - preferLocalBuild = true; - } - '' - echo "MANDB_MAP ${cfg.manualPages}/share/man $out" > man.conf - mandb -C man.conf -pscq - ''; - in - '' - # Manual pages paths for NixOS - MANPATH_MAP /run/current-system/sw/bin /run/current-system/sw/share/man - MANPATH_MAP /run/wrappers/bin /run/current-system/sw/share/man + echo "MANDB_MAP $CACHE_DIRECTORY/nixos-manpages $CACHE_DIRECTORY/nixos-mandb" \ + > "$RUNTIME_DIRECTORY/man.conf" - ${lib.optionalString config.documentation.man.generateCaches '' - # Generated manual pages cache for NixOS (immutable) - MANDB_MAP /run/current-system/sw/share/man ${manualCache} - ''} - # Manual pages caches for NixOS - MANDB_MAP /run/current-system/sw/share/man /var/cache/man/nixos - ''; - }; + mandb -C "$RUNTIME_DIRECTORY/man.conf" -q + ''; + serviceConfig = { + CacheDirectory = "man"; + RuntimeDirectory = "mandb"; + User = "mandb"; + BindReadOnlyPaths = [ "/dev/null:/etc/man_db.conf" ]; # mandb will still read /etc/man_db.conf if it exists, even when setting -C path/to/config.conf + ProtectSystem = "strict"; + }; + wantedBy = [ "default.target" ]; + }; + }) + ] + ); } diff --git a/nixos/modules/misc/mandoc.nix b/nixos/modules/misc/mandoc.nix index 694f3137478e..dc8bfae9a6f0 100644 --- a/nixos/modules/misc/mandoc.nix +++ b/nixos/modules/misc/mandoc.nix @@ -60,7 +60,7 @@ in apply = makeLeadingSlashes; description = '' Change the paths where mandoc {manpage}`makewhatis(8)`generates the - manual page index caches. {option}`documentation.man.generateCaches` + manual page index caches. {option}`documentation.man.cache.enable` should be enabled to allow cache generation. This list should only include the paths to manpages installed in the system configuration, i. e. /run/current-system/sw/share/man. {manpage}`makewhatis(8)` @@ -215,7 +215,7 @@ in # create mandoc.db for whatis(1), apropos(1) and man(1) -k # TODO(@sternenseemman): fix symlinked directories not getting indexed, # see: https://inbox.vuxu.org/mandoc-tech/20210906171231.GF83680@athene.usta.de/T/#e85f773c1781e3fef85562b2794f9cad7b2909a3c - extraSetup = lib.mkIf config.documentation.man.generateCaches '' + extraSetup = lib.mkIf config.documentation.man.cache.enable '' for man_path in ${ lib.concatMapStringsSep " " (path: "$out" + lib.escapeShellArg path) cfg.cachePath } diff --git a/nixos/modules/programs/fish.nix b/nixos/modules/programs/fish.nix index 1031a0bd8dc0..13c00237906e 100644 --- a/nixos/modules/programs/fish.nix +++ b/nixos/modules/programs/fish.nix @@ -169,7 +169,8 @@ in programs.fish.shellAliases = lib.mapAttrs (name: lib.mkDefault) cfge.shellAliases; # Required for man completions - documentation.man.generateCaches = lib.mkDefault true; + documentation.man.cache.enable = lib.mkDefault true; + documentation.man.cache.generateAtRuntime = lib.mkDefault true; environment = lib.mkMerge [ (lib.mkIf cfg.useBabelfish {