-
-
Notifications
You must be signed in to change notification settings - Fork 14.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
nixos/docs: Add documentation for settings options
- Loading branch information
Showing
2 changed files
with
180 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
<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, ... } | ||
</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> | ||
</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 | ||
<link xlink:href="https://example.com/docs/foo"/> | ||
for supported values. | ||
''; | ||
}; | ||
}; | ||
|
||
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} = {} | ||
|
||
# ... | ||
}; | ||
} | ||
</programlisting> | ||
</example> | ||
</section> | ||
|
||
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters