2021-07-03 16:14:03 +02:00
|
|
|
|
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-option-declarations">
|
|
|
|
|
<title>Option Declarations</title>
|
|
|
|
|
<para>
|
|
|
|
|
An option declaration specifies the name, type and description of a
|
|
|
|
|
NixOS configuration option. It is invalid to define an option that
|
|
|
|
|
hasn’t been declared in any module. An option declaration generally
|
|
|
|
|
looks like this:
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting language="bash">
|
|
|
|
|
options = {
|
|
|
|
|
name = mkOption {
|
|
|
|
|
type = type specification;
|
|
|
|
|
default = default value;
|
|
|
|
|
example = example value;
|
|
|
|
|
description = "Description for use in the NixOS manual.";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
|
|
|
|
<para>
|
|
|
|
|
The attribute names within the <literal>name</literal> attribute
|
|
|
|
|
path must be camel cased in general but should, as an exception,
|
|
|
|
|
match the
|
|
|
|
|
<link xlink:href="https://nixos.org/nixpkgs/manual/#sec-package-naming">
|
|
|
|
|
package attribute name</link> when referencing a Nixpkgs package.
|
|
|
|
|
For example, the option
|
|
|
|
|
<literal>services.nix-serve.bindAddress</literal> references the
|
|
|
|
|
<literal>nix-serve</literal> Nixpkgs package.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
The function <literal>mkOption</literal> accepts the following
|
|
|
|
|
arguments.
|
|
|
|
|
</para>
|
|
|
|
|
<variablelist>
|
|
|
|
|
<varlistentry>
|
|
|
|
|
<term>
|
|
|
|
|
<literal>type</literal>
|
|
|
|
|
</term>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
The type of the option (see
|
2021-06-16 12:27:47 +02:00
|
|
|
|
<xref linkend="sec-option-types" />). This argument is
|
|
|
|
|
mandatory for nixpkgs modules. Setting this is highly
|
|
|
|
|
recommended for the sake of documentation and type checking.
|
|
|
|
|
In case it is not set, a fallback type with unspecified
|
|
|
|
|
behavior is used.
|
2021-07-03 16:14:03 +02:00
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
|
|
|
|
<varlistentry>
|
|
|
|
|
<term>
|
|
|
|
|
<literal>default</literal>
|
|
|
|
|
</term>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
The default value used if no value is defined by any module. A
|
|
|
|
|
default is not required; but if a default is not given, then
|
|
|
|
|
users of the module will have to define the value of the
|
|
|
|
|
option, otherwise an error will be thrown.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
2021-10-03 18:06:03 +02:00
|
|
|
|
<varlistentry>
|
|
|
|
|
<term>
|
|
|
|
|
<literal>defaultText</literal>
|
|
|
|
|
</term>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
A textual representation of the default value to be rendered
|
|
|
|
|
verbatim in the manual. Useful if the default value is a
|
|
|
|
|
complex expression or depends on other values or packages. Use
|
|
|
|
|
<literal>lib.literalExpression</literal> for a Nix expression,
|
|
|
|
|
<literal>lib.literalDocBook</literal> for a plain English
|
|
|
|
|
description in DocBook format.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
2021-07-03 16:14:03 +02:00
|
|
|
|
<varlistentry>
|
|
|
|
|
<term>
|
|
|
|
|
<literal>example</literal>
|
|
|
|
|
</term>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
2021-10-03 18:06:03 +02:00
|
|
|
|
An example value that will be shown in the NixOS manual. You
|
|
|
|
|
can use <literal>lib.literalExpression</literal> and
|
|
|
|
|
<literal>lib.literalDocBook</literal> in the same way as in
|
|
|
|
|
<literal>defaultText</literal>.
|
2021-07-03 16:14:03 +02:00
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
|
|
|
|
<varlistentry>
|
|
|
|
|
<term>
|
|
|
|
|
<literal>description</literal>
|
|
|
|
|
</term>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
|
|
|
|
A textual description of the option, in DocBook format, that
|
|
|
|
|
will be included in the NixOS manual.
|
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
|
|
|
|
</variablelist>
|
2022-01-21 10:41:34 +01:00
|
|
|
|
<section xml:id="sec-option-declarations-util">
|
|
|
|
|
<title>Utility functions for common option patterns</title>
|
|
|
|
|
<section xml:id="sec-option-declarations-util-mkEnableOption">
|
|
|
|
|
<title><literal>mkEnableOption</literal></title>
|
|
|
|
|
<para>
|
|
|
|
|
Creates an Option attribute set for a boolean value option i.e
|
|
|
|
|
an option to be toggled on or off.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
This function takes a single string argument, the name of the
|
|
|
|
|
thing to be toggled.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
The option’s description is <quote>Whether to enable
|
|
|
|
|
<name>.</quote>.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
For example:
|
|
|
|
|
</para>
|
|
|
|
|
<anchor xml:id="ex-options-declarations-util-mkEnableOption-magic" />
|
|
|
|
|
<programlisting language="bash">
|
|
|
|
|
lib.mkEnableOption "magic"
|
|
|
|
|
# is like
|
|
|
|
|
lib.mkOption {
|
|
|
|
|
type = lib.types.bool;
|
|
|
|
|
default = false;
|
|
|
|
|
example = true;
|
|
|
|
|
description = "Whether to enable magic.";
|
|
|
|
|
}
|
|
|
|
|
</programlisting>
|
|
|
|
|
<section xml:id="sec-option-declarations-util-mkPackageOption">
|
|
|
|
|
<title><literal>mkPackageOption</literal></title>
|
2021-07-03 16:14:03 +02:00
|
|
|
|
<para>
|
2022-01-21 10:41:34 +01:00
|
|
|
|
Usage:
|
2021-07-03 16:14:03 +02:00
|
|
|
|
</para>
|
2022-01-21 10:41:34 +01:00
|
|
|
|
<programlisting language="bash">
|
|
|
|
|
mkPackageOption pkgs "name" { default = [ "path" "in" "pkgs" ]; example = "literal example"; }
|
|
|
|
|
</programlisting>
|
2021-07-03 16:14:03 +02:00
|
|
|
|
<para>
|
2022-01-21 10:41:34 +01:00
|
|
|
|
Creates an Option attribute set for an option that specifies
|
|
|
|
|
the package a module should use for some purpose.
|
2021-07-03 16:14:03 +02:00
|
|
|
|
</para>
|
2022-01-21 10:41:34 +01:00
|
|
|
|
<para>
|
|
|
|
|
<emphasis role="strong">Note</emphasis>: You shouldn’t
|
|
|
|
|
necessarily make package options for all of your modules. You
|
|
|
|
|
can always overwrite a specific package throughout nixpkgs by
|
|
|
|
|
using
|
|
|
|
|
<link xlink:href="https://nixos.org/manual/nixpkgs/stable/#chap-overlays">nixpkgs
|
|
|
|
|
overlays</link>.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
The default package is specified as a list of strings
|
|
|
|
|
representing its attribute path in nixpkgs. Because of this,
|
|
|
|
|
you need to pass nixpkgs itself as the first argument.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
The second argument is the name of the option, used in the
|
|
|
|
|
description <quote>The <name> package to use.</quote>.
|
|
|
|
|
You can also pass an example value, either a literal string or
|
|
|
|
|
a package’s attribute path.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
You can omit the default path if the name of the option is
|
|
|
|
|
also attribute path in nixpkgs.
|
|
|
|
|
</para>
|
|
|
|
|
<anchor xml:id="ex-options-declarations-util-mkPackageOption" />
|
|
|
|
|
<para>
|
|
|
|
|
Examples:
|
|
|
|
|
</para>
|
|
|
|
|
<anchor xml:id="ex-options-declarations-util-mkPackageOption-hello" />
|
|
|
|
|
<programlisting language="bash">
|
|
|
|
|
lib.mkPackageOption pkgs "hello" { }
|
|
|
|
|
# is like
|
|
|
|
|
lib.mkOption {
|
|
|
|
|
type = lib.types.package;
|
|
|
|
|
default = pkgs.hello;
|
|
|
|
|
defaultText = lib.literalExpression "pkgs.hello";
|
|
|
|
|
description = "The hello package to use.";
|
|
|
|
|
}
|
|
|
|
|
</programlisting>
|
|
|
|
|
<anchor xml:id="ex-options-declarations-util-mkPackageOption-ghc" />
|
|
|
|
|
<programlisting language="bash">
|
|
|
|
|
lib.mkPackageOption pkgs "GHC" {
|
|
|
|
|
default = [ "ghc" ];
|
2022-03-09 11:29:14 +01:00
|
|
|
|
example = "pkgs.haskell.package.ghc922.ghc.withPackages (hkgs: [ hkgs.primes ])";
|
2022-01-21 10:41:34 +01:00
|
|
|
|
}
|
|
|
|
|
# is like
|
|
|
|
|
lib.mkOption {
|
|
|
|
|
type = lib.types.package;
|
|
|
|
|
default = pkgs.ghc;
|
|
|
|
|
defaultText = lib.literalExpression "pkgs.ghc";
|
2022-03-09 11:29:14 +01:00
|
|
|
|
example = lib.literalExpression "pkgs.haskell.package.ghc922.ghc.withPackages (hkgs: [ hkgs.primes ])";
|
2022-01-21 10:41:34 +01:00
|
|
|
|
description = "The GHC package to use.";
|
|
|
|
|
}
|
|
|
|
|
</programlisting>
|
|
|
|
|
<section xml:id="sec-option-declarations-eot">
|
|
|
|
|
<title>Extensible Option Types</title>
|
|
|
|
|
<para>
|
|
|
|
|
Extensible option types is a feature that allow to extend
|
|
|
|
|
certain types declaration through multiple module files.
|
|
|
|
|
This feature only work with a restricted set of types,
|
|
|
|
|
namely <literal>enum</literal> and
|
|
|
|
|
<literal>submodules</literal> and any composed forms of
|
|
|
|
|
them.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Extensible option types can be used for
|
|
|
|
|
<literal>enum</literal> options that affects multiple
|
|
|
|
|
modules, or as an alternative to related
|
|
|
|
|
<literal>enable</literal> options.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
As an example, we will take the case of display managers.
|
|
|
|
|
There is a central display manager module for generic
|
|
|
|
|
display manager options and a module file per display
|
|
|
|
|
manager backend (sddm, gdm ...).
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
2022-03-04 21:08:09 +01:00
|
|
|
|
There are two approaches we could take with this module
|
|
|
|
|
structure:
|
2022-01-21 10:41:34 +01:00
|
|
|
|
</para>
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
2022-03-04 21:08:09 +01:00
|
|
|
|
Configuring the display managers independently by adding
|
|
|
|
|
an enable option to every display manager module
|
|
|
|
|
backend. (NixOS)
|
2022-01-21 10:41:34 +01:00
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>
|
2022-03-04 21:08:09 +01:00
|
|
|
|
Configuring the display managers in the central module
|
|
|
|
|
by adding an option to select which display manager
|
|
|
|
|
backend to use.
|
2022-01-21 10:41:34 +01:00
|
|
|
|
</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
<para>
|
|
|
|
|
Both approaches have problems.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Making backends independent can quickly become hard to
|
2022-03-04 21:08:09 +01:00
|
|
|
|
manage. For display managers, there can only be one enabled
|
|
|
|
|
at a time, but the type system cannot enforce this
|
|
|
|
|
restriction as there is no relation between each backend’s
|
2022-01-21 10:41:34 +01:00
|
|
|
|
<literal>enable</literal> option. As a result, this
|
2022-03-04 21:08:09 +01:00
|
|
|
|
restriction has to be done explicitly by adding assertions
|
2022-01-21 10:41:34 +01:00
|
|
|
|
in each display manager backend module.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
2022-03-04 21:08:09 +01:00
|
|
|
|
On the other hand, managing the display manager backends in
|
|
|
|
|
the central module will require changing the central module
|
2022-01-21 10:41:34 +01:00
|
|
|
|
option every time a new backend is added or removed.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
By using extensible option types, it is possible to create a
|
|
|
|
|
placeholder option in the central module
|
|
|
|
|
(<link linkend="ex-option-declaration-eot-service">Example:
|
|
|
|
|
Extensible type placeholder in the service module</link>),
|
|
|
|
|
and to extend it in each backend module
|
|
|
|
|
(<link linkend="ex-option-declaration-eot-backend-gdm">Example:
|
|
|
|
|
Extending
|
|
|
|
|
<literal>services.xserver.displayManager.enable</literal> in
|
|
|
|
|
the <literal>gdm</literal> module</link>,
|
|
|
|
|
<link linkend="ex-option-declaration-eot-backend-sddm">Example:
|
|
|
|
|
Extending
|
|
|
|
|
<literal>services.xserver.displayManager.enable</literal> in
|
|
|
|
|
the <literal>sddm</literal> module</link>).
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
As a result, <literal>displayManager.enable</literal> option
|
|
|
|
|
values can be added without changing the main service module
|
2022-03-04 21:08:09 +01:00
|
|
|
|
file and the type system automatically enforces that there
|
2022-01-21 10:41:34 +01:00
|
|
|
|
can only be a single display manager enabled.
|
|
|
|
|
</para>
|
|
|
|
|
<anchor xml:id="ex-option-declaration-eot-service" />
|
|
|
|
|
<para>
|
|
|
|
|
<emphasis role="strong">Example: Extensible type placeholder
|
|
|
|
|
in the service module</emphasis>
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting language="bash">
|
2021-07-03 16:14:03 +02:00
|
|
|
|
services.xserver.displayManager.enable = mkOption {
|
|
|
|
|
description = "Display manager to use";
|
|
|
|
|
type = with types; nullOr (enum [ ]);
|
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
2022-01-21 10:41:34 +01:00
|
|
|
|
<anchor xml:id="ex-option-declaration-eot-backend-gdm" />
|
|
|
|
|
<para>
|
|
|
|
|
<emphasis role="strong">Example: Extending
|
|
|
|
|
<literal>services.xserver.displayManager.enable</literal> in
|
|
|
|
|
the <literal>gdm</literal> module</emphasis>
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting language="bash">
|
2021-07-03 16:14:03 +02:00
|
|
|
|
services.xserver.displayManager.enable = mkOption {
|
|
|
|
|
type = with types; nullOr (enum [ "gdm" ]);
|
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
2022-01-21 10:41:34 +01:00
|
|
|
|
<anchor xml:id="ex-option-declaration-eot-backend-sddm" />
|
|
|
|
|
<para>
|
|
|
|
|
<emphasis role="strong">Example: Extending
|
|
|
|
|
<literal>services.xserver.displayManager.enable</literal> in
|
|
|
|
|
the <literal>sddm</literal> module</emphasis>
|
|
|
|
|
</para>
|
|
|
|
|
<programlisting language="bash">
|
2021-07-03 16:14:03 +02:00
|
|
|
|
services.xserver.displayManager.enable = mkOption {
|
|
|
|
|
type = with types; nullOr (enum [ "sddm" ]);
|
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
2022-01-21 10:41:34 +01:00
|
|
|
|
<para>
|
|
|
|
|
The placeholder declaration is a standard
|
|
|
|
|
<literal>mkOption</literal> declaration, but it is important
|
|
|
|
|
that extensible option declarations only use the
|
|
|
|
|
<literal>type</literal> argument.
|
|
|
|
|
</para>
|
|
|
|
|
<para>
|
|
|
|
|
Extensible option types work with any of the composed
|
|
|
|
|
variants of <literal>enum</literal> such as
|
|
|
|
|
<literal>with types; nullOr (enum [ "foo" "bar" ])</literal>
|
|
|
|
|
or
|
|
|
|
|
<literal>with types; listOf (enum [ "foo" "bar" ])</literal>.
|
|
|
|
|
</para>
|
|
|
|
|
</section>
|
|
|
|
|
</section>
|
|
|
|
|
</section>
|
2021-07-03 16:14:03 +02:00
|
|
|
|
</section>
|
|
|
|
|
</section>
|