summaryrefslogtreecommitdiffstats
path: root/nixos/doc
diff options
context:
space:
mode:
authorSilvan Mosberger <github@infinisil.com>2020-12-18 16:42:42 +0100
committerSilvan Mosberger <github@infinisil.com>2020-12-18 16:44:37 +0100
commit9e6737710c4fb2613850e699178b23d54f1a3261 (patch)
tree9ba4d7163707bbc92e8a5917680426b0a01836f4 /nixos/doc
parentfd1cc29974de2255d407a706f23aacdfb76f543b (diff)
Revert "Module-builtin assertions, disabling assertions and submodule assertions"
Diffstat (limited to 'nixos/doc')
-rw-r--r--nixos/doc/manual/development/assertions.xml159
1 files changed, 38 insertions, 121 deletions
diff --git a/nixos/doc/manual/development/assertions.xml b/nixos/doc/manual/development/assertions.xml
index 31d09f958af5..32f90cf2e7c4 100644
--- a/nixos/doc/manual/development/assertions.xml
+++ b/nixos/doc/manual/development/assertions.xml
@@ -3,155 +3,72 @@
xmlns:xi="http://www.w3.org/2001/XInclude"
version="5.0"
xml:id="sec-assertions">
- <title>Evaluation Checks</title>
+ <title>Warnings and Assertions</title>
<para>
When configuration problems are detectable in a module, it is a good idea to
- write a check for catching it early. Doing so can provide clear feedback to
- the user and can prevent errors before the build.
+ write an assertion or warning. Doing so provides clear feedback to the user
+ and prevents errors after the build.
</para>
<para>
Although Nix has the <literal>abort</literal> and
<literal>builtins.trace</literal>
<link xlink:href="https://nixos.org/nix/manual/#ssec-builtins">functions</link>
- to perform such tasks generally, they are not ideally suited for NixOS
- modules. Instead of these functions, you can declare your evaluation checks
- using the NixOS module system.
+ to perform such tasks, they are not ideally suited for NixOS modules. Instead
+ of these functions, you can declare your warnings and assertions using the
+ NixOS module system.
</para>
- <section xml:id="sec-assertions-define">
- <title>Defining Checks</title>
+ <section xml:id="sec-assertions-warnings">
+ <title>Warnings</title>
<para>
- Checks can be defined using the <xref linkend="opt-_module.checks"/> option.
- Each check needs an attribute name, under which you can define a trigger
- assertion using <xref linkend="opt-_module.checks._name_.check"/> and a
- message using <xref linkend="opt-_module.checks._name_.message"/>.
- For the message, you can add
- <literal>options</literal> to the module arguments and use
- <literal>${options.path.to.option}</literal> to print a context-aware string
- representation of an option path. Here is an example showing how this can be
- done.
- </para>
-
-<programlisting>
-{ config, options, ... }: {
- _module.checks.gpgSshAgent = {
- check = config.programs.gnupg.agent.enableSSHSupport -> !config.programs.ssh.startAgent;
- message = "If you have ${options.programs.gnupg.agent.enableSSHSupport} enabled,"
- + " you can't enable ${options.programs.ssh.startAgent} as well!";
- };
-
- _module.checks.grafanaPassword = {
- check = config.services.grafana.database.password == "";
- message = "The grafana password defined with ${options.services.grafana.database.password}"
- + " will be stored as plaintext in the Nix store!";
- # This is a non-fatal warning
- type = "warning";
- };
-}
-</programlisting>
-
- </section>
-
- <section xml:id="sec-assertions-ignoring">
- <title>Ignoring Checks</title>
-
- <para>
- Sometimes you can get failing checks that don't apply to your specific case
- and you wish to ignore them, or at least make errors non-fatal. You can do so
- for all checks defined using <xref linkend="opt-_module.checks"/> by
- using the attribute name of the definition, which is conveniently printed
- using <literal>[...]</literal> when the check is triggered. For above
- example, the evaluation output when the checks are triggered looks as
- follows:
- </para>
-
-<programlisting>
-trace: warning: [grafanaPassword] The grafana password defined with
- services.grafana.database.password will be stored as plaintext in the Nix store!
-error: Failed checks:
-- [gpgSshAgent] If you have programs.gnupg.agent.enableSSHSupport
- enabled, you can't enable programs.ssh.startAgent as well!
-</programlisting>
-
- <para>
- The <literal>[grafanaPassword]</literal> and <literal>[gpgSshAgent]</literal>
- strings tell you that these were defined under the <literal>grafanaPassword
- </literal> and <literal>gpgSshAgent</literal> attributes of
- <xref linkend="opt-_module.checks"/> respectively. With this knowledge
- you can adjust them to your liking:
+ This is an example of using <literal>warnings</literal>.
</para>
<programlisting>
+<![CDATA[
+{ config, lib, ... }:
{
- # Change the error into a non-fatal warning
- _module.checks.gpgSshAgent.type = "warning";
-
- # We don't care about this warning, disable it
- _module.checks.grafanaPassword.enable = false;
+ config = lib.mkIf config.services.foo.enable {
+ warnings =
+ if config.services.foo.bar
+ then [ ''You have enabled the bar feature of the foo service.
+ This is known to cause some specific problems in certain situations.
+ '' ]
+ else [];
+ }
}
+]]>
</programlisting>
-
-
</section>
- <section xml:id="sec-assertions-submodules">
- <title>Checks in Submodules</title>
- <para>
- Evaluation checks can be defined within submodules in the same way. Here is an example:
- </para>
-
-<programlisting>
-{ lib, ... }: {
-
- options.myServices = lib.mkOption {
- type = lib.types.attrsOf (lib.types.submodule ({ config, options, ... }: {
- options.port = lib.mkOption {};
-
- config._module.checks.portConflict = {
- check = config.port != 80;
- message = "Port ${toString config.port} defined using"
- + " ${options.port} is usually used for HTTP";
- type = "warning";
- };
- }));
- };
-
-}
-</programlisting>
+ <section xml:id="sec-assertions-assertions">
+ <title>Assertions</title>
<para>
- When this check is triggered, it shows both the submodule path along with
- the check attribute within that submodule, joined by a
- <literal>/</literal>. Note also how <literal>${options.port}</literal>
- correctly shows the context of the option.
- </para>
-
-<programlisting>
-trace: warning: [myServices.foo/portConflict] Port 80 defined using
- myServices.foo.port is usually used for HTTP
-</programlisting>
-
- <para>
- Therefore to disable such a check, you can do so by changing the
- <xref linkend="opt-_module.checks"/> option within the
- <literal>myServices.foo</literal> submodule:
+ This example, extracted from the
+ <link xlink:href="https://github.com/NixOS/nixpkgs/blob/release-17.09/nixos/modules/services/logging/syslogd.nix">
+ <literal>syslogd</literal> module </link> shows how to use
+ <literal>assertions</literal>. Since there can only be one active syslog
+ daemon at a time, an assertion is useful to prevent such a broken system
+ from being built.
</para>
<programlisting>
+<![CDATA[
+{ config, lib, ... }:
{
- myServices.foo._module.checks.portConflict.enable = false;
+ config = lib.mkIf config.services.syslogd.enable {
+ assertions =
+ [ { assertion = !config.services.rsyslogd.enable;
+ message = "rsyslogd conflicts with syslogd";
+ }
+ ];
+ }
}
+]]>
</programlisting>
-
-<note>
- <para>
- Checks defined in submodules under <literal>types.listOf</literal> can't be
- ignored, since there's no way to change previously defined list items.
- </para>
-</note>
-
</section>
</section>