at 23.05-pre 13 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 = lib.mdDoc &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" />). This argument is 42 mandatory for nixpkgs modules. Setting this is highly 43 recommended for the sake of documentation and type checking. 44 In case it is not set, a fallback type with unspecified 45 behavior is used. 46 </para> 47 </listitem> 48 </varlistentry> 49 <varlistentry> 50 <term> 51 <literal>default</literal> 52 </term> 53 <listitem> 54 <para> 55 The default value used if no value is defined by any module. A 56 default is not required; but if a default is not given, then 57 users of the module will have to define the value of the 58 option, otherwise an error will be thrown. 59 </para> 60 </listitem> 61 </varlistentry> 62 <varlistentry> 63 <term> 64 <literal>defaultText</literal> 65 </term> 66 <listitem> 67 <para> 68 A textual representation of the default value to be rendered 69 verbatim in the manual. Useful if the default value is a 70 complex expression or depends on other values or packages. Use 71 <literal>lib.literalExpression</literal> for a Nix expression, 72 <literal>lib.literalMD</literal> for a plain English 73 description in 74 <link xlink:href="https://nixos.org/nixpkgs/manual/#sec-contributing-markup">Nixpkgs-flavored 75 Markdown</link> format. 76 </para> 77 </listitem> 78 </varlistentry> 79 <varlistentry> 80 <term> 81 <literal>example</literal> 82 </term> 83 <listitem> 84 <para> 85 An example value that will be shown in the NixOS manual. You 86 can use <literal>lib.literalExpression</literal> and 87 <literal>lib.literalMD</literal> in the same way as in 88 <literal>defaultText</literal>. 89 </para> 90 </listitem> 91 </varlistentry> 92 <varlistentry> 93 <term> 94 <literal>description</literal> 95 </term> 96 <listitem> 97 <para> 98 A textual description of the option, in 99 <link xlink:href="https://nixos.org/nixpkgs/manual/#sec-contributing-markup">Nixpkgs-flavored 100 Markdown</link> format, that will be included in the NixOS 101 manual. During the migration process from DocBook it is 102 necessary to mark descriptions written in CommonMark with 103 <literal>lib.mdDoc</literal>. The description may still be 104 written in DocBook (without any marker), but this is 105 discouraged and will be deprecated in the future. 106 </para> 107 </listitem> 108 </varlistentry> 109 </variablelist> 110 <section xml:id="sec-option-declarations-util"> 111 <title>Utility functions for common option patterns</title> 112 <section xml:id="sec-option-declarations-util-mkEnableOption"> 113 <title><literal>mkEnableOption</literal></title> 114 <para> 115 Creates an Option attribute set for a boolean value option i.e 116 an option to be toggled on or off. 117 </para> 118 <para> 119 This function takes a single string argument, the name of the 120 thing to be toggled. 121 </para> 122 <para> 123 The option’s description is <quote>Whether to enable 124 &lt;name&gt;.</quote>. 125 </para> 126 <para> 127 For example: 128 </para> 129 <anchor xml:id="ex-options-declarations-util-mkEnableOption-magic" /> 130 <programlisting language="bash"> 131lib.mkEnableOption &quot;magic&quot; 132# is like 133lib.mkOption { 134 type = lib.types.bool; 135 default = false; 136 example = true; 137 description = lib.mdDoc &quot;Whether to enable magic.&quot;; 138} 139</programlisting> 140 <section xml:id="sec-option-declarations-util-mkPackageOption"> 141 <title><literal>mkPackageOption</literal></title> 142 <para> 143 Usage: 144 </para> 145 <programlisting language="bash"> 146mkPackageOption pkgs &quot;name&quot; { default = [ &quot;path&quot; &quot;in&quot; &quot;pkgs&quot; ]; example = &quot;literal example&quot;; } 147</programlisting> 148 <para> 149 Creates an Option attribute set for an option that specifies 150 the package a module should use for some purpose. 151 </para> 152 <para> 153 <emphasis role="strong">Note</emphasis>: You shouldn’t 154 necessarily make package options for all of your modules. You 155 can always overwrite a specific package throughout nixpkgs by 156 using 157 <link xlink:href="https://nixos.org/manual/nixpkgs/stable/#chap-overlays">nixpkgs 158 overlays</link>. 159 </para> 160 <para> 161 The default package is specified as a list of strings 162 representing its attribute path in nixpkgs. Because of this, 163 you need to pass nixpkgs itself as the first argument. 164 </para> 165 <para> 166 The second argument is the name of the option, used in the 167 description <quote>The &lt;name&gt; package to use.</quote>. 168 You can also pass an example value, either a literal string or 169 a package’s attribute path. 170 </para> 171 <para> 172 You can omit the default path if the name of the option is 173 also attribute path in nixpkgs. 174 </para> 175 <anchor xml:id="ex-options-declarations-util-mkPackageOption" /> 176 <para> 177 Examples: 178 </para> 179 <anchor xml:id="ex-options-declarations-util-mkPackageOption-hello" /> 180 <programlisting language="bash"> 181lib.mkPackageOption pkgs &quot;hello&quot; { } 182# is like 183lib.mkOption { 184 type = lib.types.package; 185 default = pkgs.hello; 186 defaultText = lib.literalExpression &quot;pkgs.hello&quot;; 187 description = lib.mdDoc &quot;The hello package to use.&quot;; 188} 189</programlisting> 190 <anchor xml:id="ex-options-declarations-util-mkPackageOption-ghc" /> 191 <programlisting language="bash"> 192lib.mkPackageOption pkgs &quot;GHC&quot; { 193 default = [ &quot;ghc&quot; ]; 194 example = &quot;pkgs.haskell.packages.ghc92.ghc.withPackages (hkgs: [ hkgs.primes ])&quot;; 195} 196# is like 197lib.mkOption { 198 type = lib.types.package; 199 default = pkgs.ghc; 200 defaultText = lib.literalExpression &quot;pkgs.ghc&quot;; 201 example = lib.literalExpression &quot;pkgs.haskell.packages.ghc92.ghc.withPackages (hkgs: [ hkgs.primes ])&quot;; 202 description = lib.mdDoc &quot;The GHC package to use.&quot;; 203} 204</programlisting> 205 <section xml:id="sec-option-declarations-eot"> 206 <title>Extensible Option Types</title> 207 <para> 208 Extensible option types is a feature that allow to extend 209 certain types declaration through multiple module files. 210 This feature only work with a restricted set of types, 211 namely <literal>enum</literal> and 212 <literal>submodules</literal> and any composed forms of 213 them. 214 </para> 215 <para> 216 Extensible option types can be used for 217 <literal>enum</literal> options that affects multiple 218 modules, or as an alternative to related 219 <literal>enable</literal> options. 220 </para> 221 <para> 222 As an example, we will take the case of display managers. 223 There is a central display manager module for generic 224 display manager options and a module file per display 225 manager backend (sddm, gdm ...). 226 </para> 227 <para> 228 There are two approaches we could take with this module 229 structure: 230 </para> 231 <itemizedlist> 232 <listitem> 233 <para> 234 Configuring the display managers independently by adding 235 an enable option to every display manager module 236 backend. (NixOS) 237 </para> 238 </listitem> 239 <listitem> 240 <para> 241 Configuring the display managers in the central module 242 by adding an option to select which display manager 243 backend to use. 244 </para> 245 </listitem> 246 </itemizedlist> 247 <para> 248 Both approaches have problems. 249 </para> 250 <para> 251 Making backends independent can quickly become hard to 252 manage. For display managers, there can only be one enabled 253 at a time, but the type system cannot enforce this 254 restriction as there is no relation between each backend’s 255 <literal>enable</literal> option. As a result, this 256 restriction has to be done explicitly by adding assertions 257 in each display manager backend module. 258 </para> 259 <para> 260 On the other hand, managing the display manager backends in 261 the central module will require changing the central module 262 option every time a new backend is added or removed. 263 </para> 264 <para> 265 By using extensible option types, it is possible to create a 266 placeholder option in the central module 267 (<link linkend="ex-option-declaration-eot-service">Example: 268 Extensible type placeholder in the service module</link>), 269 and to extend it in each backend module 270 (<link linkend="ex-option-declaration-eot-backend-gdm">Example: 271 Extending 272 <literal>services.xserver.displayManager.enable</literal> in 273 the <literal>gdm</literal> module</link>, 274 <link linkend="ex-option-declaration-eot-backend-sddm">Example: 275 Extending 276 <literal>services.xserver.displayManager.enable</literal> in 277 the <literal>sddm</literal> module</link>). 278 </para> 279 <para> 280 As a result, <literal>displayManager.enable</literal> option 281 values can be added without changing the main service module 282 file and the type system automatically enforces that there 283 can only be a single display manager enabled. 284 </para> 285 <anchor xml:id="ex-option-declaration-eot-service" /> 286 <para> 287 <emphasis role="strong">Example: Extensible type placeholder 288 in the service module</emphasis> 289 </para> 290 <programlisting language="bash"> 291services.xserver.displayManager.enable = mkOption { 292 description = &quot;Display manager to use&quot;; 293 type = with types; nullOr (enum [ ]); 294}; 295</programlisting> 296 <anchor xml:id="ex-option-declaration-eot-backend-gdm" /> 297 <para> 298 <emphasis role="strong">Example: Extending 299 <literal>services.xserver.displayManager.enable</literal> in 300 the <literal>gdm</literal> module</emphasis> 301 </para> 302 <programlisting language="bash"> 303services.xserver.displayManager.enable = mkOption { 304 type = with types; nullOr (enum [ &quot;gdm&quot; ]); 305}; 306</programlisting> 307 <anchor xml:id="ex-option-declaration-eot-backend-sddm" /> 308 <para> 309 <emphasis role="strong">Example: Extending 310 <literal>services.xserver.displayManager.enable</literal> in 311 the <literal>sddm</literal> module</emphasis> 312 </para> 313 <programlisting language="bash"> 314services.xserver.displayManager.enable = mkOption { 315 type = with types; nullOr (enum [ &quot;sddm&quot; ]); 316}; 317</programlisting> 318 <para> 319 The placeholder declaration is a standard 320 <literal>mkOption</literal> declaration, but it is important 321 that extensible option declarations only use the 322 <literal>type</literal> argument. 323 </para> 324 <para> 325 Extensible option types work with any of the composed 326 variants of <literal>enum</literal> such as 327 <literal>with types; nullOr (enum [ &quot;foo&quot; &quot;bar&quot; ])</literal> 328 or 329 <literal>with types; listOf (enum [ &quot;foo&quot; &quot;bar&quot; ])</literal>. 330 </para> 331 </section> 332 </section> 333 </section> 334 </section> 335</section>