at 22.05-pre 8.2 kB view raw
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> 3 <para> 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 7 looks like this: 8 </para> 9 <programlisting language="bash"> 10options = { 11 name = mkOption { 12 type = type specification; 13 default = default value; 14 example = example value; 15 description = &quot;Description for use in the NixOS manual.&quot;; 16 }; 17}; 18</programlisting> 19 <para> 20 The attribute names within the <literal>name</literal> attribute 21 path must be camel cased in general but should, as an exception, 22 match the 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. 28 </para> 29 <para> 30 The function <literal>mkOption</literal> accepts the following 31 arguments. 32 </para> 33 <variablelist> 34 <varlistentry> 35 <term> 36 <literal>type</literal> 37 </term> 38 <listitem> 39 <para> 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 43 to diagnose. 44 </para> 45 </listitem> 46 </varlistentry> 47 <varlistentry> 48 <term> 49 <literal>default</literal> 50 </term> 51 <listitem> 52 <para> 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. 57 </para> 58 </listitem> 59 </varlistentry> 60 <varlistentry> 61 <term> 62 <literal>defaultText</literal> 63 </term> 64 <listitem> 65 <para> 66 A textual representation of the default value to be rendered 67 verbatim in the manual. Useful if the default value is a 68 complex expression or depends on other values or packages. Use 69 <literal>lib.literalExpression</literal> for a Nix expression, 70 <literal>lib.literalDocBook</literal> for a plain English 71 description in DocBook format. 72 </para> 73 </listitem> 74 </varlistentry> 75 <varlistentry> 76 <term> 77 <literal>example</literal> 78 </term> 79 <listitem> 80 <para> 81 An example value that will be shown in the NixOS manual. You 82 can use <literal>lib.literalExpression</literal> and 83 <literal>lib.literalDocBook</literal> in the same way as in 84 <literal>defaultText</literal>. 85 </para> 86 </listitem> 87 </varlistentry> 88 <varlistentry> 89 <term> 90 <literal>description</literal> 91 </term> 92 <listitem> 93 <para> 94 A textual description of the option, in DocBook format, that 95 will be included in the NixOS manual. 96 </para> 97 </listitem> 98 </varlistentry> 99 </variablelist> 100 <section xml:id="sec-option-declarations-eot"> 101 <title>Extensible Option Types</title> 102 <para> 103 Extensible option types is a feature that allow to extend certain 104 types declaration through multiple module files. This feature only 105 work with a restricted set of types, namely 106 <literal>enum</literal> and <literal>submodules</literal> and any 107 composed forms of them. 108 </para> 109 <para> 110 Extensible option types can be used for <literal>enum</literal> 111 options that affects multiple modules, or as an alternative to 112 related <literal>enable</literal> options. 113 </para> 114 <para> 115 As an example, we will take the case of display managers. There is 116 a central display manager module for generic display manager 117 options and a module file per display manager backend (sddm, gdm 118 ...). 119 </para> 120 <para> 121 There are two approach to this module structure: 122 </para> 123 <itemizedlist> 124 <listitem> 125 <para> 126 Managing the display managers independently by adding an 127 enable option to every display manager module backend. (NixOS) 128 </para> 129 </listitem> 130 <listitem> 131 <para> 132 Managing the display managers in the central module by adding 133 an option to select which display manager backend to use. 134 </para> 135 </listitem> 136 </itemizedlist> 137 <para> 138 Both approaches have problems. 139 </para> 140 <para> 141 Making backends independent can quickly become hard to manage. For 142 display managers, there can be only one enabled at a time, but the 143 type system can not enforce this restriction as there is no 144 relation between each backend <literal>enable</literal> option. As 145 a result, this restriction has to be done explicitely by adding 146 assertions in each display manager backend module. 147 </para> 148 <para> 149 On the other hand, managing the display managers backends in the 150 central module will require to change the central module option 151 every time a new backend is added or removed. 152 </para> 153 <para> 154 By using extensible option types, it is possible to create a 155 placeholder option in the central module 156 (<link linkend="ex-option-declaration-eot-service">Example: 157 Extensible type placeholder in the service module</link>), and to 158 extend it in each backend module 159 (<link linkend="ex-option-declaration-eot-backend-gdm">Example: 160 Extending 161 <literal>services.xserver.displayManager.enable</literal> in the 162 <literal>gdm</literal> module</link>, 163 <link linkend="ex-option-declaration-eot-backend-sddm">Example: 164 Extending 165 <literal>services.xserver.displayManager.enable</literal> in the 166 <literal>sddm</literal> module</link>). 167 </para> 168 <para> 169 As a result, <literal>displayManager.enable</literal> option 170 values can be added without changing the main service module file 171 and the type system automatically enforce that there can only be a 172 single display manager enabled. 173 </para> 174 <anchor xml:id="ex-option-declaration-eot-service" /> 175 <para> 176 <emphasis role="strong">Example: Extensible type placeholder in 177 the service module</emphasis> 178 </para> 179 <programlisting language="bash"> 180services.xserver.displayManager.enable = mkOption { 181 description = &quot;Display manager to use&quot;; 182 type = with types; nullOr (enum [ ]); 183}; 184</programlisting> 185 <anchor xml:id="ex-option-declaration-eot-backend-gdm" /> 186 <para> 187 <emphasis role="strong">Example: Extending 188 <literal>services.xserver.displayManager.enable</literal> in the 189 <literal>gdm</literal> module</emphasis> 190 </para> 191 <programlisting language="bash"> 192services.xserver.displayManager.enable = mkOption { 193 type = with types; nullOr (enum [ &quot;gdm&quot; ]); 194}; 195</programlisting> 196 <anchor xml:id="ex-option-declaration-eot-backend-sddm" /> 197 <para> 198 <emphasis role="strong">Example: Extending 199 <literal>services.xserver.displayManager.enable</literal> in the 200 <literal>sddm</literal> module</emphasis> 201 </para> 202 <programlisting language="bash"> 203services.xserver.displayManager.enable = mkOption { 204 type = with types; nullOr (enum [ &quot;sddm&quot; ]); 205}; 206</programlisting> 207 <para> 208 The placeholder declaration is a standard 209 <literal>mkOption</literal> declaration, but it is important that 210 extensible option declarations only use the 211 <literal>type</literal> argument. 212 </para> 213 <para> 214 Extensible option types work with any of the composed variants of 215 <literal>enum</literal> such as 216 <literal>with types; nullOr (enum [ &quot;foo&quot; &quot;bar&quot; ])</literal> 217 or 218 <literal>with types; listOf (enum [ &quot;foo&quot; &quot;bar&quot; ])</literal>. 219 </para> 220 </section> 221</section>