···
1
+
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-option-declarations">
2
+
<title>Option Declarations</title>
4
+
An option declaration specifies the name, type and description of a
5
+
NixOS configuration option. It is invalid to define an option that
6
+
hasn’t been declared in any module. An option declaration generally
9
+
<programlisting language="bash">
12
+
type = type specification;
13
+
default = default value;
14
+
example = example value;
15
+
description = "Description for use in the NixOS manual.";
20
+
The attribute names within the <literal>name</literal> attribute
21
+
path must be camel cased in general but should, as an exception,
23
+
<link xlink:href="https://nixos.org/nixpkgs/manual/#sec-package-naming">
24
+
package attribute name</link> when referencing a Nixpkgs package.
25
+
For example, the option
26
+
<literal>services.nix-serve.bindAddress</literal> references the
27
+
<literal>nix-serve</literal> Nixpkgs package.
30
+
The function <literal>mkOption</literal> accepts the following
36
+
<literal>type</literal>
40
+
The type of the option (see
41
+
<xref linkend="sec-option-types" />). It may be omitted, but
42
+
that’s not advisable since it may lead to errors that are hard
49
+
<literal>default</literal>
53
+
The default value used if no value is defined by any module. A
54
+
default is not required; but if a default is not given, then
55
+
users of the module will have to define the value of the
56
+
option, otherwise an error will be thrown.
62
+
<literal>example</literal>
66
+
An example value that will be shown in the NixOS manual.
72
+
<literal>description</literal>
76
+
A textual description of the option, in DocBook format, that
77
+
will be included in the NixOS manual.
82
+
<section xml:id="sec-option-declarations-eot">
83
+
<title>Extensible Option Types</title>
85
+
Extensible option types is a feature that allow to extend certain
86
+
types declaration through multiple module files. This feature only
87
+
work with a restricted set of types, namely
88
+
<literal>enum</literal> and <literal>submodules</literal> and any
89
+
composed forms of them.
92
+
Extensible option types can be used for <literal>enum</literal>
93
+
options that affects multiple modules, or as an alternative to
94
+
related <literal>enable</literal> options.
97
+
As an example, we will take the case of display managers. There is
98
+
a central display manager module for generic display manager
99
+
options and a module file per display manager backend (sddm, gdm
103
+
There are two approach to this module structure:
108
+
Managing the display managers independently by adding an
109
+
enable option to every display manager module backend. (NixOS)
114
+
Managing the display managers in the central module by adding
115
+
an option to select which display manager backend to use.
120
+
Both approaches have problems.
123
+
Making backends independent can quickly become hard to manage. For
124
+
display managers, there can be only one enabled at a time, but the
125
+
type system can not enforce this restriction as there is no
126
+
relation between each backend <literal>enable</literal> option. As
127
+
a result, this restriction has to be done explicitely by adding
128
+
assertions in each display manager backend module.
131
+
On the other hand, managing the display managers backends in the
132
+
central module will require to change the central module option
133
+
every time a new backend is added or removed.
136
+
By using extensible option types, it is possible to create a
137
+
placeholder option in the central module
138
+
(<link linkend="ex-option-declaration-eot-service">Example:
139
+
Extensible type placeholder in the service module</link>), and to
140
+
extend it in each backend module
141
+
(<link linkend="ex-option-declaration-eot-backend-gdm">Example:
143
+
<literal>services.xserver.displayManager.enable</literal> in the
144
+
<literal>gdm</literal> module</link>,
145
+
<link linkend="ex-option-declaration-eot-backend-sddm">Example:
147
+
<literal>services.xserver.displayManager.enable</literal> in the
148
+
<literal>sddm</literal> module</link>).
151
+
As a result, <literal>displayManager.enable</literal> option
152
+
values can be added without changing the main service module file
153
+
and the type system automatically enforce that there can only be a
154
+
single display manager enabled.
156
+
<anchor xml:id="ex-option-declaration-eot-service" />
158
+
<emphasis role="strong">Example: Extensible type placeholder in
159
+
the service module</emphasis>
161
+
<programlisting language="bash">
162
+
services.xserver.displayManager.enable = mkOption {
163
+
description = "Display manager to use";
164
+
type = with types; nullOr (enum [ ]);
167
+
<anchor xml:id="ex-option-declaration-eot-backend-gdm" />
169
+
<emphasis role="strong">Example: Extending
170
+
<literal>services.xserver.displayManager.enable</literal> in the
171
+
<literal>gdm</literal> module</emphasis>
173
+
<programlisting language="bash">
174
+
services.xserver.displayManager.enable = mkOption {
175
+
type = with types; nullOr (enum [ "gdm" ]);
178
+
<anchor xml:id="ex-option-declaration-eot-backend-sddm" />
180
+
<emphasis role="strong">Example: Extending
181
+
<literal>services.xserver.displayManager.enable</literal> in the
182
+
<literal>sddm</literal> module</emphasis>
184
+
<programlisting language="bash">
185
+
services.xserver.displayManager.enable = mkOption {
186
+
type = with types; nullOr (enum [ "sddm" ]);
190
+
The placeholder declaration is a standard
191
+
<literal>mkOption</literal> declaration, but it is important that
192
+
extensible option declarations only use the
193
+
<literal>type</literal> argument.
196
+
Extensible option types work with any of the composed variants of
197
+
<literal>enum</literal> such as
198
+
<literal>with types; nullOr (enum [ "foo" "bar" ])</literal>
200
+
<literal>with types; listOf (enum [ "foo" "bar" ])</literal>.