diff options
Diffstat (limited to 'nixos/modules/misc')
-rw-r--r-- | nixos/modules/misc/assertions.nix | 34 | ||||
-rw-r--r-- | nixos/modules/misc/crashdump.nix | 76 | ||||
-rw-r--r-- | nixos/modules/misc/documentation.nix | 346 | ||||
-rw-r--r-- | nixos/modules/misc/extra-arguments.nix | 7 | ||||
-rw-r--r-- | nixos/modules/misc/ids.nix | 677 | ||||
-rw-r--r-- | nixos/modules/misc/label.nix | 72 | ||||
-rw-r--r-- | nixos/modules/misc/lib.nix | 15 | ||||
-rw-r--r-- | nixos/modules/misc/locate.nix | 313 | ||||
-rw-r--r-- | nixos/modules/misc/man-db.nix | 73 | ||||
-rw-r--r-- | nixos/modules/misc/mandoc.nix | 61 | ||||
-rw-r--r-- | nixos/modules/misc/meta.nix | 76 | ||||
-rw-r--r-- | nixos/modules/misc/nixops-autoluks.nix | 43 | ||||
-rw-r--r-- | nixos/modules/misc/nixpkgs.nix | 259 | ||||
-rw-r--r-- | nixos/modules/misc/nixpkgs/test.nix | 8 | ||||
-rw-r--r-- | nixos/modules/misc/passthru.nix | 16 | ||||
-rw-r--r-- | nixos/modules/misc/version.nix | 141 | ||||
-rw-r--r-- | nixos/modules/misc/wordlist.nix | 59 |
17 files changed, 2276 insertions, 0 deletions
diff --git a/nixos/modules/misc/assertions.nix b/nixos/modules/misc/assertions.nix new file mode 100644 index 00000000000..550b3ac97f6 --- /dev/null +++ b/nixos/modules/misc/assertions.nix @@ -0,0 +1,34 @@ +{ lib, ... }: + +with lib; + +{ + + options = { + + assertions = mkOption { + type = types.listOf types.unspecified; + internal = true; + default = []; + example = [ { assertion = false; message = "you can't enable this for that reason"; } ]; + description = '' + This option allows modules to express conditions that must + hold for the evaluation of the system configuration to + succeed, along with associated error messages for the user. + ''; + }; + + warnings = mkOption { + internal = true; + default = []; + type = types.listOf types.str; + example = [ "The `foo' service is deprecated and will go away soon!" ]; + description = '' + This option allows modules to show warnings to users during + the evaluation of the system configuration. + ''; + }; + + }; + # impl of assertions is in <nixpkgs/nixos/modules/system/activation/top-level.nix> +} diff --git a/nixos/modules/misc/crashdump.nix b/nixos/modules/misc/crashdump.nix new file mode 100644 index 00000000000..b0f75d9caaa --- /dev/null +++ b/nixos/modules/misc/crashdump.nix @@ -0,0 +1,76 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + crashdump = config.boot.crashDump; + + kernelParams = concatStringsSep " " crashdump.kernelParams; + +in +###### interface +{ + options = { + boot = { + crashDump = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + If enabled, NixOS will set up a kernel that will + boot on crash, and leave the user in systemd rescue + to be able to save the crashed kernel dump at + /proc/vmcore. + It also activates the NMI watchdog. + ''; + }; + reservedMemory = mkOption { + default = "128M"; + type = types.str; + description = '' + The amount of memory reserved for the crashdump kernel. + If you choose a too high value, dmesg will mention + "crashkernel reservation failed". + ''; + }; + kernelParams = mkOption { + type = types.listOf types.str; + default = [ "1" "boot.shell_on_fail" ]; + description = '' + Parameters that will be passed to the kernel kexec-ed on crash. + ''; + }; + }; + }; + }; + +###### implementation + + config = mkIf crashdump.enable { + boot = { + postBootCommands = '' + echo "loading crashdump kernel..."; + ${pkgs.kexec-tools}/sbin/kexec -p /run/current-system/kernel \ + --initrd=/run/current-system/initrd \ + --reset-vga --console-vga \ + --command-line="init=$(readlink -f /run/current-system/init) irqpoll maxcpus=1 reset_devices ${kernelParams}" + ''; + kernelParams = [ + "crashkernel=${crashdump.reservedMemory}" + "nmi_watchdog=panic" + "softlockup_panic=1" + ]; + kernelPatches = [ { + name = "crashdump-config"; + patch = null; + extraConfig = '' + CRASH_DUMP y + DEBUG_INFO y + PROC_VMCORE y + LOCKUP_DETECTOR y + HARDLOCKUP_DETECTOR y + ''; + } ]; + }; + }; +} diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix new file mode 100644 index 00000000000..9304c307af2 --- /dev/null +++ b/nixos/modules/misc/documentation.nix @@ -0,0 +1,346 @@ +{ config, options, lib, pkgs, utils, modules, baseModules, extraModules, modulesPath, ... }: + +with lib; + +let + + cfg = config.documentation; + allOpts = options; + + /* Modules for which to show options even when not imported. */ + extraDocModules = [ ../virtualisation/qemu-vm.nix ]; + + canCacheDocs = m: + let + f = import m; + instance = f (mapAttrs (n: _: abort "evaluating ${n} for `meta` failed") (functionArgs f)); + in + cfg.nixos.options.splitBuild + && builtins.isPath m + && isFunction f + && instance ? options + && instance.meta.buildDocsInSandbox or true; + + docModules = + let + p = partition canCacheDocs (baseModules ++ extraDocModules); + in + { + lazy = p.right; + eager = p.wrong ++ optionals cfg.nixos.includeAllModules (extraModules ++ modules); + }; + + manual = import ../../doc/manual rec { + inherit pkgs config; + version = config.system.nixos.release; + revision = "release-${version}"; + extraSources = cfg.nixos.extraModuleSources; + options = + let + scrubbedEval = evalModules { + modules = [ { + _module.check = false; + } ] ++ docModules.eager; + specialArgs = { + pkgs = scrubDerivations "pkgs" pkgs; + # allow access to arbitrary options for eager modules, eg for getting + # option types from lazy modules + options = allOpts; + inherit modulesPath utils; + }; + }; + scrubDerivations = namePrefix: pkgSet: mapAttrs + (name: value: + let wholeName = "${namePrefix}.${name}"; in + if isAttrs value then + scrubDerivations wholeName value + // (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; }) + else value + ) + pkgSet; + in scrubbedEval.options; + baseOptionsJSON = + let + filter = + builtins.filterSource + (n: t: + (t == "directory" -> baseNameOf n != "tests") + && (t == "file" -> hasSuffix ".nix" n) + ); + in + pkgs.runCommand "lazy-options.json" { + libPath = filter "${toString pkgs.path}/lib"; + pkgsLibPath = filter "${toString pkgs.path}/pkgs/pkgs-lib"; + nixosPath = filter "${toString pkgs.path}/nixos"; + modules = map (p: ''"${removePrefix "${modulesPath}/" (toString p)}"'') docModules.lazy; + } '' + export NIX_STORE_DIR=$TMPDIR/store + export NIX_STATE_DIR=$TMPDIR/state + ${pkgs.buildPackages.nix}/bin/nix-instantiate \ + --show-trace \ + --eval --json --strict \ + --argstr libPath "$libPath" \ + --argstr pkgsLibPath "$pkgsLibPath" \ + --argstr nixosPath "$nixosPath" \ + --arg modules "[ $modules ]" \ + --argstr stateVersion "${options.system.stateVersion.default}" \ + --argstr release "${config.system.nixos.release}" \ + $nixosPath/lib/eval-cacheable-options.nix > $out \ + || { + echo -en "\e[1;31m" + echo 'Cacheable portion of option doc build failed.' + echo 'Usually this means that an option attribute that ends up in documentation (eg' \ + '`default` or `description`) depends on the restricted module arguments' \ + '`config` or `pkgs`.' + echo + echo 'Rebuild your configuration with `--show-trace` to find the offending' \ + 'location. Remove the references to restricted arguments (eg by escaping' \ + 'their antiquotations or adding a `defaultText`) or disable the sandboxed' \ + 'build for the failing module by setting `meta.buildDocsInSandbox = false`.' + echo -en "\e[0m" + exit 1 + } >&2 + ''; + inherit (cfg.nixos.options) warningsAreErrors; + }; + + + nixos-help = let + helpScript = pkgs.writeShellScriptBin "nixos-help" '' + # Finds first executable browser in a colon-separated list. + # (see how xdg-open defines BROWSER) + browser="$( + IFS=: ; for b in $BROWSER; do + [ -n "$(type -P "$b" || true)" ] && echo "$b" && break + done + )" + if [ -z "$browser" ]; then + browser="$(type -P xdg-open || true)" + if [ -z "$browser" ]; then + browser="${pkgs.w3m-nographics}/bin/w3m" + fi + fi + exec "$browser" ${manual.manualHTMLIndex} + ''; + + desktopItem = pkgs.makeDesktopItem { + name = "nixos-manual"; + desktopName = "NixOS Manual"; + genericName = "View NixOS documentation in a web browser"; + icon = "nix-snowflake"; + exec = "nixos-help"; + categories = ["System"]; + }; + + in pkgs.symlinkJoin { + name = "nixos-help"; + paths = [ + helpScript + desktopItem + ]; + }; + +in + +{ + imports = [ + (mkRenamedOptionModule [ "programs" "info" "enable" ] [ "documentation" "info" "enable" ]) + (mkRenamedOptionModule [ "programs" "man" "enable" ] [ "documentation" "man" "enable" ]) + (mkRenamedOptionModule [ "services" "nixosManual" "enable" ] [ "documentation" "nixos" "enable" ]) + ]; + + options = { + + documentation = { + + enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to install documentation of packages from + <option>environment.systemPackages</option> into the generated system path. + + See "Multiple-output packages" chapter in the nixpkgs manual for more info. + ''; + # which is at ../../../doc/multiple-output.chapter.md + }; + + man.enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to install manual pages. + This also includes <literal>man</literal> outputs. + ''; + }; + + man.generateCaches = mkOption { + type = types.bool; + default = false; + description = '' + Whether to generate the manual page index caches. + This allows searching for a page or + keyword using utilities like + <citerefentry> + <refentrytitle>apropos</refentrytitle> + <manvolnum>1</manvolnum> + </citerefentry> + and the <literal>-k</literal> option of + <citerefentry> + <refentrytitle>man</refentrytitle> + <manvolnum>1</manvolnum> + </citerefentry>. + ''; + }; + + info.enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to install info pages and the <command>info</command> command. + This also includes "info" outputs. + ''; + }; + + doc.enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to install documentation distributed in packages' <literal>/share/doc</literal>. + Usually plain text and/or HTML. + This also includes "doc" outputs. + ''; + }; + + dev.enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to install documentation targeted at developers. + <itemizedlist> + <listitem><para>This includes man pages targeted at developers if <option>documentation.man.enable</option> is + set (this also includes "devman" outputs).</para></listitem> + <listitem><para>This includes info pages targeted at developers if <option>documentation.info.enable</option> + is set (this also includes "devinfo" outputs).</para></listitem> + <listitem><para>This includes other pages targeted at developers if <option>documentation.doc.enable</option> + is set (this also includes "devdoc" outputs).</para></listitem> + </itemizedlist> + ''; + }; + + nixos.enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to install NixOS's own documentation. + <itemizedlist> + <listitem><para>This includes man pages like + <citerefentry><refentrytitle>configuration.nix</refentrytitle> + <manvolnum>5</manvolnum></citerefentry> if <option>documentation.man.enable</option> is + set.</para></listitem> + <listitem><para>This includes the HTML manual and the <command>nixos-help</command> command if + <option>documentation.doc.enable</option> is set.</para></listitem> + </itemizedlist> + ''; + }; + + nixos.options.splitBuild = mkOption { + type = types.bool; + default = true; + description = '' + Whether to split the option docs build into a cacheable and an uncacheable part. + Splitting the build can substantially decrease the amount of time needed to build + the manual, but some user modules may be incompatible with this splitting. + ''; + }; + + nixos.options.warningsAreErrors = mkOption { + type = types.bool; + default = true; + description = '' + Treat warning emitted during the option documentation build (eg for missing option + descriptions) as errors. + ''; + }; + + nixos.includeAllModules = mkOption { + type = types.bool; + default = false; + description = '' + Whether the generated NixOS's documentation should include documentation for all + the options from all the NixOS modules included in the current + <literal>configuration.nix</literal>. Disabling this will make the manual + generator to ignore options defined outside of <literal>baseModules</literal>. + ''; + }; + + nixos.extraModuleSources = mkOption { + type = types.listOf (types.either types.path types.str); + default = [ ]; + description = '' + Which extra NixOS module paths the generated NixOS's documentation should strip + from options. + ''; + example = literalExpression '' + # e.g. with options from modules in ''${pkgs.customModules}/nix: + [ pkgs.customModules ] + ''; + }; + + }; + + }; + + config = mkIf cfg.enable (mkMerge [ + { + assertions = [ + { + assertion = !(cfg.man.man-db.enable && cfg.man.mandoc.enable); + message = '' + man-db and mandoc can't be used as the default man page viewer at the same time! + ''; + } + ]; + } + + # The actual implementation for this lives in man-db.nix or mandoc.nix, + # depending on which backend is active. + (mkIf cfg.man.enable { + environment.pathsToLink = [ "/share/man" ]; + environment.extraOutputsToInstall = [ "man" ] ++ optional cfg.dev.enable "devman"; + }) + + (mkIf cfg.info.enable { + environment.systemPackages = [ pkgs.texinfoInteractive ]; + environment.pathsToLink = [ "/share/info" ]; + environment.extraOutputsToInstall = [ "info" ] ++ optional cfg.dev.enable "devinfo"; + environment.extraSetup = '' + if [ -w $out/share/info ]; then + shopt -s nullglob + for i in $out/share/info/*.info $out/share/info/*.info.gz; do + ${pkgs.buildPackages.texinfo}/bin/install-info $i $out/share/info/dir + done + fi + ''; + }) + + (mkIf cfg.doc.enable { + environment.pathsToLink = [ "/share/doc" ]; + environment.extraOutputsToInstall = [ "doc" ] ++ optional cfg.dev.enable "devdoc"; + }) + + (mkIf cfg.nixos.enable { + system.build.manual = manual; + + environment.systemPackages = [] + ++ optional cfg.man.enable manual.manpages + ++ optionals cfg.doc.enable [ manual.manualHTML nixos-help ]; + + services.getty.helpLine = mkIf cfg.doc.enable ( + "\nRun 'nixos-help' for the NixOS manual." + ); + }) + + ]); + +} diff --git a/nixos/modules/misc/extra-arguments.nix b/nixos/modules/misc/extra-arguments.nix new file mode 100644 index 00000000000..48891b44049 --- /dev/null +++ b/nixos/modules/misc/extra-arguments.nix @@ -0,0 +1,7 @@ +{ lib, config, pkgs, ... }: + +{ + _module.args = { + utils = import ../../lib/utils.nix { inherit lib config pkgs; }; + }; +} diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix new file mode 100644 index 00000000000..7d1faa50f4b --- /dev/null +++ b/nixos/modules/misc/ids.nix @@ -0,0 +1,677 @@ +# This module defines the global list of uids and gids. We keep a +# central list to prevent id collisions. + +# IMPORTANT! +# We only add static uids and gids for services where it is not feasible +# to change uids/gids on service start, in example a service with a lot of +# files. Please also check if the service is applicable for systemd's +# DynamicUser option and does not need a uid/gid allocation at all. +# Systemd can also change ownership of service directories using the +# RuntimeDirectory/StateDirectory options. + +{ lib, ... }: + +let + inherit (lib) types; +in +{ + options = { + + ids.uids = lib.mkOption { + internal = true; + description = '' + The user IDs used in NixOS. + ''; + type = types.attrsOf types.int; + }; + + ids.gids = lib.mkOption { + internal = true; + description = '' + The group IDs used in NixOS. + ''; + type = types.attrsOf types.int; + }; + + }; + + + config = { + + ids.uids = { + root = 0; + #wheel = 1; # unused + #kmem = 2; # unused + #tty = 3; # unused + messagebus = 4; # D-Bus + haldaemon = 5; + #disk = 6; # unused + #vsftpd = 7; # dynamically allocated ass of 2021-09-14 + ftp = 8; + # bitlbee = 9; # removed 2021-10-05 #139765 + #avahi = 10; # removed 2019-05-22 + nagios = 11; + atd = 12; + postfix = 13; + #postdrop = 14; # unused + dovecot = 15; + tomcat = 16; + #audio = 17; # unused + #floppy = 18; # unused + uucp = 19; + #lp = 20; # unused + #proc = 21; # unused + pulseaudio = 22; # must match `pulseaudio' GID + gpsd = 23; + #cdrom = 24; # unused + #tape = 25; # unused + #video = 26; # unused + #dialout = 27; # unused + polkituser = 28; + #utmp = 29; # unused + # ddclient = 30; # converted to DynamicUser = true + davfs2 = 31; + disnix = 33; + osgi = 34; + tor = 35; + cups = 36; + foldingathome = 37; + sabnzbd = 38; + #kdm = 39; # dropped in 17.03 + #ghostone = 40; # dropped in 18.03 + git = 41; + #fourstore = 42; # dropped in 20.03 + #fourstorehttp = 43; # dropped in 20.03 + #virtuoso = 44; dropped module + #rtkit = 45; # dynamically allocated 2021-09-03 + dovecot2 = 46; + dovenull2 = 47; + prayer = 49; + mpd = 50; + clamav = 51; + #fprot = 52; # unused + # bind = 53; #dynamically allocated as of 2021-09-03 + wwwrun = 54; + #adm = 55; # unused + spamd = 56; + #networkmanager = 57; # unused + nslcd = 58; + scanner = 59; + nginx = 60; + chrony = 61; + #systemd-journal = 62; # unused + smtpd = 63; + smtpq = 64; + supybot = 65; + iodined = 66; + #libvirtd = 67; # unused + graphite = 68; + #statsd = 69; # removed 2018-11-14 + transmission = 70; + postgres = 71; + #vboxusers = 72; # unused + #vboxsf = 73; # unused + smbguest = 74; # unused + varnish = 75; + datadog = 76; + lighttpd = 77; + lightdm = 78; + freenet = 79; + ircd = 80; + bacula = 81; + #almir = 82; # removed 2018-03-25, the almir package was removed in 30291227f2411abaca097773eedb49b8f259e297 during 2017-08 + deluge = 83; + mysql = 84; + rabbitmq = 85; + activemq = 86; + gnunet = 87; + oidentd = 88; + quassel = 89; + amule = 90; + minidlna = 91; + elasticsearch = 92; + tcpcryptd = 93; # tcpcryptd uses a hard-coded uid. We patch it in Nixpkgs to match this choice. + firebird = 95; + #keys = 96; # unused + #haproxy = 97; # dynamically allocated as of 2020-03-11 + #mongodb = 98; #dynamically allocated as of 2021-09-03 + #openldap = 99; # dynamically allocated as of PR#94610 + #users = 100; # unused + # cgminer = 101; #dynamically allocated as of 2021-09-17 + munin = 102; + #logcheck = 103; #dynamically allocated as of 2021-09-17 + #nix-ssh = 104; #dynamically allocated as of 2021-09-03 + dictd = 105; + couchdb = 106; + #searx = 107; # dynamically allocated as of 2020-10-27 + #kippo = 108; # removed 2021-10-07, the kippo package was removed in 1b213f321cdbfcf868b96fd9959c24207ce1b66a during 2021-04 + jenkins = 109; + systemd-journal-gateway = 110; + #notbit = 111; # unused + aerospike = 111; + #ngircd = 112; #dynamically allocated as of 2021-09-03 + #btsync = 113; # unused + #minecraft = 114; #dynamically allocated as of 2021-09-03 + vault = 115; + # rippled = 116; #dynamically allocated as of 2021-09-18 + murmur = 117; + foundationdb = 118; + newrelic = 119; + starbound = 120; + hydra = 122; + spiped = 123; + teamspeak = 124; + influxdb = 125; + nsd = 126; + gitolite = 127; + znc = 128; + polipo = 129; + mopidy = 130; + #docker = 131; # unused + gdm = 132; + #dhcpd = 133; # dynamically allocated as of 2021-09-03 + siproxd = 134; + mlmmj = 135; + #neo4j = 136;# dynamically allocated as of 2021-09-03 + riemann = 137; + riemanndash = 138; + #radvd = 139;# dynamically allocated as of 2021-09-03 + #zookeeper = 140;# dynamically allocated as of 2021-09-03 + #dnsmasq = 141;# dynamically allocated as of 2021-09-03 + #uhub = 142; # unused + yandexdisk = 143; + mxisd = 144; # was once collectd + #consul = 145;# dynamically allocated as of 2021-09-03 + #mailpile = 146; # removed 2022-01-12 + redmine = 147; + #seeks = 148; # removed 2020-06-21 + prosody = 149; + i2pd = 150; + systemd-coredump = 151; + systemd-network = 152; + systemd-resolve = 153; + systemd-timesync = 154; + liquidsoap = 155; + #etcd = 156;# dynamically allocated as of 2021-09-03 + hbase = 158; + opentsdb = 159; + scollector = 160; + bosun = 161; + kubernetes = 162; + peerflix = 163; + #chronos = 164; # removed 2020-08-15 + gitlab = 165; + # tox-bootstrapd = 166; removed 2021-09-15 + cadvisor = 167; + nylon = 168; + #apache-kafka = 169;# dynamically allocated as of 2021-09-03 + #panamax = 170; # unused + exim = 172; + #fleet = 173; # unused + #input = 174; # unused + sddm = 175; + #tss = 176; # dynamically allocated as of 2021-09-17 + #memcached = 177; removed 2018-01-03 + #ntp = 179; # dynamically allocated as of 2021-09-17 + zabbix = 180; + #redis = 181; removed 2018-01-03 + #unifi = 183; dynamically allocated as of 2021-09-17 + uptimed = 184; + #zope2 = 185; # dynamically allocated as of 2021-09-18 + #ripple-data-api = 186; dynamically allocated as of 2021-09-17 + mediatomb = 187; + #rdnssd = 188; #dynamically allocated as of 2021-09-18 + ihaskell = 189; + i2p = 190; + lambdabot = 191; + asterisk = 192; + plex = 193; + plexpy = 195; + grafana = 196; + skydns = 197; + # ripple-rest = 198; # unused, removed 2017-08-12 + # nix-serve = 199; # unused, removed 2020-12-12 + #tvheadend = 200; # dynamically allocated as of 2021-09-18 + uwsgi = 201; + gitit = 202; + riemanntools = 203; + subsonic = 204; + riak = 205; + #shout = 206; # dynamically allocated as of 2021-09-18 + gateone = 207; + namecoin = 208; + #lxd = 210; # unused + #kibana = 211;# dynamically allocated as of 2021-09-03 + xtreemfs = 212; + calibre-server = 213; + #heapster = 214; #dynamically allocated as of 2021-09-17 + bepasty = 215; + # pumpio = 216; # unused, removed 2018-02-24 + nm-openvpn = 217; + # mathics = 218; # unused, removed 2020-08-15 + ejabberd = 219; + postsrsd = 220; + opendkim = 221; + dspam = 222; + # gale = 223; removed 2021-06-10 + matrix-synapse = 224; + rspamd = 225; + # rmilter = 226; # unused, removed 2019-08-22 + cfdyndns = 227; + # gammu-smsd = 228; #dynamically allocated as of 2021-09-17 + pdnsd = 229; + octoprint = 230; + avahi-autoipd = 231; + # nntp-proxy = 232; #dynamically allocated as of 2021-09-17 + mjpg-streamer = 233; + #radicale = 234;# dynamically allocated as of 2021-09-03 + hydra-queue-runner = 235; + hydra-www = 236; + syncthing = 237; + caddy = 239; + taskd = 240; + # factorio = 241; # DynamicUser = true + # emby = 242; # unusued, removed 2019-05-01 + #graylog = 243;# dynamically allocated as of 2021-09-03 + sniproxy = 244; + nzbget = 245; + mosquitto = 246; + #toxvpn = 247; # dynamically allocated as of 2021-09-18 + # squeezelite = 248; # DynamicUser = true + turnserver = 249; + #smokeping = 250;# dynamically allocated as of 2021-09-03 + gocd-agent = 251; + gocd-server = 252; + terraria = 253; + mattermost = 254; + prometheus = 255; + telegraf = 256; + gitlab-runner = 257; + postgrey = 258; + hound = 259; + leaps = 260; + ipfs = 261; + # stanchion = 262; # unused, removed 2020-10-14 + # riak-cs = 263; # unused, removed 2020-10-14 + infinoted = 264; + sickbeard = 265; + headphones = 266; + # couchpotato = 267; # unused, removed 2022-01-01 + gogs = 268; + #pdns-recursor = 269; # dynamically allocated as of 2020-20-18 + #kresd = 270; # switched to "knot-resolver" with dynamic ID + rpc = 271; + #geoip = 272; # new module uses DynamicUser + fcron = 273; + sonarr = 274; + radarr = 275; + jackett = 276; + aria2 = 277; + clickhouse = 278; + rslsync = 279; + minio = 280; + kanboard = 281; + # pykms = 282; # DynamicUser = true + kodi = 283; + restya-board = 284; + mighttpd2 = 285; + hass = 286; + #monero = 287; # dynamically allocated as of 2021-05-08 + ceph = 288; + duplicati = 289; + monetdb = 290; + restic = 291; + openvpn = 292; + # meguca = 293; # removed 2020-08-21 + yarn = 294; + hdfs = 295; + mapred = 296; + hadoop = 297; + hydron = 298; + cfssl = 299; + cassandra = 300; + qemu-libvirtd = 301; + # kvm = 302; # unused + # render = 303; # unused + # zeronet = 304; # removed 2019-01-03 + lirc = 305; + lidarr = 306; + slurm = 307; + kapacitor = 308; + solr = 309; + alerta = 310; + minetest = 311; + rss2email = 312; + cockroachdb = 313; + zoneminder = 314; + paperless = 315; + #mailman = 316; # removed 2019-08-30 + zigbee2mqtt = 317; + # shadow = 318; # unused + hqplayer = 319; + moonraker = 320; + distcc = 321; + webdav = 322; + pipewire = 323; + rstudio-server = 324; + + # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399! + + nixbld = 30000; # start of range of uids + nobody = 65534; + }; + + ids.gids = { + root = 0; + wheel = 1; + kmem = 2; + tty = 3; + messagebus = 4; # D-Bus + haldaemon = 5; + disk = 6; + #vsftpd = 7; # dynamically allocated as of 2021-09-14 + ftp = 8; + # bitlbee = 9; # removed 2021-10-05 #139765 + #avahi = 10; # removed 2019-05-22 + #nagios = 11; # unused + atd = 12; + postfix = 13; + postdrop = 14; + dovecot = 15; + tomcat = 16; + audio = 17; + floppy = 18; + uucp = 19; + lp = 20; + proc = 21; + pulseaudio = 22; # must match `pulseaudio' UID + gpsd = 23; + cdrom = 24; + tape = 25; + video = 26; + dialout = 27; + #polkituser = 28; # currently unused, polkitd doesn't need a group + utmp = 29; + # ddclient = 30; # converted to DynamicUser = true + davfs2 = 31; + disnix = 33; + osgi = 34; + tor = 35; + #cups = 36; # unused + #foldingathome = 37; # unused + #sabnzd = 38; # unused + #kdm = 39; # unused, even before 17.03 + #ghostone = 40; # dropped in 18.03 + git = 41; + fourstore = 42; + fourstorehttp = 43; + virtuoso = 44; + #rtkit = 45; # unused + dovecot2 = 46; + dovenull2 = 47; + prayer = 49; + mpd = 50; + clamav = 51; + #fprot = 52; # unused + #bind = 53; # unused + wwwrun = 54; + adm = 55; + spamd = 56; + networkmanager = 57; + nslcd = 58; + scanner = 59; + nginx = 60; + chrony = 61; + systemd-journal = 62; + smtpd = 63; + smtpq = 64; + supybot = 65; + iodined = 66; + libvirtd = 67; + graphite = 68; + #statsd = 69; # removed 2018-11-14 + transmission = 70; + postgres = 71; + vboxusers = 72; + vboxsf = 73; + smbguest = 74; # unused + varnish = 75; + datadog = 76; + lighttpd = 77; + lightdm = 78; + freenet = 79; + ircd = 80; + bacula = 81; + #almir = 82; # removed 2018-03-25, the almir package was removed in 30291227f2411abaca097773eedb49b8f259e297 during 2017-08 + deluge = 83; + mysql = 84; + rabbitmq = 85; + activemq = 86; + gnunet = 87; + oidentd = 88; + quassel = 89; + amule = 90; + minidlna = 91; + elasticsearch = 92; + #tcpcryptd = 93; # unused + firebird = 95; + keys = 96; + #haproxy = 97; # dynamically allocated as of 2020-03-11 + #mongodb = 98; # unused + #openldap = 99; # dynamically allocated as of PR#94610 + munin = 102; + #logcheck = 103; # unused + #nix-ssh = 104; # unused + dictd = 105; + couchdb = 106; + #searx = 107; # dynamically allocated as of 2020-10-27 + #kippo = 108; # removed 2021-10-07, the kippo package was removed in 1b213f321cdbfcf868b96fd9959c24207ce1b66a during 2021-04 + jenkins = 109; + systemd-journal-gateway = 110; + #notbit = 111; # unused + aerospike = 111; + #ngircd = 112; # unused + #btsync = 113; # unused + #minecraft = 114; # unused + vault = 115; + #ripped = 116; # unused + murmur = 117; + foundationdb = 118; + newrelic = 119; + starbound = 120; + hydra = 122; + spiped = 123; + teamspeak = 124; + influxdb = 125; + nsd = 126; + gitolite = 127; + znc = 128; + polipo = 129; + mopidy = 130; + docker = 131; + gdm = 132; + #dhcpcd = 133; # unused + siproxd = 134; + mlmmj = 135; + #neo4j = 136; # unused + riemann = 137; + riemanndash = 138; + #radvd = 139; # unused + #zookeeper = 140; # unused + #dnsmasq = 141; # unused + uhub = 142; + #yandexdisk = 143; # unused + mxisd = 144; # was once collectd + #consul = 145; # unused + #mailpile = 146; # removed 2022-01-12 + redmine = 147; + #seeks = 148; # removed 2020-06-21 + prosody = 149; + i2pd = 150; + systemd-network = 152; + systemd-resolve = 153; + systemd-timesync = 154; + liquidsoap = 155; + #etcd = 156; # unused + hbase = 158; + opentsdb = 159; + scollector = 160; + bosun = 161; + kubernetes = 162; + #peerflix = 163; # unused + #chronos = 164; # unused + gitlab = 165; + nylon = 168; + #panamax = 170; # unused + exim = 172; + #fleet = 173; # unused + input = 174; + sddm = 175; + #tss = 176; #dynamically allocateda as of 2021-09-20 + #memcached = 177; # unused, removed 2018-01-03 + #ntp = 179; # unused + zabbix = 180; + #redis = 181; # unused, removed 2018-01-03 + #unifi = 183; # unused + #uptimed = 184; # unused + #zope2 = 185; # unused + #ripple-data-api = 186; #unused + mediatomb = 187; + #rdnssd = 188; # unused + ihaskell = 189; + i2p = 190; + lambdabot = 191; + asterisk = 192; + plex = 193; + sabnzbd = 194; + #grafana = 196; #unused + #skydns = 197; #unused + # ripple-rest = 198; # unused, removed 2017-08-12 + #nix-serve = 199; #unused + #tvheadend = 200; #unused + uwsgi = 201; + gitit = 202; + riemanntools = 203; + subsonic = 204; + riak = 205; + #shout = 206; #unused + gateone = 207; + namecoin = 208; + #lxd = 210; # unused + #kibana = 211; + xtreemfs = 212; + calibre-server = 213; + bepasty = 215; + # pumpio = 216; # unused, removed 2018-02-24 + nm-openvpn = 217; + mathics = 218; + ejabberd = 219; + postsrsd = 220; + opendkim = 221; + dspam = 222; + # gale = 223; removed 2021-06-10 + matrix-synapse = 224; + rspamd = 225; + # rmilter = 226; # unused, removed 2019-08-22 + cfdyndns = 227; + pdnsd = 229; + octoprint = 230; + #radicale = 234;# dynamically allocated as of 2021-09-03 + syncthing = 237; + caddy = 239; + taskd = 240; + # factorio = 241; # unused + # emby = 242; # unused, removed 2019-05-01 + sniproxy = 244; + nzbget = 245; + mosquitto = 246; + #toxvpn = 247; # unused + #squeezelite = 248; #unused + turnserver = 249; + #smokeping = 250;# dynamically allocated as of 2021-09-03 + gocd-agent = 251; + gocd-server = 252; + terraria = 253; + mattermost = 254; + prometheus = 255; + #telegraf = 256; # unused + gitlab-runner = 257; + postgrey = 258; + hound = 259; + leaps = 260; + ipfs = 261; + # stanchion = 262; # unused, removed 2020-10-14 + # riak-cs = 263; # unused, removed 2020-10-14 + infinoted = 264; + sickbeard = 265; + headphones = 266; + # couchpotato = 267; # unused, removed 2022-01-01 + gogs = 268; + #kresd = 270; # switched to "knot-resolver" with dynamic ID + #rpc = 271; # unused + #geoip = 272; # unused + fcron = 273; + sonarr = 274; + radarr = 275; + jackett = 276; + aria2 = 277; + clickhouse = 278; + rslsync = 279; + minio = 280; + kanboard = 281; + # pykms = 282; # DynamicUser = true + kodi = 283; + restya-board = 284; + mighttpd2 = 285; + hass = 286; + # monero = 287; # dynamically allocated as of 2021-05-08 + ceph = 288; + duplicati = 289; + monetdb = 290; + restic = 291; + openvpn = 292; + # meguca = 293; # removed 2020-08-21 + yarn = 294; + hdfs = 295; + mapred = 296; + hadoop = 297; + hydron = 298; + cfssl = 299; + cassandra = 300; + qemu-libvirtd = 301; + kvm = 302; # default udev rules from systemd requires these + render = 303; # default udev rules from systemd requires these + sgx = 304; # default udev rules from systemd requires these + lirc = 305; + lidarr = 306; + slurm = 307; + kapacitor = 308; + solr = 309; + alerta = 310; + minetest = 311; + rss2email = 312; + cockroachdb = 313; + zoneminder = 314; + paperless = 315; + #mailman = 316; # removed 2019-08-30 + zigbee2mqtt = 317; + shadow = 318; + hqplayer = 319; + moonraker = 320; + distcc = 321; + webdav = 322; + pipewire = 323; + rstudio-server = 324; + + # When adding a gid, make sure it doesn't match an existing + # uid. Users and groups with the same name should have equal + # uids and gids. Also, don't use gids above 399! + + users = 100; + nixbld = 30000; + nogroup = 65534; + }; + + }; + +} diff --git a/nixos/modules/misc/label.nix b/nixos/modules/misc/label.nix new file mode 100644 index 00000000000..02b91555b3c --- /dev/null +++ b/nixos/modules/misc/label.nix @@ -0,0 +1,72 @@ +{ config, lib, ... }: + +with lib; + +let + cfg = config.system.nixos; +in + +{ + + options.system = { + + nixos.label = mkOption { + type = types.str; + description = '' + NixOS version name to be used in the names of generated + outputs and boot labels. + + If you ever wanted to influence the labels in your GRUB menu, + this is the option for you. + + The default is <option>system.nixos.tags</option> separated by + "-" + "-" + <envar>NIXOS_LABEL_VERSION</envar> environment + variable (defaults to the value of + <option>system.nixos.version</option>). + + Can be overriden by setting <envar>NIXOS_LABEL</envar>. + + Useful for not loosing track of configurations built from different + nixos branches/revisions, e.g.: + + <screen> + #!/bin/sh + today=`date +%Y%m%d` + branch=`(cd nixpkgs ; git branch 2>/dev/null | sed -n '/^\* / { s|^\* ||; p; }')` + revision=`(cd nixpkgs ; git rev-parse HEAD)` + export NIXOS_LABEL_VERSION="$today.$branch-''${revision:0:7}" + nixos-rebuild switch</screen> + ''; + }; + + nixos.tags = mkOption { + type = types.listOf types.str; + default = []; + example = [ "with-xen" ]; + description = '' + Strings to prefix to the default + <option>system.nixos.label</option>. + + Useful for not loosing track of configurations built with + different options, e.g.: + + <screen> + { + system.nixos.tags = [ "with-xen" ]; + virtualisation.xen.enable = true; + } + </screen> + ''; + }; + + }; + + config = { + # This is set here rather than up there so that changing it would + # not rebuild the manual + system.nixos.label = mkDefault (maybeEnv "NIXOS_LABEL" + (concatStringsSep "-" ((sort (x: y: x < y) cfg.tags) + ++ [ (maybeEnv "NIXOS_LABEL_VERSION" cfg.version) ]))); + }; + +} diff --git a/nixos/modules/misc/lib.nix b/nixos/modules/misc/lib.nix new file mode 100644 index 00000000000..121f396701e --- /dev/null +++ b/nixos/modules/misc/lib.nix @@ -0,0 +1,15 @@ +{ lib, ... }: + +{ + options = { + lib = lib.mkOption { + default = {}; + + type = lib.types.attrsOf lib.types.attrs; + + description = '' + This option allows modules to define helper functions, constants, etc. + ''; + }; + }; +} diff --git a/nixos/modules/misc/locate.nix b/nixos/modules/misc/locate.nix new file mode 100644 index 00000000000..204a8914300 --- /dev/null +++ b/nixos/modules/misc/locate.nix @@ -0,0 +1,313 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.locate; + isMLocate = hasPrefix "mlocate" cfg.locate.name; + isPLocate = hasPrefix "plocate" cfg.locate.name; + isMorPLocate = (isMLocate || isPLocate); + isFindutils = hasPrefix "findutils" cfg.locate.name; +in +{ + imports = [ + (mkRenamedOptionModule [ "services" "locate" "period" ] [ "services" "locate" "interval" ]) + (mkRemovedOptionModule [ "services" "locate" "includeStore" ] "Use services.locate.prunePaths") + ]; + + options.services.locate = with types; { + enable = mkOption { + type = bool; + default = false; + description = '' + If enabled, NixOS will periodically update the database of + files used by the <command>locate</command> command. + ''; + }; + + locate = mkOption { + type = package; + default = pkgs.findutils; + defaultText = literalExpression "pkgs.findutils"; + example = literalExpression "pkgs.mlocate"; + description = '' + The locate implementation to use + ''; + }; + + interval = mkOption { + type = str; + default = "02:15"; + example = "hourly"; + description = '' + Update the locate database at this interval. Updates by + default at 2:15 AM every day. + + The format is described in + <citerefentry><refentrytitle>systemd.time</refentrytitle> + <manvolnum>7</manvolnum></citerefentry>. + + To disable automatic updates, set to <literal>"never"</literal> + and run <command>updatedb</command> manually. + ''; + }; + + extraFlags = mkOption { + type = listOf str; + default = [ ]; + description = '' + Extra flags to pass to <command>updatedb</command>. + ''; + }; + + output = mkOption { + type = path; + default = "/var/cache/locatedb"; + description = '' + The database file to build. + ''; + }; + + localuser = mkOption { + type = nullOr str; + default = "nobody"; + description = '' + The user to search non-network directories as, using + <command>su</command>. + ''; + }; + + pruneFS = mkOption { + type = listOf str; + default = [ + "afs" + "anon_inodefs" + "auto" + "autofs" + "bdev" + "binfmt" + "binfmt_misc" + "ceph" + "cgroup" + "cgroup2" + "cifs" + "coda" + "configfs" + "cramfs" + "cpuset" + "curlftpfs" + "debugfs" + "devfs" + "devpts" + "devtmpfs" + "ecryptfs" + "eventpollfs" + "exofs" + "futexfs" + "ftpfs" + "fuse" + "fusectl" + "fusesmb" + "fuse.ceph" + "fuse.glusterfs" + "fuse.gvfsd-fuse" + "fuse.mfs" + "fuse.rclone" + "fuse.rozofs" + "fuse.sshfs" + "gfs" + "gfs2" + "hostfs" + "hugetlbfs" + "inotifyfs" + "iso9660" + "jffs2" + "lustre" + "lustre_lite" + "misc" + "mfs" + "mqueue" + "ncpfs" + "nfs" + "NFS" + "nfs4" + "nfsd" + "nnpfs" + "ocfs" + "ocfs2" + "pipefs" + "proc" + "ramfs" + "rpc_pipefs" + "securityfs" + "selinuxfs" + "sfs" + "shfs" + "smbfs" + "sockfs" + "spufs" + "sshfs" + "subfs" + "supermount" + "sysfs" + "tmpfs" + "tracefs" + "ubifs" + "udev" + "udf" + "usbfs" + "vboxsf" + "vperfctrfs" + ]; + description = '' + Which filesystem types to exclude from indexing + ''; + }; + + prunePaths = mkOption { + type = listOf path; + default = [ + "/tmp" + "/var/tmp" + "/var/cache" + "/var/lock" + "/var/run" + "/var/spool" + "/nix/store" + "/nix/var/log/nix" + ]; + description = '' + Which paths to exclude from indexing + ''; + }; + + pruneNames = mkOption { + type = listOf str; + default = lib.optionals (!isFindutils) [ ".bzr" ".cache" ".git" ".hg" ".svn" ]; + defaultText = literalDocBook '' + <literal>[ ".bzr" ".cache" ".git" ".hg" ".svn" ]</literal>, if + supported by the locate implementation (i.e. mlocate or plocate). + ''; + description = '' + Directory components which should exclude paths containing them from indexing + ''; + }; + + pruneBindMounts = mkOption { + type = bool; + default = false; + description = '' + Whether not to index bind mounts + ''; + }; + + }; + + config = mkIf cfg.enable { + users.groups = mkMerge [ + (mkIf isMLocate { mlocate = { }; }) + (mkIf isPLocate { plocate = { }; }) + ]; + + security.wrappers = + let + common = { + owner = "root"; + permissions = "u+rx,g+x,o+x"; + setgid = true; + setuid = false; + }; + mlocate = (mkIf isMLocate { + group = "mlocate"; + source = "${cfg.locate}/bin/locate"; + }); + plocate = (mkIf isPLocate { + group = "plocate"; + source = "${cfg.locate}/bin/plocate"; + }); + in + mkIf isMorPLocate { + locate = mkMerge [ common mlocate plocate ]; + plocate = (mkIf isPLocate (mkMerge [ common plocate ])); + }; + + nixpkgs.config = { locate.dbfile = cfg.output; }; + + environment.systemPackages = [ cfg.locate ]; + + environment.variables = mkIf (!isMorPLocate) { LOCATE_PATH = cfg.output; }; + + environment.etc = { + # write /etc/updatedb.conf for manual calls to `updatedb` + "updatedb.conf" = { + text = '' + PRUNEFS="${lib.concatStringsSep " " cfg.pruneFS}" + PRUNENAMES="${lib.concatStringsSep " " cfg.pruneNames}" + PRUNEPATHS="${lib.concatStringsSep " " cfg.prunePaths}" + PRUNE_BIND_MOUNTS="${if cfg.pruneBindMounts then "yes" else "no"}" + ''; + }; + }; + + warnings = optional (isMorPLocate && cfg.localuser != null) + "mlocate does not support the services.locate.localuser option; updatedb will run as root. (Silence with services.locate.localuser = null.)" + ++ optional (isFindutils && cfg.pruneNames != [ ]) + "findutils locate does not support pruning by directory component" + ++ optional (isFindutils && cfg.pruneBindMounts) + "findutils locate does not support skipping bind mounts"; + + systemd.services.update-locatedb = { + description = "Update Locate Database"; + path = mkIf (!isMorPLocate) [ pkgs.su ]; + + # mlocate's updatedb takes flags via a configuration file or + # on the command line, but not by environment variable. + script = + if isMorPLocate then + let + toFlags = x: + optional (cfg.${x} != [ ]) + "--${lib.toLower x} '${concatStringsSep " " cfg.${x}}'"; + args = concatLists (map toFlags [ "pruneFS" "pruneNames" "prunePaths" ]); + in + '' + exec ${cfg.locate}/bin/updatedb \ + --output ${toString cfg.output} ${concatStringsSep " " args} \ + --prune-bind-mounts ${if cfg.pruneBindMounts then "yes" else "no"} \ + ${concatStringsSep " " cfg.extraFlags} + '' + else '' + exec ${cfg.locate}/bin/updatedb \ + ${optionalString (cfg.localuser != null && !isMorPLocate) "--localuser=${cfg.localuser}"} \ + --output=${toString cfg.output} ${concatStringsSep " " cfg.extraFlags} + ''; + environment = optionalAttrs (!isMorPLocate) { + PRUNEFS = concatStringsSep " " cfg.pruneFS; + PRUNEPATHS = concatStringsSep " " cfg.prunePaths; + PRUNENAMES = concatStringsSep " " cfg.pruneNames; + PRUNE_BIND_MOUNTS = if cfg.pruneBindMounts then "yes" else "no"; + }; + serviceConfig.Nice = 19; + serviceConfig.IOSchedulingClass = "idle"; + serviceConfig.PrivateTmp = "yes"; + serviceConfig.PrivateNetwork = "yes"; + serviceConfig.NoNewPrivileges = "yes"; + serviceConfig.ReadOnlyPaths = "/"; + # Use dirOf cfg.output because mlocate creates temporary files next to + # the actual database. We could specify and create them as well, + # but that would make this quite brittle when they change something. + # NOTE: If /var/cache does not exist, this leads to the misleading error message: + # update-locatedb.service: Failed at step NAMESPACE spawning …/update-locatedb-start: No such file or directory + serviceConfig.ReadWritePaths = dirOf cfg.output; + }; + + systemd.timers.update-locatedb = mkIf (cfg.interval != "never") { + description = "Update timer for locate database"; + partOf = [ "update-locatedb.service" ]; + wantedBy = [ "timers.target" ]; + timerConfig.OnCalendar = cfg.interval; + }; + }; + + meta.maintainers = with lib.maintainers; [ SuperSandro2000 ]; +} diff --git a/nixos/modules/misc/man-db.nix b/nixos/modules/misc/man-db.nix new file mode 100644 index 00000000000..8bd329bc4e0 --- /dev/null +++ b/nixos/modules/misc/man-db.nix @@ -0,0 +1,73 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.documentation.man.man-db; +in + +{ + options = { + documentation.man.man-db = { + enable = lib.mkEnableOption "man-db as the default man page viewer" // { + default = config.documentation.man.enable; + defaultText = lib.literalExpression "config.documentation.man.enable"; + example = false; + }; + + manualPages = lib.mkOption { + type = lib.types.path; + default = pkgs.buildEnv { + name = "man-paths"; + paths = config.environment.systemPackages; + pathsToLink = [ "/share/man" ]; + extraOutputsToInstall = [ "man" ] + ++ lib.optionals config.documentation.dev.enable [ "devman" ]; + ignoreCollisions = true; + }; + defaultText = lib.literalDocBook "all man pages in <option>config.environment.systemPackages</option>"; + description = '' + The manual pages to generate caches for if <option>documentation.man.generateCaches</option> + is enabled. Must be a path to a directory with man pages under + <literal>/share/man</literal>; see the source for an example. + Advanced users can make this a content-addressed derivation to save a few rebuilds. + ''; + }; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.man-db; + defaultText = lib.literalExpression "pkgs.man-db"; + description = '' + The <literal>man-db</literal> derivation to use. Useful to override + configuration options used for the package. + ''; + }; + }; + }; + + imports = [ + (lib.mkRenamedOptionModule [ "documentation" "man" "manualPages" ] [ "documentation" "man" "man-db" "manualPages" ]) + ]; + + config = lib.mkIf cfg.enable { + environment.systemPackages = [ cfg.package ]; + environment.etc."man_db.conf".text = + let + manualCache = pkgs.runCommandLocal "man-cache" { } '' + echo "MANDB_MAP ${cfg.manualPages}/share/man $out" > man.conf + ${cfg.package}/bin/mandb -C man.conf -psc >/dev/null 2>&1 + ''; + 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 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 + ''; + }; +} diff --git a/nixos/modules/misc/mandoc.nix b/nixos/modules/misc/mandoc.nix new file mode 100644 index 00000000000..3da60f2f8e6 --- /dev/null +++ b/nixos/modules/misc/mandoc.nix @@ -0,0 +1,61 @@ +{ config, lib, pkgs, ... }: + +let + makewhatis = "${lib.getBin cfg.package}/bin/makewhatis"; + + cfg = config.documentation.man.mandoc; + +in { + meta.maintainers = [ lib.maintainers.sternenseemann ]; + + options = { + documentation.man.mandoc = { + enable = lib.mkEnableOption "mandoc as the default man page viewer"; + + manPath = lib.mkOption { + type = with lib.types; listOf str; + default = [ "share/man" ]; + example = lib.literalExpression "[ \"share/man\" \"share/man/fr\" ]"; + description = '' + Change the manpath, i. e. the directories where + <citerefentry><refentrytitle>man</refentrytitle><manvolnum>1</manvolnum></citerefentry> + looks for section-specific directories of man pages. + You only need to change this setting if you want extra man pages + (e. g. in non-english languages). All values must be strings that + are a valid path from the target prefix (without including it). + The first value given takes priority. + ''; + }; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.mandoc; + defaultText = lib.literalExpression "pkgs.mandoc"; + description = '' + The <literal>mandoc</literal> derivation to use. Useful to override + configuration options used for the package. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + environment = { + systemPackages = [ cfg.package ]; + + # tell mandoc about man pages + etc."man.conf".text = lib.concatMapStrings (path: '' + manpath /run/current-system/sw/${path} + '') cfg.manPath; + + # 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 '' + ${makewhatis} -T utf8 ${ + lib.concatMapStringsSep " " (path: "\"$out/${path}\"") cfg.manPath + } + ''; + }; + }; +} diff --git a/nixos/modules/misc/meta.nix b/nixos/modules/misc/meta.nix new file mode 100644 index 00000000000..8e689a63f6b --- /dev/null +++ b/nixos/modules/misc/meta.nix @@ -0,0 +1,76 @@ +{ lib, ... }: + +with lib; + +let + maintainer = mkOptionType { + name = "maintainer"; + check = email: elem email (attrValues lib.maintainers); + merge = loc: defs: listToAttrs (singleton (nameValuePair (last defs).file (last defs).value)); + }; + + listOfMaintainers = types.listOf maintainer // { + # Returns list of + # { "module-file" = [ + # "maintainer1 <first@nixos.org>" + # "maintainer2 <second@nixos.org>" ]; + # } + merge = loc: defs: + zipAttrs + (flatten (imap1 (n: def: imap1 (m: def': + maintainer.merge (loc ++ ["[${toString n}-${toString m}]"]) + [{ inherit (def) file; value = def'; }]) def.value) defs)); + }; + + docFile = types.path // { + # Returns tuples of + # { file = "module location"; value = <path/to/doc.xml>; } + merge = loc: defs: defs; + }; +in + +{ + options = { + meta = { + + maintainers = mkOption { + type = listOfMaintainers; + internal = true; + default = []; + example = literalExpression ''[ lib.maintainers.all ]''; + description = '' + List of maintainers of each module. This option should be defined at + most once per module. + ''; + }; + + doc = mkOption { + type = docFile; + internal = true; + example = "./meta.chapter.xml"; + description = '' + Documentation prologue for the set of options of each module. This + option should be defined at most once per module. + ''; + }; + + buildDocsInSandbox = mkOption { + type = types.bool // { + merge = loc: defs: defs; + }; + internal = true; + default = true; + description = '' + Whether to include this module in the split options doc build. + Disable if the module references `config`, `pkgs` or other module + arguments that cannot be evaluated as constants. + + This option should be defined at most once per module. + ''; + }; + + }; + }; + + meta.maintainers = singleton lib.maintainers.pierron; +} diff --git a/nixos/modules/misc/nixops-autoluks.nix b/nixos/modules/misc/nixops-autoluks.nix new file mode 100644 index 00000000000..20c143286af --- /dev/null +++ b/nixos/modules/misc/nixops-autoluks.nix @@ -0,0 +1,43 @@ +{ config, options, lib, ... }: +let + path = [ "deployment" "autoLuks" ]; + hasAutoLuksConfig = lib.hasAttrByPath path config && (lib.attrByPath path {} config) != {}; + + inherit (config.nixops) enableDeprecatedAutoLuks; +in { + options.nixops.enableDeprecatedAutoLuks = lib.mkEnableOption "Enable the deprecated NixOps AutoLuks module"; + + config = { + assertions = [ + { + assertion = if hasAutoLuksConfig then hasAutoLuksConfig && enableDeprecatedAutoLuks else true; + message = '' + ⚠️ !!! WARNING !!! ⚠️ + + NixOps autoLuks is deprecated. The feature was never widely used and the maintenance did outgrow the benefit. + If you still want to use the module: + a) Please raise your voice in the issue tracking usage of the module: + https://github.com/NixOS/nixpkgs/issues/62211 + b) make sure you set the `_netdev` option for each of the file + systems referring to block devices provided by the autoLuks module. + + ⚠️ If you do not set the option your system will not boot anymore! ⚠️ + + { + fileSystems."/secret" = { options = [ "_netdev" ]; }; + } + + b) set the option >nixops.enableDeprecatedAutoLuks = true< to remove this error. + + + For more details read through the following resources: + - https://github.com/NixOS/nixops/pull/1156 + - https://github.com/NixOS/nixpkgs/issues/47550 + - https://github.com/NixOS/nixpkgs/issues/62211 + - https://github.com/NixOS/nixpkgs/pull/61321 + ''; + } + ]; + }; + +} diff --git a/nixos/modules/misc/nixpkgs.nix b/nixos/modules/misc/nixpkgs.nix new file mode 100644 index 00000000000..69967c8a760 --- /dev/null +++ b/nixos/modules/misc/nixpkgs.nix @@ -0,0 +1,259 @@ +{ config, options, lib, pkgs, ... }: + +with lib; + +let + cfg = config.nixpkgs; + opt = options.nixpkgs; + + isConfig = x: + builtins.isAttrs x || lib.isFunction x; + + optCall = f: x: + if lib.isFunction f + then f x + else f; + + mergeConfig = lhs_: rhs_: + let + lhs = optCall lhs_ { inherit pkgs; }; + rhs = optCall rhs_ { inherit pkgs; }; + in + recursiveUpdate lhs rhs // + optionalAttrs (lhs ? packageOverrides) { + packageOverrides = pkgs: + optCall lhs.packageOverrides pkgs // + optCall (attrByPath ["packageOverrides"] ({}) rhs) pkgs; + } // + optionalAttrs (lhs ? perlPackageOverrides) { + perlPackageOverrides = pkgs: + optCall lhs.perlPackageOverrides pkgs // + optCall (attrByPath ["perlPackageOverrides"] ({}) rhs) pkgs; + }; + + configType = mkOptionType { + name = "nixpkgs-config"; + description = "nixpkgs config"; + check = x: + let traceXIfNot = c: + if c x then true + else lib.traceSeqN 1 x false; + in traceXIfNot isConfig; + merge = args: foldr (def: mergeConfig def.value) {}; + }; + + overlayType = mkOptionType { + name = "nixpkgs-overlay"; + description = "nixpkgs overlay"; + check = lib.isFunction; + merge = lib.mergeOneOption; + }; + + pkgsType = mkOptionType { + name = "nixpkgs"; + description = "An evaluation of Nixpkgs; the top level attribute set of packages"; + check = builtins.isAttrs; + }; + + defaultPkgs = import ../../.. { + inherit (cfg) config overlays localSystem crossSystem; + }; + + finalPkgs = if opt.pkgs.isDefined then cfg.pkgs.appendOverlays cfg.overlays else defaultPkgs; + +in + +{ + imports = [ + ./assertions.nix + ./meta.nix + ]; + + options.nixpkgs = { + + pkgs = mkOption { + defaultText = literalExpression '' + import "''${nixos}/.." { + inherit (cfg) config overlays localSystem crossSystem; + } + ''; + type = pkgsType; + example = literalExpression "import <nixpkgs> {}"; + description = '' + If set, the pkgs argument to all NixOS modules is the value of + this option, extended with <code>nixpkgs.overlays</code>, if + that is also set. Either <code>nixpkgs.crossSystem</code> or + <code>nixpkgs.localSystem</code> will be used in an assertion + to check that the NixOS and Nixpkgs architectures match. Any + other options in <code>nixpkgs.*</code>, notably <code>config</code>, + will be ignored. + + If unset, the pkgs argument to all NixOS modules is determined + as shown in the default value for this option. + + The default value imports the Nixpkgs source files + relative to the location of this NixOS module, because + NixOS and Nixpkgs are distributed together for consistency, + so the <code>nixos</code> in the default value is in fact a + relative path. The <code>config</code>, <code>overlays</code>, + <code>localSystem</code>, and <code>crossSystem</code> come + from this option's siblings. + + This option can be used by applications like NixOps to increase + the performance of evaluation, or to create packages that depend + on a container that should be built with the exact same evaluation + of Nixpkgs, for example. Applications like this should set + their default value using <code>lib.mkDefault</code>, so + user-provided configuration can override it without using + <code>lib</code>. + + Note that using a distinct version of Nixpkgs with NixOS may + be an unexpected source of problems. Use this option with care. + ''; + }; + + config = mkOption { + default = {}; + example = literalExpression + '' + { allowBroken = true; allowUnfree = true; } + ''; + type = configType; + description = '' + The configuration of the Nix Packages collection. (For + details, see the Nixpkgs documentation.) It allows you to set + package configuration options. + + Ignored when <code>nixpkgs.pkgs</code> is set. + ''; + }; + + overlays = mkOption { + default = []; + example = literalExpression + '' + [ + (self: super: { + openssh = super.openssh.override { + hpnSupport = true; + kerberos = self.libkrb5; + }; + }) + ] + ''; + type = types.listOf overlayType; + description = '' + List of overlays to use with the Nix Packages collection. + (For details, see the Nixpkgs documentation.) It allows + you to override packages globally. Each function in the list + takes as an argument the <emphasis>original</emphasis> Nixpkgs. + The first argument should be used for finding dependencies, and + the second should be used for overriding recipes. + + If <code>nixpkgs.pkgs</code> is set, overlays specified here + will be applied after the overlays that were already present + in <code>nixpkgs.pkgs</code>. + ''; + }; + + localSystem = mkOption { + type = types.attrs; # TODO utilize lib.systems.parsedPlatform + default = { inherit (cfg) system; }; + example = { system = "aarch64-linux"; config = "aarch64-unknown-linux-gnu"; }; + # Make sure that the final value has all fields for sake of other modules + # referring to this. TODO make `lib.systems` itself use the module system. + apply = lib.systems.elaborate; + defaultText = literalExpression + ''(import "''${nixos}/../lib").lib.systems.examples.aarch64-multiplatform''; + description = '' + Specifies the platform on which NixOS should be built. When + <code>nixpkgs.crossSystem</code> is unset, it also specifies + the platform <emphasis>for</emphasis> which NixOS should be + built. If this option is unset, it defaults to the platform + type of the machine where evaluation happens. Specifying this + option is useful when doing distributed multi-platform + deployment, or when building virtual machines. See its + description in the Nixpkgs manual for more details. + + Ignored when <code>nixpkgs.pkgs</code> is set. + ''; + }; + + crossSystem = mkOption { + type = types.nullOr types.attrs; # TODO utilize lib.systems.parsedPlatform + default = null; + example = { system = "aarch64-linux"; config = "aarch64-unknown-linux-gnu"; }; + description = '' + Specifies the platform for which NixOS should be + built. Specify this only if it is different from + <code>nixpkgs.localSystem</code>, the platform + <emphasis>on</emphasis> which NixOS should be built. In other + words, specify this to cross-compile NixOS. Otherwise it + should be set as null, the default. See its description in the + Nixpkgs manual for more details. + + Ignored when <code>nixpkgs.pkgs</code> is set. + ''; + }; + + system = mkOption { + type = types.str; + example = "i686-linux"; + description = '' + Specifies the Nix platform type on which NixOS should be built. + It is better to specify <code>nixpkgs.localSystem</code> instead. + <programlisting> + { + nixpkgs.system = ..; + } + </programlisting> + is the same as + <programlisting> + { + nixpkgs.localSystem.system = ..; + } + </programlisting> + See <code>nixpkgs.localSystem</code> for more information. + + Ignored when <code>nixpkgs.localSystem</code> is set. + Ignored when <code>nixpkgs.pkgs</code> is set. + ''; + }; + + initialSystem = mkOption { + type = types.str; + internal = true; + description = '' + Preserved value of <literal>system</literal> passed to <literal>eval-config.nix</literal>. + ''; + }; + }; + + config = { + _module.args = { + pkgs = finalPkgs; + }; + + assertions = [ + ( + let + nixosExpectedSystem = + if config.nixpkgs.crossSystem != null + then config.nixpkgs.crossSystem.system or (lib.systems.parse.doubleFromSystem (lib.systems.parse.mkSystemFromString config.nixpkgs.crossSystem.config)) + else config.nixpkgs.localSystem.system or (lib.systems.parse.doubleFromSystem (lib.systems.parse.mkSystemFromString config.nixpkgs.localSystem.config)); + nixosOption = + if config.nixpkgs.crossSystem != null + then "nixpkgs.crossSystem" + else "nixpkgs.localSystem"; + pkgsSystem = finalPkgs.stdenv.targetPlatform.system; + in { + assertion = nixosExpectedSystem == pkgsSystem; + message = "The NixOS nixpkgs.pkgs option was set to a Nixpkgs invocation that compiles to target system ${pkgsSystem} but NixOS was configured for system ${nixosExpectedSystem} via NixOS option ${nixosOption}. The NixOS system settings must match the Nixpkgs target system."; + } + ) + ]; + }; + + # needs a full nixpkgs path to import nixpkgs + meta.buildDocsInSandbox = false; +} diff --git a/nixos/modules/misc/nixpkgs/test.nix b/nixos/modules/misc/nixpkgs/test.nix new file mode 100644 index 00000000000..ec5fab9fb4a --- /dev/null +++ b/nixos/modules/misc/nixpkgs/test.nix @@ -0,0 +1,8 @@ +{ evalMinimalConfig, pkgs, lib, stdenv }: +lib.recurseIntoAttrs { + invokeNixpkgsSimple = + (evalMinimalConfig ({ config, modulesPath, ... }: { + imports = [ (modulesPath + "/misc/nixpkgs.nix") ]; + nixpkgs.system = stdenv.hostPlatform.system; + }))._module.args.pkgs.hello; +} diff --git a/nixos/modules/misc/passthru.nix b/nixos/modules/misc/passthru.nix new file mode 100644 index 00000000000..4e99631fdd8 --- /dev/null +++ b/nixos/modules/misc/passthru.nix @@ -0,0 +1,16 @@ +# This module allows you to export something from configuration +# Use case: export kernel source expression for ease of configuring + +{ lib, ... }: + +{ + options = { + passthru = lib.mkOption { + visible = false; + description = '' + This attribute set will be exported as a system attribute. + You can put whatever you want here. + ''; + }; + }; +} diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix new file mode 100644 index 00000000000..d825f4beb30 --- /dev/null +++ b/nixos/modules/misc/version.nix @@ -0,0 +1,141 @@ +{ config, lib, options, pkgs, ... }: + +let + cfg = config.system.nixos; + opt = options.system.nixos; + + inherit (lib) + concatStringsSep mapAttrsToList toLower + literalExpression mkRenamedOptionModule mkDefault mkOption trivial types; + + needsEscaping = s: null != builtins.match "[a-zA-Z0-9]+" s; + escapeIfNeccessary = s: if needsEscaping s then s else ''"${lib.escape [ "\$" "\"" "\\" "\`" ] s}"''; + attrsToText = attrs: + concatStringsSep "\n" ( + mapAttrsToList (n: v: ''${n}=${escapeIfNeccessary (toString v)}'') attrs + ); + +in +{ + imports = [ + (mkRenamedOptionModule [ "system" "nixosVersion" ] [ "system" "nixos" "version" ]) + (mkRenamedOptionModule [ "system" "nixosVersionSuffix" ] [ "system" "nixos" "versionSuffix" ]) + (mkRenamedOptionModule [ "system" "nixosRevision" ] [ "system" "nixos" "revision" ]) + (mkRenamedOptionModule [ "system" "nixosLabel" ] [ "system" "nixos" "label" ]) + ]; + + options.system = { + + nixos.version = mkOption { + internal = true; + type = types.str; + description = "The full NixOS version (e.g. <literal>16.03.1160.f2d4ee1</literal>)."; + }; + + nixos.release = mkOption { + readOnly = true; + type = types.str; + default = trivial.release; + description = "The NixOS release (e.g. <literal>16.03</literal>)."; + }; + + nixos.versionSuffix = mkOption { + internal = true; + type = types.str; + default = trivial.versionSuffix; + description = "The NixOS version suffix (e.g. <literal>1160.f2d4ee1</literal>)."; + }; + + nixos.revision = mkOption { + internal = true; + type = types.nullOr types.str; + default = trivial.revisionWithDefault null; + description = "The Git revision from which this NixOS configuration was built."; + }; + + nixos.codeName = mkOption { + readOnly = true; + type = types.str; + default = trivial.codeName; + description = "The NixOS release code name (e.g. <literal>Emu</literal>)."; + }; + + stateVersion = mkOption { + type = types.str; + default = cfg.release; + defaultText = literalExpression "config.${opt.release}"; + description = '' + Every once in a while, a new NixOS release may change + configuration defaults in a way incompatible with stateful + data. For instance, if the default version of PostgreSQL + changes, the new version will probably be unable to read your + existing databases. To prevent such breakage, you should set the + value of this option to the NixOS release with which you want + to be compatible. The effect is that NixOS will use + defaults corresponding to the specified release (such as using + an older version of PostgreSQL). + It‘s perfectly fine and recommended to leave this value at the + release version of the first install of this system. + Changing this option will not upgrade your system. In fact it + is meant to stay constant exactly when you upgrade your system. + You should only bump this option, if you are sure that you can + or have migrated all state on your system which is affected + by this option. + ''; + }; + + defaultChannel = mkOption { + internal = true; + type = types.str; + default = "https://nixos.org/channels/nixos-unstable"; + description = "Default NixOS channel to which the root user is subscribed."; + }; + + configurationRevision = mkOption { + type = types.nullOr types.str; + default = null; + description = "The Git revision of the top-level flake from which this configuration was built."; + }; + + }; + + config = { + + system.nixos = { + # These defaults are set here rather than up there so that + # changing them would not rebuild the manual + version = mkDefault (cfg.release + cfg.versionSuffix); + }; + + # Generate /etc/os-release. See + # https://www.freedesktop.org/software/systemd/man/os-release.html for the + # format. + environment.etc = { + "lsb-release".text = attrsToText { + LSB_VERSION = "${cfg.release} (${cfg.codeName})"; + DISTRIB_ID = "nixos"; + DISTRIB_RELEASE = cfg.release; + DISTRIB_CODENAME = toLower cfg.codeName; + DISTRIB_DESCRIPTION = "NixOS ${cfg.release} (${cfg.codeName})"; + }; + + "os-release".text = attrsToText { + NAME = "NixOS"; + ID = "nixos"; + VERSION = "${cfg.release} (${cfg.codeName})"; + VERSION_CODENAME = toLower cfg.codeName; + VERSION_ID = cfg.release; + BUILD_ID = cfg.version; + PRETTY_NAME = "NixOS ${cfg.release} (${cfg.codeName})"; + LOGO = "nix-snowflake"; + HOME_URL = "https://nixos.org/"; + DOCUMENTATION_URL = "https://nixos.org/learn.html"; + SUPPORT_URL = "https://nixos.org/community.html"; + BUG_REPORT_URL = "https://github.com/NixOS/nixpkgs/issues"; + }; + }; + }; + + # uses version info nixpkgs, which requires a full nixpkgs path + meta.buildDocsInSandbox = false; +} diff --git a/nixos/modules/misc/wordlist.nix b/nixos/modules/misc/wordlist.nix new file mode 100644 index 00000000000..988b522d743 --- /dev/null +++ b/nixos/modules/misc/wordlist.nix @@ -0,0 +1,59 @@ +{ config, lib, pkgs, ... }: +with lib; +let + concatAndSort = name: files: pkgs.runCommand name {} '' + awk 1 ${lib.escapeShellArgs files} | sed '{ /^\s*$/d; s/^\s\+//; s/\s\+$// }' | sort | uniq > $out + ''; +in +{ + options = { + environment.wordlist = { + enable = mkEnableOption "environment variables for lists of words"; + + lists = mkOption { + type = types.attrsOf (types.nonEmptyListOf types.path); + + default = { + WORDLIST = [ "${pkgs.scowl}/share/dict/words.txt" ]; + }; + + defaultText = literalExpression '' + { + WORDLIST = [ "''${pkgs.scowl}/share/dict/words.txt" ]; + } + ''; + + description = '' + A set with the key names being the environment variable you'd like to + set and the values being a list of paths to text documents containing + lists of words. The various files will be merged, sorted, duplicates + removed, and extraneous spacing removed. + + If you have a handful of words that you want to add to an already + existing wordlist, you may find `builtins.toFile` useful for this + task. + ''; + + example = literalExpression '' + { + WORDLIST = [ "''${pkgs.scowl}/share/dict/words.txt" ]; + AUGMENTED_WORDLIST = [ + "''${pkgs.scowl}/share/dict/words.txt" + "''${pkgs.scowl}/share/dict/words.variants.txt" + (builtins.toFile "extra-words" ''' + desynchonization + oobleck''') + ]; + } + ''; + }; + }; + }; + + config = mkIf config.environment.wordlist.enable { + environment.variables = + lib.mapAttrs + (name: value: "${concatAndSort "wordlist-${name}" value}") + config.environment.wordlist.lists; + }; +} |