1# This module includes the NixOS man-pages in the system environment, 2# and optionally starts a browser that shows the NixOS manual on one 3# of the virtual consoles. The latter is useful for the installation 4# CD. 5 6{ config, lib, pkgs, baseModules, ... }: 7 8with lib; 9 10let 11 12 cfg = config.services.nixosManual; 13 14 versionModule = 15 { system.nixosVersionSuffix = config.system.nixosVersionSuffix; 16 system.nixosRevision = config.system.nixosRevision; 17 nixpkgs.system = config.nixpkgs.system; 18 }; 19 20 /* For the purpose of generating docs, evaluate options with each derivation 21 in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}". 22 It isn't perfect, but it seems to cover a vast majority of use cases. 23 Caveat: even if the package is reached by a different means, 24 the path above will be shown and not e.g. `${config.services.foo.package}`. */ 25 manual = import ../../../doc/manual { 26 inherit pkgs; 27 version = config.system.nixosVersion; 28 revision = config.system.nixosRevision; 29 options = 30 let 31 scrubbedEval = evalModules { 32 modules = [ versionModule ] ++ baseModules; 33 args = (config._module.args) // { modules = [ ]; }; 34 specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; }; 35 }; 36 scrubDerivations = namePrefix: pkgSet: mapAttrs 37 (name: value: 38 let wholeName = "${namePrefix}.${name}"; in 39 if isAttrs value then 40 scrubDerivations wholeName value 41 // (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; }) 42 else value 43 ) 44 pkgSet; 45 in scrubbedEval.options; 46 }; 47 48 entry = "${manual.manual}/share/doc/nixos/index.html"; 49 50 help = pkgs.writeScriptBin "nixos-help" 51 '' 52 #! ${pkgs.stdenv.shell} -e 53 browser="$BROWSER" 54 if [ -z "$browser" ]; then 55 browser="$(type -P xdg-open || true)" 56 if [ -z "$browser" ]; then 57 browser="$(type -P w3m || true)" 58 if [ -z "$browser" ]; then 59 echo "$0: unable to start a web browser; please set \$BROWSER" 60 exit 1 61 fi 62 fi 63 fi 64 exec "$browser" ${entry} 65 ''; 66 67in 68 69{ 70 71 options = { 72 73 services.nixosManual.enable = mkOption { 74 type = types.bool; 75 default = true; 76 description = '' 77 Whether to build the NixOS manual pages. 78 ''; 79 }; 80 81 services.nixosManual.showManual = mkOption { 82 type = types.bool; 83 default = false; 84 description = '' 85 Whether to show the NixOS manual on one of the virtual 86 consoles. 87 ''; 88 }; 89 90 services.nixosManual.ttyNumber = mkOption { 91 type = types.int; 92 default = 8; 93 description = '' 94 Virtual console on which to show the manual. 95 ''; 96 }; 97 98 services.nixosManual.browser = mkOption { 99 type = types.path; 100 default = "${pkgs.w3m-nox}/bin/w3m"; 101 description = '' 102 Browser used to show the manual. 103 ''; 104 }; 105 106 }; 107 108 109 config = mkIf cfg.enable { 110 111 system.build.manual = manual; 112 113 environment.systemPackages = 114 [ manual.manual help ] 115 ++ optional config.programs.man.enable manual.manpages; 116 117 boot.extraTTYs = mkIf cfg.showManual ["tty${toString cfg.ttyNumber}"]; 118 119 systemd.services = optionalAttrs cfg.showManual 120 { "nixos-manual" = 121 { description = "NixOS Manual"; 122 wantedBy = [ "multi-user.target" ]; 123 serviceConfig = 124 { ExecStart = "${cfg.browser} ${entry}"; 125 StandardInput = "tty"; 126 StandardOutput = "tty"; 127 TTYPath = "/dev/tty${toString cfg.ttyNumber}"; 128 TTYReset = true; 129 TTYVTDisallocate = true; 130 Restart = "always"; 131 }; 132 }; 133 }; 134 135 services.mingetty.helpLine = mkIf cfg.showManual 136 "\nPress <Alt-F${toString cfg.ttyNumber}> for the NixOS manual."; 137 138 }; 139 140}