nixos: nixos/doc/manual/development/settings-options.xml to CommonMark

Changed files
+479 -228
nixos
+192
nixos/doc/manual/development/settings-options.section.md
···
···
+
# Options for Program Settings {#sec-settings-options}
+
+
Many programs have configuration files where program-specific settings
+
can be declared. File formats can be separated into two categories:
+
+
- Nix-representable ones: These can trivially be mapped to a subset of
+
Nix syntax. E.g. JSON is an example, since its values like
+
`{"foo":{"bar":10}}` can be mapped directly to Nix:
+
`{ foo = { bar = 10; }; }`. Other examples are INI, YAML and TOML.
+
The following section explains the convention for these settings.
+
+
- Non-nix-representable ones: These can\'t be trivially mapped to a
+
subset of Nix syntax. Most generic programming languages are in this
+
group, e.g. bash, since the statement `if true; then echo hi; fi`
+
doesn\'t have a trivial representation in Nix.
+
+
Currently there are no fixed conventions for these, but it is common
+
to have a `configFile` option for setting the configuration file
+
path directly. The default value of `configFile` can be an
+
auto-generated file, with convenient options for controlling the
+
contents. For example an option of type `attrsOf str` can be used
+
for representing environment variables which generates a section
+
like `export FOO="foo"`. Often it can also be useful to also include
+
an `extraConfig` option of type `lines` to allow arbitrary text
+
after the autogenerated part of the file.
+
+
## Nix-representable Formats (JSON, YAML, TOML, INI, \...) {#sec-settings-nix-representable}
+
+
By convention, formats like this are handled with a generic `settings`
+
option, representing the full program configuration as a Nix value. The
+
type of this option should represent the format. The most common formats
+
have a predefined type and string generator already declared under
+
`pkgs.formats`:
+
+
`pkgs.formats.json` { }
+
+
: A function taking an empty attribute set (for future extensibility)
+
and returning a set with JSON-specific attributes `type` and
+
`generate` as specified [below](#pkgs-formats-result).
+
+
`pkgs.formats.yaml` { }
+
+
: A function taking an empty attribute set (for future extensibility)
+
and returning a set with YAML-specific attributes `type` and
+
`generate` as specified [below](#pkgs-formats-result).
+
+
`pkgs.formats.ini` { *`listsAsDuplicateKeys`* ? false, *`listToValue`* ? null, \... }
+
+
: A function taking an attribute set with values
+
+
`listsAsDuplicateKeys`
+
+
: A boolean for controlling whether list values can be used to
+
represent duplicate INI keys
+
+
`listToValue`
+
+
: A function for turning a list of values into a single value.
+
+
It returns a set with INI-specific attributes `type` and `generate`
+
as specified [below](#pkgs-formats-result).
+
+
`pkgs.formats.toml` { }
+
+
: A function taking an empty attribute set (for future extensibility)
+
and returning a set with TOML-specific attributes `type` and
+
`generate` as specified [below](#pkgs-formats-result).
+
+
::: {#pkgs-formats-result}
+
These functions all return an attribute set with these values:
+
:::
+
+
`type`
+
+
: A module system type representing a value of the format
+
+
`generate` *`filename jsonValue`*
+
+
: A function that can render a value of the format to a file. Returns
+
a file path.
+
+
::: {.note}
+
This function puts the value contents in the Nix store. So this
+
should be avoided for secrets.
+
:::
+
+
::: {#ex-settings-nix-representable .example}
+
::: {.title}
+
**Example: Module with conventional `settings` option**
+
:::
+
The following shows a module for an example program that uses a JSON
+
configuration file. It demonstrates how above values can be used, along
+
with some other related best practices. See the comments for
+
explanations.
+
+
```nix
+
{ options, config, lib, pkgs, ... }:
+
let
+
cfg = config.services.foo;
+
# Define the settings format used for this program
+
settingsFormat = pkgs.formats.json {};
+
in {
+
+
options.services.foo = {
+
enable = lib.mkEnableOption "foo service";
+
+
settings = lib.mkOption {
+
# Setting this type allows for correct merging behavior
+
type = settingsFormat.type;
+
default = {};
+
description = ''
+
Configuration for foo, see
+
<link xlink:href="https://example.com/docs/foo"/>
+
for supported settings.
+
'';
+
};
+
};
+
+
config = lib.mkIf cfg.enable {
+
# We can assign some default settings here to make the service work by just
+
# enabling it. We use `mkDefault` for values that can be changed without
+
# problems
+
services.foo.settings = {
+
# Fails at runtime without any value set
+
log_level = lib.mkDefault "WARN";
+
+
# We assume systemd's `StateDirectory` is used, so we require this value,
+
# therefore no mkDefault
+
data_path = "/var/lib/foo";
+
+
# Since we use this to create a user we need to know the default value at
+
# eval time
+
user = lib.mkDefault "foo";
+
};
+
+
environment.etc."foo.json".source =
+
# The formats generator function takes a filename and the Nix value
+
# representing the format value and produces a filepath with that value
+
# rendered in the format
+
settingsFormat.generate "foo-config.json" cfg.settings;
+
+
# We know that the `user` attribute exists because we set a default value
+
# for it above, allowing us to use it without worries here
+
users.users.${cfg.settings.user} = { isSystemUser = true; };
+
+
# ...
+
};
+
}
+
```
+
:::
+
+
### Option declarations for attributes {#sec-settings-attrs-options}
+
+
Some `settings` attributes may deserve some extra care. They may need a
+
different type, default or merging behavior, or they are essential
+
options that should show their documentation in the manual. This can be
+
done using [](#sec-freeform-modules).
+
+
We extend above example using freeform modules to declare an option for
+
the port, which will enforce it to be a valid integer and make it show
+
up in the manual.
+
+
::: {#ex-settings-typed-attrs .example}
+
::: {.title}
+
**Example: Declaring a type-checked `settings` attribute**
+
:::
+
```nix
+
settings = lib.mkOption {
+
type = lib.types.submodule {
+
+
freeformType = settingsFormat.type;
+
+
# Declare an option for the port such that the type is checked and this option
+
# is shown in the manual.
+
options.port = lib.mkOption {
+
type = lib.types.port;
+
default = 8080;
+
description = ''
+
Which port this service should listen on.
+
'';
+
};
+
+
};
+
default = {};
+
description = ''
+
Configuration for Foo, see
+
<link xlink:href="https://example.com/docs/foo"/>
+
for supported values.
+
'';
+
};
+
```
+
:::
-226
nixos/doc/manual/development/settings-options.xml
···
-
<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-settings-options">
-
<title>Options for Program Settings</title>
-
-
<para>
-
Many programs have configuration files where program-specific settings can be declared. File formats can be separated into two categories:
-
<itemizedlist>
-
<listitem>
-
<para>
-
Nix-representable ones: These can trivially be mapped to a subset of Nix syntax. E.g. JSON is an example, since its values like <literal>{"foo":{"bar":10}}</literal> can be mapped directly to Nix: <literal>{ foo = { bar = 10; }; }</literal>. Other examples are INI, YAML and TOML. The following section explains the convention for these settings.
-
</para>
-
</listitem>
-
<listitem>
-
<para>
-
Non-nix-representable ones: These can't be trivially mapped to a subset of Nix syntax. Most generic programming languages are in this group, e.g. bash, since the statement <literal>if true; then echo hi; fi</literal> doesn't have a trivial representation in Nix.
-
</para>
-
<para>
-
Currently there are no fixed conventions for these, but it is common to have a <literal>configFile</literal> option for setting the configuration file path directly. The default value of <literal>configFile</literal> can be an auto-generated file, with convenient options for controlling the contents. For example an option of type <literal>attrsOf str</literal> can be used for representing environment variables which generates a section like <literal>export FOO="foo"</literal>. Often it can also be useful to also include an <literal>extraConfig</literal> option of type <literal>lines</literal> to allow arbitrary text after the autogenerated part of the file.
-
</para>
-
</listitem>
-
</itemizedlist>
-
</para>
-
<section xml:id="sec-settings-nix-representable">
-
<title>Nix-representable Formats (JSON, YAML, TOML, INI, ...)</title>
-
<para>
-
By convention, formats like this are handled with a generic <literal>settings</literal> option, representing the full program configuration as a Nix value. The type of this option should represent the format. The most common formats have a predefined type and string generator already declared under <literal>pkgs.formats</literal>:
-
<variablelist>
-
<varlistentry>
-
<term>
-
<varname>pkgs.formats.json</varname> { }
-
</term>
-
<listitem>
-
<para>
-
A function taking an empty attribute set (for future extensibility) and returning a set with JSON-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
-
</para>
-
</listitem>
-
</varlistentry>
-
<varlistentry>
-
<term>
-
<varname>pkgs.formats.yaml</varname> { }
-
</term>
-
<listitem>
-
<para>
-
A function taking an empty attribute set (for future extensibility) and returning a set with YAML-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
-
</para>
-
</listitem>
-
</varlistentry>
-
<varlistentry>
-
<term>
-
<varname>pkgs.formats.ini</varname> { <replaceable>listsAsDuplicateKeys</replaceable> ? false, <replaceable>listToValue</replaceable> ? null, ... }
-
</term>
-
<listitem>
-
<para>
-
A function taking an attribute set with values
-
<variablelist>
-
<varlistentry>
-
<term>
-
<varname>listsAsDuplicateKeys</varname>
-
</term>
-
<listitem>
-
<para>
-
A boolean for controlling whether list values can be used to represent duplicate INI keys
-
</para>
-
</listitem>
-
</varlistentry>
-
<varlistentry>
-
<term>
-
<varname>listToValue</varname>
-
</term>
-
<listitem>
-
<para>
-
A function for turning a list of values into a single value.
-
</para>
-
</listitem>
-
</varlistentry>
-
</variablelist>
-
It returns a set with INI-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
-
</para>
-
</listitem>
-
</varlistentry>
-
<varlistentry>
-
<term>
-
<varname>pkgs.formats.toml</varname> { }
-
</term>
-
<listitem>
-
<para>
-
A function taking an empty attribute set (for future extensibility) and returning a set with TOML-specific attributes <varname>type</varname> and <varname>generate</varname> as specified <link linkend='pkgs-formats-result'>below</link>.
-
</para>
-
</listitem>
-
</varlistentry>
-
</variablelist>
-
-
</para>
-
<para xml:id="pkgs-formats-result">
-
These functions all return an attribute set with these values:
-
<variablelist>
-
<varlistentry>
-
<term>
-
<varname>type</varname>
-
</term>
-
<listitem>
-
<para>
-
A module system type representing a value of the format
-
</para>
-
</listitem>
-
</varlistentry>
-
<varlistentry>
-
<term>
-
<varname>generate</varname> <replaceable>filename</replaceable> <replaceable>jsonValue</replaceable>
-
</term>
-
<listitem>
-
<para>
-
A function that can render a value of the format to a file. Returns a file path.
-
<note>
-
<para>
-
This function puts the value contents in the Nix store. So this should be avoided for secrets.
-
</para>
-
</note>
-
</para>
-
</listitem>
-
</varlistentry>
-
</variablelist>
-
</para>
-
<example xml:id="ex-settings-nix-representable">
-
<title>Module with conventional <literal>settings</literal> option</title>
-
<para>
-
The following shows a module for an example program that uses a JSON configuration file. It demonstrates how above values can be used, along with some other related best practices. See the comments for explanations.
-
</para>
-
<programlisting>
-
{ options, config, lib, pkgs, ... }:
-
let
-
cfg = config.services.foo;
-
# Define the settings format used for this program
-
settingsFormat = pkgs.formats.json {};
-
in {
-
-
options.services.foo = {
-
enable = lib.mkEnableOption "foo service";
-
-
settings = lib.mkOption {
-
# Setting this type allows for correct merging behavior
-
type = settingsFormat.type;
-
default = {};
-
description = ''
-
Configuration for foo, see
-
&lt;link xlink:href="https://example.com/docs/foo"/&gt;
-
for supported settings.
-
'';
-
};
-
};
-
-
config = lib.mkIf cfg.enable {
-
# We can assign some default settings here to make the service work by just
-
# enabling it. We use `mkDefault` for values that can be changed without
-
# problems
-
services.foo.settings = {
-
# Fails at runtime without any value set
-
log_level = lib.mkDefault "WARN";
-
-
# We assume systemd's `StateDirectory` is used, so we require this value,
-
# therefore no mkDefault
-
data_path = "/var/lib/foo";
-
-
# Since we use this to create a user we need to know the default value at
-
# eval time
-
user = lib.mkDefault "foo";
-
};
-
-
environment.etc."foo.json".source =
-
# The formats generator function takes a filename and the Nix value
-
# representing the format value and produces a filepath with that value
-
# rendered in the format
-
settingsFormat.generate "foo-config.json" cfg.settings;
-
-
# We know that the `user` attribute exists because we set a default value
-
# for it above, allowing us to use it without worries here
-
users.users.${cfg.settings.user} = { isSystemUser = true; };
-
-
# ...
-
};
-
}
-
</programlisting>
-
</example>
-
<section xml:id="sec-settings-attrs-options">
-
<title>Option declarations for attributes</title>
-
<para>
-
Some <literal>settings</literal> attributes may deserve some extra care. They may need a different type, default or merging behavior, or they are essential options that should show their documentation in the manual. This can be done using <xref linkend='sec-freeform-modules'/>.
-
<example xml:id="ex-settings-typed-attrs">
-
<title>Declaring a type-checked <literal>settings</literal> attribute</title>
-
<para>
-
We extend above example using freeform modules to declare an option for the port, which will enforce it to be a valid integer and make it show up in the manual.
-
</para>
-
<programlisting>
-
settings = lib.mkOption {
-
type = lib.types.submodule {
-
-
freeformType = settingsFormat.type;
-
-
# Declare an option for the port such that the type is checked and this option
-
# is shown in the manual.
-
options.port = lib.mkOption {
-
type = lib.types.port;
-
default = 8080;
-
description = ''
-
Which port this service should listen on.
-
'';
-
};
-
-
};
-
default = {};
-
description = ''
-
Configuration for Foo, see
-
&lt;link xlink:href="https://example.com/docs/foo"/&gt;
-
for supported values.
-
'';
-
};
-
</programlisting>
-
</example>
-
</para>
-
</section>
-
</section>
-
-
</section>
···
+2 -2
nixos/doc/manual/development/writing-modules.xml
···
<xi:include href="../from_md/development/meta-attributes.section.xml" />
<xi:include href="../from_md/development/importing-modules.section.xml" />
<xi:include href="../from_md/development/replace-modules.section.xml" />
-
<xi:include href="freeform-modules.xml" />
-
<xi:include href="settings-options.xml" />
</chapter>
···
<xi:include href="../from_md/development/meta-attributes.section.xml" />
<xi:include href="../from_md/development/importing-modules.section.xml" />
<xi:include href="../from_md/development/replace-modules.section.xml" />
+
<xi:include href="../from_md/development/freeform-modules.section.xml" />
+
<xi:include href="../from_md/development/settings-options.section.xml" />
</chapter>
+285
nixos/doc/manual/from_md/development/settings-options.section.xml
···
···
+
<section xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xml:id="sec-settings-options">
+
<title>Options for Program Settings</title>
+
<para>
+
Many programs have configuration files where program-specific
+
settings can be declared. File formats can be separated into two
+
categories:
+
</para>
+
<itemizedlist>
+
<listitem>
+
<para>
+
Nix-representable ones: These can trivially be mapped to a
+
subset of Nix syntax. E.g. JSON is an example, since its values
+
like <literal>{&quot;foo&quot;:{&quot;bar&quot;:10}}</literal>
+
can be mapped directly to Nix:
+
<literal>{ foo = { bar = 10; }; }</literal>. Other examples are
+
INI, YAML and TOML. The following section explains the
+
convention for these settings.
+
</para>
+
</listitem>
+
<listitem>
+
<para>
+
Non-nix-representable ones: These can't be trivially mapped to a
+
subset of Nix syntax. Most generic programming languages are in
+
this group, e.g. bash, since the statement
+
<literal>if true; then echo hi; fi</literal> doesn't have a
+
trivial representation in Nix.
+
</para>
+
<para>
+
Currently there are no fixed conventions for these, but it is
+
common to have a <literal>configFile</literal> option for
+
setting the configuration file path directly. The default value
+
of <literal>configFile</literal> can be an auto-generated file,
+
with convenient options for controlling the contents. For
+
example an option of type <literal>attrsOf str</literal> can be
+
used for representing environment variables which generates a
+
section like <literal>export FOO=&quot;foo&quot;</literal>.
+
Often it can also be useful to also include an
+
<literal>extraConfig</literal> option of type
+
<literal>lines</literal> to allow arbitrary text after the
+
autogenerated part of the file.
+
</para>
+
</listitem>
+
</itemizedlist>
+
<section xml:id="sec-settings-nix-representable">
+
<title>Nix-representable Formats (JSON, YAML, TOML, INI,
+
...)</title>
+
<para>
+
By convention, formats like this are handled with a generic
+
<literal>settings</literal> option, representing the full program
+
configuration as a Nix value. The type of this option should
+
represent the format. The most common formats have a predefined
+
type and string generator already declared under
+
<literal>pkgs.formats</literal>:
+
</para>
+
<variablelist>
+
<varlistentry>
+
<term>
+
<literal>pkgs.formats.json</literal> { }
+
</term>
+
<listitem>
+
<para>
+
A function taking an empty attribute set (for future
+
extensibility) and returning a set with JSON-specific
+
attributes <literal>type</literal> and
+
<literal>generate</literal> as specified
+
<link linkend="pkgs-formats-result">below</link>.
+
</para>
+
</listitem>
+
</varlistentry>
+
<varlistentry>
+
<term>
+
<literal>pkgs.formats.yaml</literal> { }
+
</term>
+
<listitem>
+
<para>
+
A function taking an empty attribute set (for future
+
extensibility) and returning a set with YAML-specific
+
attributes <literal>type</literal> and
+
<literal>generate</literal> as specified
+
<link linkend="pkgs-formats-result">below</link>.
+
</para>
+
</listitem>
+
</varlistentry>
+
<varlistentry>
+
<term>
+
<literal>pkgs.formats.ini</literal> {
+
<emphasis><literal>listsAsDuplicateKeys</literal></emphasis> ?
+
false, <emphasis><literal>listToValue</literal></emphasis> ?
+
null, ... }
+
</term>
+
<listitem>
+
<para>
+
A function taking an attribute set with values
+
</para>
+
<variablelist>
+
<varlistentry>
+
<term>
+
<literal>listsAsDuplicateKeys</literal>
+
</term>
+
<listitem>
+
<para>
+
A boolean for controlling whether list values can be
+
used to represent duplicate INI keys
+
</para>
+
</listitem>
+
</varlistentry>
+
<varlistentry>
+
<term>
+
<literal>listToValue</literal>
+
</term>
+
<listitem>
+
<para>
+
A function for turning a list of values into a single
+
value.
+
</para>
+
</listitem>
+
</varlistentry>
+
</variablelist>
+
<para>
+
It returns a set with INI-specific attributes
+
<literal>type</literal> and <literal>generate</literal> as
+
specified <link linkend="pkgs-formats-result">below</link>.
+
</para>
+
</listitem>
+
</varlistentry>
+
<varlistentry>
+
<term>
+
<literal>pkgs.formats.toml</literal> { }
+
</term>
+
<listitem>
+
<para>
+
A function taking an empty attribute set (for future
+
extensibility) and returning a set with TOML-specific
+
attributes <literal>type</literal> and
+
<literal>generate</literal> as specified
+
<link linkend="pkgs-formats-result">below</link>.
+
</para>
+
</listitem>
+
</varlistentry>
+
</variablelist>
+
<para xml:id="pkgs-formats-result">
+
These functions all return an attribute set with these values:
+
</para>
+
<variablelist>
+
<varlistentry>
+
<term>
+
<literal>type</literal>
+
</term>
+
<listitem>
+
<para>
+
A module system type representing a value of the format
+
</para>
+
</listitem>
+
</varlistentry>
+
<varlistentry>
+
<term>
+
<literal>generate</literal>
+
<emphasis><literal>filename jsonValue</literal></emphasis>
+
</term>
+
<listitem>
+
<para>
+
A function that can render a value of the format to a file.
+
Returns a file path.
+
</para>
+
<note>
+
<para>
+
This function puts the value contents in the Nix store. So
+
this should be avoided for secrets.
+
</para>
+
</note>
+
</listitem>
+
</varlistentry>
+
</variablelist>
+
<anchor xml:id="ex-settings-nix-representable" />
+
<para>
+
<emphasis role="strong">Example: Module with conventional
+
<literal>settings</literal> option</emphasis>
+
</para>
+
<para>
+
The following shows a module for an example program that uses a
+
JSON configuration file. It demonstrates how above values can be
+
used, along with some other related best practices. See the
+
comments for explanations.
+
</para>
+
<programlisting language="bash">
+
{ options, config, lib, pkgs, ... }:
+
let
+
cfg = config.services.foo;
+
# Define the settings format used for this program
+
settingsFormat = pkgs.formats.json {};
+
in {
+
+
options.services.foo = {
+
enable = lib.mkEnableOption &quot;foo service&quot;;
+
+
settings = lib.mkOption {
+
# Setting this type allows for correct merging behavior
+
type = settingsFormat.type;
+
default = {};
+
description = ''
+
Configuration for foo, see
+
&lt;link xlink:href=&quot;https://example.com/docs/foo&quot;/&gt;
+
for supported settings.
+
'';
+
};
+
};
+
+
config = lib.mkIf cfg.enable {
+
# We can assign some default settings here to make the service work by just
+
# enabling it. We use `mkDefault` for values that can be changed without
+
# problems
+
services.foo.settings = {
+
# Fails at runtime without any value set
+
log_level = lib.mkDefault &quot;WARN&quot;;
+
+
# We assume systemd's `StateDirectory` is used, so we require this value,
+
# therefore no mkDefault
+
data_path = &quot;/var/lib/foo&quot;;
+
+
# Since we use this to create a user we need to know the default value at
+
# eval time
+
user = lib.mkDefault &quot;foo&quot;;
+
};
+
+
environment.etc.&quot;foo.json&quot;.source =
+
# The formats generator function takes a filename and the Nix value
+
# representing the format value and produces a filepath with that value
+
# rendered in the format
+
settingsFormat.generate &quot;foo-config.json&quot; cfg.settings;
+
+
# We know that the `user` attribute exists because we set a default value
+
# for it above, allowing us to use it without worries here
+
users.users.${cfg.settings.user} = { isSystemUser = true; };
+
+
# ...
+
};
+
}
+
</programlisting>
+
<section xml:id="sec-settings-attrs-options">
+
<title>Option declarations for attributes</title>
+
<para>
+
Some <literal>settings</literal> attributes may deserve some
+
extra care. They may need a different type, default or merging
+
behavior, or they are essential options that should show their
+
documentation in the manual. This can be done using
+
<xref linkend="sec-freeform-modules" />.
+
</para>
+
<para>
+
We extend above example using freeform modules to declare an
+
option for the port, which will enforce it to be a valid integer
+
and make it show up in the manual.
+
</para>
+
<anchor xml:id="ex-settings-typed-attrs" />
+
<para>
+
<emphasis role="strong">Example: Declaring a type-checked
+
<literal>settings</literal> attribute</emphasis>
+
</para>
+
<programlisting language="bash">
+
settings = lib.mkOption {
+
type = lib.types.submodule {
+
+
freeformType = settingsFormat.type;
+
+
# Declare an option for the port such that the type is checked and this option
+
# is shown in the manual.
+
options.port = lib.mkOption {
+
type = lib.types.port;
+
default = 8080;
+
description = ''
+
Which port this service should listen on.
+
'';
+
};
+
+
};
+
default = {};
+
description = ''
+
Configuration for Foo, see
+
&lt;link xlink:href=&quot;https://example.com/docs/foo&quot;/&gt;
+
for supported values.
+
'';
+
};
+
</programlisting>
+
</section>
+
</section>
+
</section>