vuls: init at 0.27.0
[NixPkgs.git] / nixos / doc / manual / development / settings-options.section.md
blob48cc62bb424c05ea3c73102148da91f1fb1c2762
1 # Options for Program Settings {#sec-settings-options}
3 Many programs have configuration files where program-specific settings
4 can be declared. File formats can be separated into two categories:
6 -   Nix-representable ones: These can trivially be mapped to a subset of
7     Nix syntax. E.g. JSON is an example, since its values like
8     `{"foo":{"bar":10}}` can be mapped directly to Nix:
9     `{ foo = { bar = 10; }; }`. Other examples are INI, YAML and TOML.
10     The following section explains the convention for these settings.
12 -   Non-nix-representable ones: These can't be trivially mapped to a
13     subset of Nix syntax. Most generic programming languages are in this
14     group, e.g. bash, since the statement `if true; then echo hi; fi`
15     doesn't have a trivial representation in Nix.
17     Currently there are no fixed conventions for these, but it is common
18     to have a `configFile` option for setting the configuration file
19     path directly. The default value of `configFile` can be an
20     auto-generated file, with convenient options for controlling the
21     contents. For example an option of type `attrsOf str` can be used
22     for representing environment variables which generates a section
23     like `export FOO="foo"`. Often it can also be useful to also include
24     an `extraConfig` option of type `lines` to allow arbitrary text
25     after the autogenerated part of the file.
27 ## Nix-representable Formats (JSON, YAML, TOML, INI, ...) {#sec-settings-nix-representable}
29 By convention, formats like this are handled with a generic `settings`
30 option, representing the full program configuration as a Nix value. The
31 type of this option should represent the format. The most common formats
32 have a predefined type and string generator already declared under
33 `pkgs.formats`:
35 `pkgs.formats.javaProperties` { *`comment`* ? `"Generated with Nix"` }
37 :   A function taking an attribute set with values
39     `comment`
41     :   A string to put at the start of the
42         file in a comment. It can have multiple
43         lines.
45     It returns the `type`: `attrsOf str` and a function
46     `generate` to build a Java `.properties` file, taking
47     care of the correct escaping, etc.
49 `pkgs.formats.hocon` { *`generator`* ? `<derivation>`, *`validator`* ? `<derivation>`, *`doCheck`* ? true }
51 :  A function taking an attribute set with values
53     `generator`
55     :   A derivation used for converting the JSON output
56         from the nix settings into HOCON. This might be
57         useful if your HOCON variant is slightly different
58         from the java-based one, or for testing purposes.
60     `validator`
62     :   A derivation used for verifying that the HOCON
63         output is correct and parsable. This might be
64         useful if your HOCON variant is slightly different
65         from the java-based one, or for testing purposes.
67     `doCheck`
69     :   Whether to enable/disable the validator check.
71     It returns an attrset with a `type`, `generate` function,
72     and a `lib` attset, as specified [below](#pkgs-formats-result).
73     Some of the lib functions will be best understood if you have
74     read the reference specification. You can find this
75     specification here:
77     <https://github.com/lightbend/config/blob/main/HOCON.md>
79     Inside of `lib`, you will find these functions
81     `mkInclude`
83     :   This is used together with a specially named
84         attribute `includes`, to include other HOCON
85         sources into the document.
87         The function has a shorthand variant where it
88         is up to the HOCON parser to figure out what type
89         of include is being used. The include will default
90         to being non-required. If you want to be more
91         explicit about the details of the include, you can
92         provide an attrset with following arguments
94         `required`
96         :   Whether the parser should fail upon failure
97             to include the document
99         `type`
101         :   Type of the source of the included document.
102             Valid values are `file`, `url` and `classpath`.
103             See upstream documentation for the semantics
104             behind each value
106         `value`
108         :   The URI/path/classpath pointing to the source of
109             the document to be included.
111         `Example usage:`
113         ```nix
114           let
115             format = pkgs.formats.hocon { };
116             hocon_file = pkgs.writeText "to_include.hocon" ''
117               a = 1;
118             '';
119           in {
120             some.nested.hocon.attrset = {
121               _includes = [
122                 (format.lib.mkInclude hocon_file)
123                 (format.lib.mkInclude "https://example.com/to_include.hocon")
124                 (format.lib.mkInclude {
125                   required = true;
126                   type = "file";
127                   value = include_file;
128                 })
129               ];
130               ...
131             };
132           }
133         ```
135     `mkAppend`
137     :   This is used to invoke the `+=` operator.
138         This can be useful if you need to add something
139         to a list that is included from outside of nix.
140         See upstream documentation for the semantics
141         behind the `+=` operation.
143         `Example usage:`
145         ```nix
146           let
147             format = pkgs.formats.hocon { };
148             hocon_file = pkgs.writeText "to_include.hocon" ''
149               a = [ 1 ];
150               b = [ 2 ];
151             '';
152           in {
153             _includes = [
154               (format.lib.mkInclude hocon_file)
155             ];
157             c = 3;
158             a = format.lib.mkAppend 3;
159             b = format.lib.mkAppend (format.lib.mkSubstitution "c");
160           }
161         ```
163     `mkSubstitution`
165     :   This is used to make HOCON substitutions.
166         Similarly to `mkInclude`, this function has
167         a shorthand variant where you just give it
168         the string with the substitution value.
169         The substitution is not optional by default.
170         Alternatively, you can provide an attrset
171         with more options
173         `optional`
175         :   Whether the parser should fail upon
176             failure to fetch the substitution value.
178         `value`
180         :   The name of the variable to use for
181             substitution.
183         See upstream documentation for semantics
184         behind the substitution functionality.
186         `Example usage:`
188         ```nix
189           let
190             format = pkgs.formats.hocon { };
191           in {
192             a = 1;
193             b = format.lib.mkSubstitution "a";
194             c = format.lib.mkSubstition "SOME_ENVVAR";
195             d = format.lib.mkSubstition {
196               value = "SOME_OPTIONAL_ENVVAR";
197               optional = true;
198             };
199           }
200         ```
202     `Implementation notes:`
204     - classpath includes are not implemented in pyhocon,
205       which is used for validating the HOCON output. This
206       means that if you are using classpath includes,
207       you will want to either use an alternative validator
208       or set `doCheck = false` in the format options.
210 `pkgs.formats.libconfig` { *`generator`* ? `<derivation>`, *`validator`* ? `<derivation>` }
212 :  A function taking an attribute set with values
214     `generator`
216     :   A derivation used for converting the JSON output
217         from the nix settings into libconfig. This might be
218         useful if your libconfig variant is slightly different
219         from the original one, or for testing purposes.
221     `validator`
223     :   A derivation used for verifying that the libconfig
224         output is correct and parsable. This might be
225         useful if your libconfig variant is slightly different
226         from the original one, or for testing purposes.
228     It returns an attrset with a `type`, `generate` function,
229     and a `lib` attset, as specified [below](#pkgs-formats-result).
230     Some of the lib functions will be best understood if you have
231     read the reference specification. You can find this
232     specification here:
234     <https://hyperrealm.github.io/libconfig/libconfig_manual.html#Configuration-Files>
236     Inside of `lib`, you will find these functions
238     `mkHex`, `mkOctal`, `mkFloat`
240     :   Use these to specify numbers in other formats.
242         `Example usage:`
244         ```nix
245           let
246             format = pkgs.formats.libconfig { };
247           in {
248             myHexValue = format.lib.mkHex "0x1FC3";
249             myOctalValue = format.lib.mkOctal "0027";
250             myFloatValue = format.lib.mkFloat "1.2E-3";
251           }
252         ```
254     `mkArray`, `mkList`
256     :   Use these to differentiate between whether
257         a nix list should be considered as a libconfig
258         array or a libconfig list. See the upstream
259         documentation for the semantics behind these types.
261         `Example usage:`
263         ```nix
264           let
265             format = pkgs.formats.libconfig { };
266           in {
267             myList = format.lib.mkList [ "foo" 1 true ];
268             myArray = format.lib.mkArray [ 1 2 3 ];
269           }
270         ```
272     `Implementation notes:`
274     - Since libconfig does not allow setting names to start with an underscore,
275       this is used as a prefix for both special types and include directives.
277     - The difference between 32bit and 64bit values became optional in libconfig
278       1.5, so we assume 64bit values for all numbers.
280 `pkgs.formats.json` { }
282 :   A function taking an empty attribute set (for future extensibility)
283     and returning a set with JSON-specific attributes `type` and
284     `generate` as specified [below](#pkgs-formats-result).
286 `pkgs.formats.yaml` { }
288 :   A function taking an empty attribute set (for future extensibility)
289     and returning a set with YAML-specific attributes `type` and
290     `generate` as specified [below](#pkgs-formats-result).
292 `pkgs.formats.ini` { *`listsAsDuplicateKeys`* ? false, *`listToValue`* ? null, \.\.\. }
294 :   A function taking an attribute set with values
296     `listsAsDuplicateKeys`
298     :   A boolean for controlling whether list values can be used to
299         represent duplicate INI keys
301     `listToValue`
303     :   A function for turning a list of values into a single value.
305     It returns a set with INI-specific attributes `type` and `generate`
306     as specified [below](#pkgs-formats-result).
307     The type of the input is an *attrset* of sections; key-value pairs where
308     the key is the section name and the value is the corresponding content
309     which is also an *attrset* of key-value pairs for the actual key-value
310     mappings of the INI format.
311     The values of the INI atoms are subject to the above parameters (e.g. lists
312     may be transformed into multiple key-value pairs depending on
313     `listToValue`).
315 `pkgs.formats.iniWithGlobalSection` { *`listsAsDuplicateKeys`* ? false, *`listToValue`* ? null, \.\.\. }
317 :   A function taking an attribute set with values
319     `listsAsDuplicateKeys`
321     :   A boolean for controlling whether list values can be used to
322         represent duplicate INI keys
324     `listToValue`
326     :   A function for turning a list of values into a single value.
328     It returns a set with INI-specific attributes `type` and `generate`
329     as specified [below](#pkgs-formats-result).
330     The type of the input is an *attrset* of the structure
331     `{ sections = {}; globalSection = {}; }` where *sections* are several
332     sections as with *pkgs.formats.ini* and *globalSection* being just a single
333     attrset of key-value pairs for a single section, the global section which
334     preceedes the section definitions.
336 `pkgs.formats.toml` { }
338 :   A function taking an empty attribute set (for future extensibility)
339     and returning a set with TOML-specific attributes `type` and
340     `generate` as specified [below](#pkgs-formats-result).
342 `pkgs.formats.elixirConf { elixir ? pkgs.elixir }`
344 :   A function taking an attribute set with values
346     `elixir`
348     :   The Elixir package which will be used to format the generated output
350     It returns a set with Elixir-Config-specific attributes `type`, `lib`, and
351     `generate` as specified [below](#pkgs-formats-result).
353     The `lib` attribute contains functions to be used in settings, for
354     generating special Elixir values:
356     `mkRaw elixirCode`
358     :   Outputs the given string as raw Elixir code
360     `mkGetEnv { envVariable, fallback ? null }`
362     :   Makes the configuration fetch an environment variable at runtime
364     `mkAtom atom`
366     :   Outputs the given string as an Elixir atom, instead of the default
367         Elixir binary string. Note: lowercase atoms still needs to be prefixed
368         with `:`
370     `mkTuple array`
372     :   Outputs the given array as an Elixir tuple, instead of the default
373         Elixir list
375     `mkMap attrset`
377     :   Outputs the given attribute set as an Elixir map, instead of the
378         default Elixir keyword list
380 `pkgs.formats.php { finalVariable }` []{#pkgs-formats-php}
382 :   A function taking an attribute set with values
384     `finalVariable`
386     :   The variable that will store generated expression (usually `config`). If set to `null`, generated expression will contain `return`.
388     It returns a set with PHP-Config-specific attributes `type`, `lib`, and
389     `generate` as specified [below](#pkgs-formats-result).
391     The `lib` attribute contains functions to be used in settings, for
392     generating special PHP values:
394     `mkRaw phpCode`
396     :   Outputs the given string as raw PHP code
398     `mkMixedArray list set`
400     :   Creates PHP array that contains both indexed and associative values. For example, `lib.mkMixedArray [ "hello" "world" ] { "nix" = "is-great"; }` returns `['hello', 'world', 'nix' => 'is-great']`
402 []{#pkgs-formats-result}
403 These functions all return an attribute set with these values:
405 `type`
407 :   A module system type representing a value of the format
409 `lib`
411 :   Utility functions for convenience, or special interactions with the format.
412     This attribute is optional. It may contain inside a `types` attribute
413     containing types specific to this format.
415 `generate` *`filename jsonValue`*
417 :   A function that can render a value of the format to a file. Returns
418     a file path.
420     ::: {.note}
421     This function puts the value contents in the Nix store. So this
422     should be avoided for secrets.
423     :::
425 ::: {#ex-settings-nix-representable .example}
426 ### Module with conventional `settings` option
428 The following shows a module for an example program that uses a JSON
429 configuration file. It demonstrates how above values can be used, along
430 with some other related best practices. See the comments for
431 explanations.
433 ```nix
434 { options, config, lib, pkgs, ... }:
436   cfg = config.services.foo;
437   # Define the settings format used for this program
438   settingsFormat = pkgs.formats.json {};
439 in {
441   options.services.foo = {
442     enable = lib.mkEnableOption "foo service";
444     settings = lib.mkOption {
445       # Setting this type allows for correct merging behavior
446       type = settingsFormat.type;
447       default = {};
448       description = ''
449         Configuration for foo, see
450         <link xlink:href="https://example.com/docs/foo"/>
451         for supported settings.
452       '';
453     };
454   };
456   config = lib.mkIf cfg.enable {
457     # We can assign some default settings here to make the service work by just
458     # enabling it. We use `mkDefault` for values that can be changed without
459     # problems
460     services.foo.settings = {
461       # Fails at runtime without any value set
462       log_level = lib.mkDefault "WARN";
464       # We assume systemd's `StateDirectory` is used, so we require this value,
465       # therefore no mkDefault
466       data_path = "/var/lib/foo";
468       # Since we use this to create a user we need to know the default value at
469       # eval time
470       user = lib.mkDefault "foo";
471     };
473     environment.etc."foo.json".source =
474       # The formats generator function takes a filename and the Nix value
475       # representing the format value and produces a filepath with that value
476       # rendered in the format
477       settingsFormat.generate "foo-config.json" cfg.settings;
479     # We know that the `user` attribute exists because we set a default value
480     # for it above, allowing us to use it without worries here
481     users.users.${cfg.settings.user} = { isSystemUser = true; };
483     # ...
484   };
489 ### Option declarations for attributes {#sec-settings-attrs-options}
491 Some `settings` attributes may deserve some extra care. They may need a
492 different type, default or merging behavior, or they are essential
493 options that should show their documentation in the manual. This can be
494 done using [](#sec-freeform-modules).
496 We extend above example using freeform modules to declare an option for
497 the port, which will enforce it to be a valid integer and make it show
498 up in the manual.
500 ::: {#ex-settings-typed-attrs .example}
501 ### Declaring a type-checked `settings` attribute
502 ```nix
504   settings = lib.mkOption {
505     type = lib.types.submodule {
507       freeformType = settingsFormat.type;
509       # Declare an option for the port such that the type is checked and this option
510       # is shown in the manual.
511       options.port = lib.mkOption {
512         type = lib.types.port;
513         default = 8080;
514         description = ''
515           Which port this service should listen on.
516         '';
517       };
519     };
520     default = {};
521     description = ''
522       Configuration for Foo, see
523       <link xlink:href="https://example.com/docs/foo"/>
524       for supported values.
525     '';
526   };