diff --git a/lib/options.nix b/lib/options.nix
index 444ec37e6eaf3..c32d298890c15 100644
--- a/lib/options.nix
+++ b/lib/options.nix
@@ -15,6 +15,7 @@ rec {
, defaultText ? null # Textual representation of the default, for in the manual.
, example ? null # Example value used in the manual.
, description ? null # String describing the option.
+ , packages ? [] # Related packages to be specified with `literalPackages*' functions
, type ? null # Option type, providing type-checking and value merging.
, apply ? null # Function that converts the option value to something else.
, internal ? null # Whether the option is for NixOS developers only.
@@ -24,13 +25,56 @@ rec {
} @ attrs:
attrs // { _type = "option"; };
- mkEnableOption = name: mkOption {
- default = false;
- example = true;
- description = "Whether to enable ${name}.";
- type = lib.types.bool;
+ # A boolean which determines whenever to do (or not to do) something.
+ mkWheneverToOption =
+ { default ? false
+ , what
+ , description ? null
+ , ...
+ } @ attrs:
+ mkOption ((removeAttrs attrs [ "what" ]) // {
+ inherit default;
+ example = !default;
+ type = lib.types.bool;
+ description = ''
+ Whether to ${what}.
+
+ ${optionalString (description != null) description}
+ '';
+ });
+
+ mkWheneverToPkgOption =
+ { description ? null
+ , broken ? false
+ , package ? null
+ , packages ? []
+ , ...
+ } @ attrs: let
+ pkgs = optional (package != null) package
+ ++ packages;
+ in
+ mkWheneverToOption (removeAttrs attrs [ "broken" "package" ] // {
+ description = ''
+ ${optionalString (description != null) description}
+
+ ${if broken then "THIS IS BROKEN."
+ else if (length pkgs > 1) then "Related packages:"
+ else if (length pkgs == 1) then "The package is:"
+ else ""}
+ '';
+ # Don't evaluate when marked as broken
+ packages = optional (!broken && package != null) package;
+ });
+
+ mkEnableOption = name: mkWheneverToPkgOption {
+ what = "enable ${name}";
};
+ mkEnableOption' = { name ? null, ... } @ attrs:
+ mkWheneverToPkgOption (removeAttrs attrs [ "name" ] // {
+ what = "enable ${name}";
+ });
+
# This option accept anything, but it does not produce any result. This
# is useful for sharing a module across different module sets without
# having to implement similar features as long as the value of the options
@@ -77,6 +121,16 @@ rec {
getValues = map (x: x.value);
getFiles = map (x: x.file);
+ # Generate DocBook documentation for a list of packages
+ packageListToDocString = packages:
+ let
+ describePkg = n: p:
+ ""
+ + " (${p.name}): ${p.meta.description or "???"}."
+ # Lots of `longDescription's break DocBook, so we just wrap them into
+ + optionalString (p.meta ? longDescription) "\n${p.meta.longDescription}"
+ + "";
+ in "${concatStringsSep "\n" (map ({name, value}: describePkg name value) packages)}";
# Generate documentation template from the list of option declaration like
# the set generated with filterOptionSets.
@@ -87,16 +141,17 @@ rec {
let
docOption = rec {
name = showOption opt.loc;
- description = opt.description or (throw "Option `${name}' has no description.");
+ description = (opt.description or (throw "Option `${name}' has no description."))
+ + optionalString (opt ? packages && opt.packages != []) "\n\n${packageListToDocString opt.packages}";
declarations = filter (x: x != unknownModule) opt.declarations;
internal = opt.internal or false;
visible = opt.visible or true;
readOnly = opt.readOnly or false;
type = opt.type.name or null;
}
- // (if opt ? example then { example = scrubOptionValue opt.example; } else {})
- // (if opt ? default then { default = scrubOptionValue opt.default; } else {})
- // (if opt ? defaultText then { default = opt.defaultText; } else {});
+ // (optionalAttrs (opt ? example) { example = scrubOptionValue opt.example; })
+ // (optionalAttrs (opt ? default) { default = scrubOptionValue opt.default; })
+ // (optionalAttrs (opt ? defaultText) { default = opt.defaultText; });
subOptions =
let ss = opt.type.getSubOptions opt.loc;
@@ -124,6 +179,14 @@ rec {
functions. */
literalExample = text: { _type = "literalExample"; inherit text; };
+ /* For use in the ‘packages’ option attribute. */
+ literalPackage' = pkgs: n: p: nameValuePair "${optionalString (n != "") (n + ".")}${p}" (getAttrFromPath (splitString "." p) pkgs);
+
+ literalPackages' = pkgs: n: l: map (literalPackage' pkgs n) l;
+
+ literalPackage = pkgs: n: literalPackage' { inherit pkgs; } "" n;
+
+ literalPackages = pkgs: l: literalPackages' { inherit pkgs; } "" l;
/* Helper functions. */
showOption = concatStringsSep ".";
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
index 86a39322ba510..569b2942d37cf 100644
--- a/nixos/doc/manual/default.nix
+++ b/nixos/doc/manual/default.nix
@@ -15,14 +15,6 @@ let
else if builtins.isFunction x then ""
else x;
- # Clean up declaration sites to not refer to the NixOS source tree.
- optionsList' = flip map optionsList (opt: opt // {
- declarations = map stripAnyPrefixes opt.declarations;
- }
- // optionalAttrs (opt ? example) { example = substFunction opt.example; }
- // optionalAttrs (opt ? default) { default = substFunction opt.default; }
- // optionalAttrs (opt ? type) { type = substFunction opt.type; });
-
# We need to strip references to /nix/store/* from options,
# including any `extraSources` if some modules came from elsewhere,
# or else the build will fail.
@@ -32,8 +24,25 @@ let
prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
stripAnyPrefixes = flip (fold removePrefix) prefixesToStrip;
+ # Clean up declaration sites to not refer to the NixOS source tree.
+ optionsList' = flip map optionsList (opt: opt // {
+ declarations = map stripAnyPrefixes opt.declarations;
+ }
+ // optionalAttrs (opt ? example) { example = substFunction opt.example; }
+ // optionalAttrs (opt ? default) { default = substFunction opt.default; }
+ // optionalAttrs (opt ? type) { type = substFunction opt.type; });
+
+ # Custom "less" that pushes up all the things ending in ".enable*"
+ isEnable = x: hasPrefix "enable" (last (splitString "." x));
+ enableFirst = a: b: if isEnable a && !isEnable b then true
+ else if !isEnable a && isEnable b then false
+ else a < b;
+
+ # Customly sort option list for the man page.
+ optionsList'' = sort (a: b: enableFirst a.name b.name) optionsList';
+
# Convert the list of options into an XML file.
- optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList');
+ optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList'');
optionsDocBook = runCommand "options-db.xml" {} ''
optionsXML=${optionsXML}
diff --git a/nixos/modules/hardware/ksm.nix b/nixos/modules/hardware/ksm.nix
index d6ac69b5d65e9..7386eaeb6bd0a 100644
--- a/nixos/modules/hardware/ksm.nix
+++ b/nixos/modules/hardware/ksm.nix
@@ -1,7 +1,9 @@
{ config, lib, ... }:
{
- options.hardware.enableKSM = lib.mkEnableOption "Kernel Same-Page Merging";
+ options.hardware.enableKSM = lib.mkEnableOption' {
+ name = "Kernel Same-Page Merging";
+ };
config = lib.mkIf config.hardware.enableKSM {
systemd.services.enable-ksm = {
diff --git a/nixos/modules/hardware/video/webcam/facetimehd.nix b/nixos/modules/hardware/video/webcam/facetimehd.nix
index b35709763b903..f6e4742010038 100644
--- a/nixos/modules/hardware/video/webcam/facetimehd.nix
+++ b/nixos/modules/hardware/video/webcam/facetimehd.nix
@@ -12,7 +12,10 @@ in
{
- options.hardware.facetimehd.enable = mkEnableOption "facetimehd kernel module";
+ options.hardware.facetimehd.enable = mkEnableOption' {
+ name = "facetimehd kernel module";
+ package = literalPackage' kernelPackages "kernelPackages" "facetimehd";
+ };
config = mkIf cfg.enable {
diff --git a/nixos/modules/programs/atop.nix b/nixos/modules/programs/atop.nix
index b91bd98047ee1..6d96fbbfe4edb 100644
--- a/nixos/modules/programs/atop.nix
+++ b/nixos/modules/programs/atop.nix
@@ -14,6 +14,11 @@ in
programs.atop = {
+ enable = mkWheneverToPkgOption {
+ what = "globally configure atop";
+ package = literalPackage pkgs "pkgs.atop";
+ };
+
settings = mkOption {
type = types.attrs;
default = {};
@@ -29,7 +34,7 @@ in
};
};
- config = mkIf (cfg.settings != {}) {
+ config = mkIf cfg.enable {
environment.etc."atoprc".text =
concatStrings (mapAttrsToList (n: v: "${n} ${toString v}\n") cfg.settings);
};
diff --git a/nixos/modules/programs/blcr.nix b/nixos/modules/programs/blcr.nix
index 804e1d01f12b8..1c82f71e47ed5 100644
--- a/nixos/modules/programs/blcr.nix
+++ b/nixos/modules/programs/blcr.nix
@@ -1,19 +1,19 @@
{ config, lib, ... }:
+with lib;
+
let
- inherit (lib) mkOption mkIf;
cfg = config.environment.blcr;
- blcrPkg = config.boot.kernelPackages.blcr;
+ kp = config.boot.kernelPackages;
in
{
###### interface
options = {
- environment.blcr.enable = mkOption {
- default = false;
- description =
- "Whether to enable support for the BLCR checkpointing tool.";
+ environment.blcr.enable = mkEnableOption' {
+ name = "support for the BLCR checkpointing tool";
+ #asserts #package = literalPackage' kp "kernelPackages" "blcr";
};
};
@@ -21,7 +21,7 @@ in
config = mkIf cfg.enable {
boot.kernelModules = [ "blcr" "blcr_imports" ];
- boot.extraModulePackages = [ blcrPkg ];
- environment.systemPackages = [ blcrPkg ];
+ boot.extraModulePackages = [ kp.blcr ];
+ environment.systemPackages = [ kp.blcr ];
};
}
diff --git a/nixos/modules/programs/cdemu.nix b/nixos/modules/programs/cdemu.nix
index 6a0185d362c50..e679d7f9793d4 100644
--- a/nixos/modules/programs/cdemu.nix
+++ b/nixos/modules/programs/cdemu.nix
@@ -7,13 +7,12 @@ in {
options = {
programs.cdemu = {
- enable = mkOption {
- default = false;
- description = ''
- cdemu for members of
- .
- '';
+
+ enable = mkWheneverToPkgOption {
+ what = "globally configure cdemu";
+ package = literalPackage pkgs "pkgs.cdemu-daemon";
};
+
group = mkOption {
default = "cdrom";
description = ''
diff --git a/nixos/modules/programs/kbdlight.nix b/nixos/modules/programs/kbdlight.nix
index 0172368e968fa..6994e35e7e67f 100644
--- a/nixos/modules/programs/kbdlight.nix
+++ b/nixos/modules/programs/kbdlight.nix
@@ -7,7 +7,10 @@ let
in
{
- options.programs.kbdlight.enable = mkEnableOption "kbdlight";
+ options.programs.kbdlight.enable = mkEnableOption' {
+ name = "kbdlight";
+ package = literalPackage pkgs "pkgs.kbdlight";
+ };
config = mkIf cfg.enable {
environment.systemPackages = [ pkgs.kbdlight ];
diff --git a/nixos/modules/programs/tmux.nix b/nixos/modules/programs/tmux.nix
index 4220a2e17b3fd..d8af40fed6a85 100644
--- a/nixos/modules/programs/tmux.nix
+++ b/nixos/modules/programs/tmux.nix
@@ -1,7 +1,8 @@
{ config, pkgs, lib, ... }:
+with lib;
+
let
- inherit (lib) mkOption mkEnableOption mkIf mkMerge types;
cfg = config.programs.tmux;
@@ -12,7 +13,10 @@ in
options = {
programs.tmux = {
- enable = mkEnableOption "tmux - a screen replacement.";
+ enable = mkWheneverToPkgOption {
+ what = "globally configure tmux";
+ package = literalPackage pkgs "pkgs.tmux";
+ };
tmuxconf = mkOption {
default = "";
diff --git a/nixos/modules/services/audio/icecast.nix b/nixos/modules/services/audio/icecast.nix
index 6a8a0f9975b3b..47a8bff83d46a 100644
--- a/nixos/modules/services/audio/icecast.nix
+++ b/nixos/modules/services/audio/icecast.nix
@@ -44,7 +44,10 @@ in {
services.icecast = {
- enable = mkEnableOption "Icecast server";
+ enable = mkEnableOption' {
+ name = "Icecast server";
+ package = literalPackage pkgs "pkgs.icecast";
+ };
hostname = mkOption {
type = types.str;
diff --git a/nixos/modules/services/backup/rsnapshot.nix b/nixos/modules/services/backup/rsnapshot.nix
index 96657cf17fc5f..55c2b00e4b3c3 100644
--- a/nixos/modules/services/backup/rsnapshot.nix
+++ b/nixos/modules/services/backup/rsnapshot.nix
@@ -7,7 +7,11 @@ in
{
options = {
services.rsnapshot = {
- enable = mkEnableOption "rsnapshot backups";
+
+ enable = mkWheneverToPkgOption {
+ what = "enable backups with rsnapshot";
+ package = literalPackage pkgs "pkgs.rsnapshot";
+ };
extraConfig = mkOption {
default = "";
diff --git a/nixos/modules/services/backup/znapzend.nix b/nixos/modules/services/backup/znapzend.nix
index 648089f90b7b4..14fd5c2f1be33 100644
--- a/nixos/modules/services/backup/znapzend.nix
+++ b/nixos/modules/services/backup/znapzend.nix
@@ -8,7 +8,12 @@ in
{
options = {
services.znapzend = {
- enable = mkEnableOption "ZnapZend daemon";
+
+ enable = mkWheneverToPkgOption {
+ what = "enable backups with ZsnapZend";
+ package = literalPackage pkgs "pkgs.znapzend";
+ };
+
};
};
diff --git a/nixos/modules/services/databases/riak.nix b/nixos/modules/services/databases/riak.nix
index bee768fa42aed..6094f617800e4 100644
--- a/nixos/modules/services/databases/riak.nix
+++ b/nixos/modules/services/databases/riak.nix
@@ -16,7 +16,11 @@ in
services.riak = {
- enable = mkEnableOption "riak";
+ enable = mkEnableOption' {
+ name = "riak";
+ broken = true;
+ package = literalPackage pkgs "pkgs.riak";
+ };
package = mkOption {
type = types.package;
diff --git a/nixos/modules/services/hardware/irqbalance.nix b/nixos/modules/services/hardware/irqbalance.nix
index b139154432cf9..8186d4cd1251f 100644
--- a/nixos/modules/services/hardware/irqbalance.nix
+++ b/nixos/modules/services/hardware/irqbalance.nix
@@ -9,7 +9,10 @@ let
in
{
- options.services.irqbalance.enable = mkEnableOption "irqbalance daemon";
+ options.services.irqbalance.enable = mkEnableOption' {
+ name = "irqbalance daemon";
+ package = literalPackage pkgs "pkgs.irqbalance";
+ };
config = mkIf cfg.enable {
diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix
index 127c3da69d14f..aee3542a6a4fc 100644
--- a/nixos/modules/services/mail/dovecot.nix
+++ b/nixos/modules/services/mail/dovecot.nix
@@ -70,7 +70,10 @@ in
{
options.services.dovecot2 = {
- enable = mkEnableOption "Dovecot 2.x POP3/IMAP server";
+ enable = mkEnableOption' {
+ name = "Dovecot POP3/IMAP server";
+ package = literalPackage pkgs "pkgs.dovecot";
+ };
enablePop3 = mkOption {
type = types.bool;
diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix
index bad9d527f9a1d..3f9addac608aa 100644
--- a/nixos/modules/services/mail/postfix.nix
+++ b/nixos/modules/services/mail/postfix.nix
@@ -191,10 +191,9 @@ in
services.postfix = {
- enable = mkOption {
- type = types.bool;
- default = false;
- description = "Whether to run the Postfix mail server.";
+ enable = mkEnableOption' {
+ name = "Postfix mail server";
+ package = literalPackage pkgs "pkgs.postfix";
};
enableSmtp = mkOption {
diff --git a/nixos/modules/services/misc/calibre-server.nix b/nixos/modules/services/misc/calibre-server.nix
index a920aa22ccdf6..fa6fe4ca8f225 100644
--- a/nixos/modules/services/misc/calibre-server.nix
+++ b/nixos/modules/services/misc/calibre-server.nix
@@ -16,7 +16,10 @@ in
services.calibre-server = {
- enable = mkEnableOption "calibre-server";
+ enable = mkEnableOption' {
+ name = "calibre-server";
+ package = literalPackage pkgs "pkgs.calibre";
+ };
libraryDir = mkOption {
description = ''
diff --git a/nixos/modules/services/misc/confd.nix b/nixos/modules/services/misc/confd.nix
index c0fbf06e6c4c1..4fd1a2c40b5da 100644
--- a/nixos/modules/services/misc/confd.nix
+++ b/nixos/modules/services/misc/confd.nix
@@ -17,7 +17,10 @@ let
in {
options.services.confd = {
- enable = mkEnableOption "confd service";
+ enable = mkEnableOption' {
+ name = "confd service";
+ package = literalPackage pkgs "pkgs.confd";
+ };
backend = mkOption {
description = "Confd config storage backend to use.";
diff --git a/nixos/modules/services/misc/gammu-smsd.nix b/nixos/modules/services/misc/gammu-smsd.nix
index 2d406b6344371..a720f73f5707d 100644
--- a/nixos/modules/services/misc/gammu-smsd.nix
+++ b/nixos/modules/services/misc/gammu-smsd.nix
@@ -53,7 +53,10 @@ in {
options = {
services.gammu-smsd = {
- enable = mkEnableOption "gammu-smsd daemon";
+ enable = mkEnableOption' {
+ name = "gammu-smsd daemon";
+ package = literalPackage pkgs "pkgs.gammu";
+ };
user = mkOption {
type = types.str;
diff --git a/nixos/modules/services/misc/matrix-synapse.nix b/nixos/modules/services/misc/matrix-synapse.nix
index 0ae0516769c05..ffa27074b99c2 100644
--- a/nixos/modules/services/misc/matrix-synapse.nix
+++ b/nixos/modules/services/misc/matrix-synapse.nix
@@ -57,7 +57,11 @@ ${cfg.extraConfig}
in {
options = {
services.matrix-synapse = {
- enable = mkEnableOption "matrix.org synapse";
+ enable = mkEnableOption' {
+ name = "matrix.org synapse";
+ package = literalPackage pkgs "pkgs.matrix-synapse";
+ };
+
package = mkOption {
type = types.package;
default = pkgs.matrix-synapse;
diff --git a/nixos/modules/services/misc/plex.nix b/nixos/modules/services/misc/plex.nix
index 92b352db416c2..6d5425ce5f14c 100644
--- a/nixos/modules/services/misc/plex.nix
+++ b/nixos/modules/services/misc/plex.nix
@@ -9,7 +9,10 @@ in
{
options = {
services.plex = {
- enable = mkEnableOption "Plex Media Server";
+ enable = mkEnableOption' {
+ name = "Plex Media Server";
+ #unfree #package = literalPackage pkgs "pkgs.plex";
+ };
# FIXME: In order for this config option to work, symlinks in the Plex
# package in the Nix store have to be changed to point to this directory.
diff --git a/nixos/modules/services/misc/ripple-data-api.nix b/nixos/modules/services/misc/ripple-data-api.nix
index dbca56b13335e..43bfe3ce60248 100644
--- a/nixos/modules/services/misc/ripple-data-api.nix
+++ b/nixos/modules/services/misc/ripple-data-api.nix
@@ -35,7 +35,11 @@ let
in {
options = {
services.rippleDataApi = {
- enable = mkEnableOption "ripple data api";
+ enable = mkEnableOption' {
+ name = "ripple data api";
+ broken = true; # does not exists
+ package = literalPackage pkgs "pkgs.ripple-data-api";
+ };
port = mkOption {
description = "Ripple data api port";
diff --git a/nixos/modules/services/misc/rippled.nix b/nixos/modules/services/misc/rippled.nix
index c6b67e8498ca8..6549bffca1d08 100644
--- a/nixos/modules/services/misc/rippled.nix
+++ b/nixos/modules/services/misc/rippled.nix
@@ -202,7 +202,10 @@ in
options = {
services.rippled = {
- enable = mkEnableOption "rippled";
+ enable = mkEnableOption' {
+ name = "rippled";
+ #unfree #package = literalPackage pkgs "pkgs.rippled";
+ };
package = mkOption {
description = "Which rippled package to use.";
@@ -374,7 +377,10 @@ in
};
statsd = {
- enable = mkEnableOption "statsd monitoring for rippled";
+ enable = mkEnableOption' {
+ name = "statsd monitoring for rippled";
+ #unfree #package = literalPackage pkgs "pkgs.rippled";
+ };
address = mkOption {
description = "The UDP address and port of the listening StatsD server.";
diff --git a/nixos/modules/services/monitoring/uptime.nix b/nixos/modules/services/monitoring/uptime.nix
index 29616a085c8f3..526345e4220ea 100644
--- a/nixos/modules/services/monitoring/uptime.nix
+++ b/nixos/modules/services/monitoring/uptime.nix
@@ -1,7 +1,8 @@
{ config, pkgs, lib, ... }:
-let
- inherit (lib) mkOption mkEnableOption mkIf mkMerge types optionalAttrs optional;
+with lib;
+
+let
cfg = config.services.uptime;
configDir = pkgs.runCommand "config" {} (if cfg.configFile != null then ''
@@ -49,9 +50,15 @@ in {
type = types.bool;
};
- enableWebService = mkEnableOption "the uptime monitoring program web service";
+ enableWebService = mkEnableOption' {
+ name = "the uptime monitoring program web service";
+ package = literalPackage pkgs "pkgs.nodePackages.node-uptime";
+ };
- enableSeparateMonitoringService = mkEnableOption "the uptime monitoring service" // { default = cfg.enableWebService; };
+ enableSeparateMonitoringService = mkEnableOption' {
+ name = "the uptime monitoring service";
+ default = cfg.enableWebService;
+ };
nodeEnv = mkOption {
description = "The node environment to run in (development, production, etc.)";
diff --git a/nixos/modules/services/networking/nsd.nix b/nixos/modules/services/networking/nsd.nix
index 333a3378c4cc1..be021e702f6dc 100644
--- a/nixos/modules/services/networking/nsd.nix
+++ b/nixos/modules/services/networking/nsd.nix
@@ -330,7 +330,10 @@ in
# options are ordered alphanumerically
options.services.nsd = {
- enable = mkEnableOption "NSD authoritative DNS server";
+ enable = mkEnableOption' {
+ name = "NSD authoritative DNS server";
+ package = literalPackage pkgs "pkgs.nsd";
+ };
bind8Stats = mkEnableOption "BIND8 like statistics";
diff --git a/nixos/modules/services/networking/wpa_supplicant.nix b/nixos/modules/services/networking/wpa_supplicant.nix
index 53648aef1e044..ea6b7f59828df 100644
--- a/nixos/modules/services/networking/wpa_supplicant.nix
+++ b/nixos/modules/services/networking/wpa_supplicant.nix
@@ -23,7 +23,10 @@ let
in {
options = {
networking.wireless = {
- enable = mkEnableOption "wpa_supplicant";
+ enable = mkEnableOption' {
+ name = "wpa_supplicant";
+ package = literalPackage pkgs "pkgs.wpa_supplicant";
+ };
interfaces = mkOption {
type = types.listOf types.str;