2014-08-24 18:18:18 +01:00
|
|
|
|
<section xmlns="http://docbook.org/ns/docbook"
|
|
|
|
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
|
|
|
xmlns:xi="http://www.w3.org/2001/XInclude"
|
|
|
|
|
version="5.0"
|
|
|
|
|
xml:id="sec-option-declarations">
|
|
|
|
|
|
|
|
|
|
<title>Option Declarations</title>
|
|
|
|
|
|
|
|
|
|
<para>An option declaration specifies the name, type and description
|
2016-05-22 10:29:33 +01:00
|
|
|
|
of a NixOS configuration option. It is invalid to define an option
|
|
|
|
|
that hasn’t been declared in any module. An option declaration
|
2014-08-24 18:18:18 +01:00
|
|
|
|
generally looks like this:
|
|
|
|
|
|
|
|
|
|
<programlisting>
|
|
|
|
|
options = {
|
|
|
|
|
<replaceable>name</replaceable> = mkOption {
|
|
|
|
|
type = <replaceable>type specification</replaceable>;
|
|
|
|
|
default = <replaceable>default value</replaceable>;
|
|
|
|
|
example = <replaceable>example value</replaceable>;
|
|
|
|
|
description = "<replaceable>Description for use in the NixOS manual.</replaceable>";
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
</programlisting>
|
|
|
|
|
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>The function <varname>mkOption</varname> accepts the following arguments.
|
|
|
|
|
|
|
|
|
|
<variablelist>
|
|
|
|
|
|
|
|
|
|
<varlistentry>
|
|
|
|
|
<term><varname>type</varname></term>
|
|
|
|
|
<listitem>
|
2016-09-13 06:04:02 +01:00
|
|
|
|
<para>The type of the option (see <xref linkend='sec-option-types' />).
|
|
|
|
|
It may be omitted, but that’s not advisable since it may lead to errors
|
|
|
|
|
that are hard to diagnose.</para>
|
2014-08-24 18:18:18 +01:00
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
|
|
|
|
|
|
|
|
|
<varlistentry>
|
|
|
|
|
<term><varname>default</varname></term>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>The default value used if no value is defined by any
|
|
|
|
|
module. A default is not required; in that case, if the option
|
2016-05-22 10:29:33 +01:00
|
|
|
|
value is never used, an error will be thrown.</para>
|
2014-08-24 18:18:18 +01:00
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
|
|
|
|
|
|
|
|
|
<varlistentry>
|
|
|
|
|
<term><varname>example</varname></term>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>An example value that will be shown in the NixOS manual.</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
|
|
|
|
|
|
|
|
|
<varlistentry>
|
|
|
|
|
<term><varname>description</varname></term>
|
|
|
|
|
<listitem>
|
|
|
|
|
<para>A textual description of the option, in DocBook format,
|
|
|
|
|
that will be included in the NixOS manual.</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</varlistentry>
|
|
|
|
|
|
|
|
|
|
</variablelist>
|
|
|
|
|
|
|
|
|
|
</para>
|
|
|
|
|
|
2016-09-07 02:03:32 +01:00
|
|
|
|
<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 (slim, kdm, gdm ...).
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>There are two approach to this module structure:
|
|
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
|
|
|
<listitem><para>Managing the display managers independently by adding an
|
|
|
|
|
enable option to every display manager module backend. (NixOS)</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
<listitem><para>Managing the display managers in the central module by
|
|
|
|
|
adding an option to select which display manager backend to use.</para>
|
|
|
|
|
</listitem>
|
|
|
|
|
</itemizedlist>
|
|
|
|
|
</para>
|
|
|
|
|
|
|
|
|
|
<para>Both approachs have problems.</para>
|
|
|
|
|
|
|
|
|
|
<para>Making backends independent can quickly become hard to manage. For
|
|
|
|
|
display managers, there can be only one enabled at a time, but the type
|
|
|
|
|
system can not enforce this restriction as there is no relation between
|
|
|
|
|
each backend <literal>enable</literal> option. As a result, this restriction
|
|
|
|
|
has to be done explicitely by adding assertions in each display manager
|
|
|
|
|
backend module.</para>
|
|
|
|
|
|
|
|
|
|
<para>On the other hand, managing the display managers backends in the
|
|
|
|
|
central module will require to change the central module 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 (<xref linkend='ex-option-declaration-eot-service'
|
|
|
|
|
/>), and to extend it in each backend module (<xref
|
|
|
|
|
linkend='ex-option-declaration-eot-backend-slim' />, <xref
|
|
|
|
|
linkend='ex-option-declaration-eot-backend-kdm' />).</para>
|
|
|
|
|
|
|
|
|
|
<para>As a result, <literal>displayManager.enable</literal> option values can
|
|
|
|
|
be added without changing the main service module file and the type system
|
|
|
|
|
automatically enforce that there can only be a single display manager
|
|
|
|
|
enabled.</para>
|
|
|
|
|
|
|
|
|
|
<example xml:id='ex-option-declaration-eot-service'><title>Extensible type
|
|
|
|
|
placeholder in the service module</title>
|
|
|
|
|
<screen>
|
|
|
|
|
services.xserver.displayManager.enable = mkOption {
|
|
|
|
|
description = "Display manager to use";
|
|
|
|
|
type = with types; nullOr (enum [ ]);
|
|
|
|
|
};</screen></example>
|
|
|
|
|
|
|
|
|
|
<example xml:id='ex-option-declaration-eot-backend-slim'><title>Extending
|
|
|
|
|
<literal>services.xserver.displayManager.enable</literal> in the
|
|
|
|
|
<literal>slim</literal> module</title>
|
|
|
|
|
<screen>
|
|
|
|
|
services.xserver.displayManager.enable = mkOption {
|
|
|
|
|
type = with types; nullOr (enum [ "slim" ]);
|
|
|
|
|
};</screen></example>
|
|
|
|
|
|
|
|
|
|
<example xml:id='ex-option-declaration-eot-backend-kdm'><title>Extending
|
|
|
|
|
<literal>services.foo.backend</literal> in the <literal>kdm</literal>
|
|
|
|
|
module</title>
|
|
|
|
|
<screen>
|
|
|
|
|
services.xserver.displayManager.enable = mkOption {
|
|
|
|
|
type = with types; nullOr (enum [ "kdm" ]);
|
|
|
|
|
};</screen></example>
|
|
|
|
|
|
|
|
|
|
<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>
|
2015-08-06 18:55:42 +01:00
|
|
|
|
</section>
|