diff options
author | Silvan Mosberger <contact@infinisil.com> | 2020-03-06 15:02:07 +0100 |
---|---|---|
committer | Silvan Mosberger <contact@infinisil.com> | 2020-07-29 18:08:25 +0200 |
commit | 83b16885f526d6ab7b39e98159e2b48024f3238c (patch) | |
tree | 36c562ac0408c4d52b0623ad2f625bfc8d6b1df7 /nixos/doc/manual | |
parent | 9c1565a042ecd2f03b800f14f3cdc5ba0d464b5d (diff) | |
download | nixpkgs-83b16885f526d6ab7b39e98159e2b48024f3238c.tar nixpkgs-83b16885f526d6ab7b39e98159e2b48024f3238c.tar.gz nixpkgs-83b16885f526d6ab7b39e98159e2b48024f3238c.tar.bz2 nixpkgs-83b16885f526d6ab7b39e98159e2b48024f3238c.tar.lz nixpkgs-83b16885f526d6ab7b39e98159e2b48024f3238c.tar.xz nixpkgs-83b16885f526d6ab7b39e98159e2b48024f3238c.tar.zst nixpkgs-83b16885f526d6ab7b39e98159e2b48024f3238c.zip |
nixos/docs: Add documentation for settings options
Diffstat (limited to 'nixos/doc/manual')
-rw-r--r-- | nixos/doc/manual/development/settings-options.xml | 179 | ||||
-rw-r--r-- | nixos/doc/manual/development/writing-modules.xml | 1 |
2 files changed, 180 insertions, 0 deletions
diff --git a/nixos/doc/manual/development/settings-options.xml b/nixos/doc/manual/development/settings-options.xml new file mode 100644 index 00000000000..84895adb444 --- /dev/null +++ b/nixos/doc/manual/development/settings-options.xml @@ -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> diff --git a/nixos/doc/manual/development/writing-modules.xml b/nixos/doc/manual/development/writing-modules.xml index bbf793bb0be..602f134f9cb 100644 --- a/nixos/doc/manual/development/writing-modules.xml +++ b/nixos/doc/manual/development/writing-modules.xml @@ -183,4 +183,5 @@ in { <xi:include href="meta-attributes.xml" /> <xi:include href="importing-modules.xml" /> <xi:include href="replace-modules.xml" /> + <xi:include href="settings-options.xml" /> </chapter> |