diff --git a/lib/modules.nix b/lib/modules.nix
index 23dbe962491..468c373d6aa 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -155,17 +155,22 @@ rec {
default = {};
internal = prefix != [];
type = types.attrsOf (types.submodule {
- # TODO: Rename to assertion? Or allow also setting assertion?
options.enable = mkOption {
description = ''
- Whether to enable this check.
-
- This is the inverse of asserting a condition: If a certain
- condition should be true, then this
- option should be set to false when that
- case occurs
-
+ Whether to enable this check. Set this to false to not trigger
+ any errors or warning messages. This is useful for ignoring a
+ check in case it doesn't make sense in certain scenarios.
'';
+ default = true;
+ type = types.bool;
+ };
+
+ options.check = mkOption {
+ description = ''
+ The condition that must succeed in order for this check to be
+ successful and not trigger a warning or error.
+ '';
+ readOnly = true;
type = types.bool;
};
@@ -189,9 +194,7 @@ rec {
and use ''${options.path.to.option}.
'';
type = types.str;
- example = literalExample ''
- Enabling both ''${options.services.foo.enable} and ''${options.services.bar.enable} is not possible.
- '';
+ example = "Enabling both \${options.services.foo.enable} and \${options.services.bar.enable} is not possible.";
};
});
};
@@ -244,7 +247,7 @@ rec {
if lib.hasPrefix "_" name then value.message
else "[${showOption prefix}${optionalString (prefix != []) "/"}${name}] ${value.message}";
in
- if ! value.enable then errors
+ if value.enable -> value.check then errors
else if value.type == "warning" then lib.warn show errors
else if value.type == "error" then errors ++ [ show ]
else abort "Unknown check type ${value.type}";
@@ -885,8 +888,7 @@ rec {
});
config._module.checks =
let opt = getAttrFromPath optionName options; in {
- ${showOption optionName} = {
- enable = mkDefault opt.isDefined;
+ ${showOption optionName} = lib.mkIf opt.isDefined {
message = ''
The option definition `${showOption optionName}' in ${showFiles opt.files} no longer has any effect; please remove it.
${replacementInstructions}
@@ -958,8 +960,7 @@ rec {
let val = getAttrFromPath f config;
opt = getAttrFromPath f options;
in {
- ${showOption f} = {
- enable = mkDefault (val != "_mkMergedOptionModule");
+ ${showOption f} = lib.mkIf (val != "_mkMergedOptionModule") {
type = "warning";
message = "The option `${showOption f}' defined in ${showFiles opt.files} has been changed to `${showOption to}' that has a different type. Please read `${showOption to}' documentation and update your configuration accordingly.";
};
@@ -1024,8 +1025,7 @@ rec {
});
config = mkMerge [
{
- _module.checks.${showOption from} = {
- enable = mkDefault (warn && fromOpt.isDefined);
+ _module.checks.${showOption from} = mkIf (warn && fromOpt.isDefined) {
type = "warning";
message = "The option `${showOption from}' defined in ${showFiles fromOpt.files} has been renamed to `${showOption to}'.";
};
diff --git a/lib/tests/modules.sh b/lib/tests/modules.sh
index 9e85c90d15c..775be9f7209 100755
--- a/lib/tests/modules.sh
+++ b/lib/tests/modules.sh
@@ -279,7 +279,8 @@ checkConfigOutput baz config.value.nested.bar.baz ./types-anything/mk-mods.nix
# Check that assertions are triggered by default for just evaluating config
checkConfigError 'Failed checks:\n- \[test\] Assertion failed' config ./assertions/simple.nix
-# Assertion is not triggered when enable is false
+# Assertion is not triggered when enable is false or condition is true
+checkConfigOutput '{ }' config ./assertions/condition-true.nix
checkConfigOutput '{ }' config ./assertions/enable-false.nix
# Warnings should be displayed on standard error
diff --git a/lib/tests/modules/assertions/condition-true.nix b/lib/tests/modules/assertions/condition-true.nix
new file mode 100644
index 00000000000..7ca0817a239
--- /dev/null
+++ b/lib/tests/modules/assertions/condition-true.nix
@@ -0,0 +1,8 @@
+{
+
+ _module.checks.test = {
+ check = true;
+ message = "Assertion failed";
+ };
+
+}
diff --git a/lib/tests/modules/assertions/enable-false.nix b/lib/tests/modules/assertions/enable-false.nix
index c326c086f03..11f753bb32e 100644
--- a/lib/tests/modules/assertions/enable-false.nix
+++ b/lib/tests/modules/assertions/enable-false.nix
@@ -2,6 +2,7 @@
_module.checks.test = {
enable = false;
+ check = false;
message = "Assertion failed";
};
diff --git a/lib/tests/modules/assertions/multi.nix b/lib/tests/modules/assertions/multi.nix
index ebbe17f3a55..1e2e14b8643 100644
--- a/lib/tests/modules/assertions/multi.nix
+++ b/lib/tests/modules/assertions/multi.nix
@@ -2,20 +2,20 @@
_module.checks = {
test1 = {
- enable = true;
+ check = false;
message = "Assertion 1 failed";
};
test2 = {
- enable = true;
+ check = false;
message = "Assertion 2 failed";
};
test3 = {
- enable = true;
+ check = false;
message = "Warning 3 failed";
type = "warning";
};
test4 = {
- enable = true;
+ check = false;
message = "Warning 4 failed";
type = "warning";
};
diff --git a/lib/tests/modules/assertions/simple.nix b/lib/tests/modules/assertions/simple.nix
index a63b8090f91..115d89a3036 100644
--- a/lib/tests/modules/assertions/simple.nix
+++ b/lib/tests/modules/assertions/simple.nix
@@ -1,6 +1,6 @@
{
_module.checks.test = {
- enable = true;
+ check = false;
message = "Assertion failed";
};
}
diff --git a/lib/tests/modules/assertions/submodule-attrsOf-attrsOf.nix b/lib/tests/modules/assertions/submodule-attrsOf-attrsOf.nix
index a5f92aa93c7..27a63d1e432 100644
--- a/lib/tests/modules/assertions/submodule-attrsOf-attrsOf.nix
+++ b/lib/tests/modules/assertions/submodule-attrsOf-attrsOf.nix
@@ -4,7 +4,7 @@
default = { bar.baz = {}; };
type = lib.types.attrsOf (lib.types.attrsOf (lib.types.submodule {
_module.checks.test = {
- enable = true;
+ check = false;
message = "Assertion failed";
};
}));
diff --git a/lib/tests/modules/assertions/submodule-attrsOf.nix b/lib/tests/modules/assertions/submodule-attrsOf.nix
index 450cad0804d..aac5937cf7e 100644
--- a/lib/tests/modules/assertions/submodule-attrsOf.nix
+++ b/lib/tests/modules/assertions/submodule-attrsOf.nix
@@ -4,7 +4,7 @@
default = { bar = {}; };
type = lib.types.attrsOf (lib.types.submodule {
_module.checks.test = {
- enable = true;
+ check = false;
message = "Assertion failed";
};
});
diff --git a/lib/tests/modules/assertions/submodule.nix b/lib/tests/modules/assertions/submodule.nix
index a46734a326b..4e7e0b1bd61 100644
--- a/lib/tests/modules/assertions/submodule.nix
+++ b/lib/tests/modules/assertions/submodule.nix
@@ -4,7 +4,7 @@
default = {};
type = lib.types.submodule {
_module.checks.test = {
- enable = true;
+ check = false;
message = "Assertion failed";
};
};
diff --git a/lib/tests/modules/assertions/underscore-attributes.nix b/lib/tests/modules/assertions/underscore-attributes.nix
index c28c9dcd918..f9ee5c5787b 100644
--- a/lib/tests/modules/assertions/underscore-attributes.nix
+++ b/lib/tests/modules/assertions/underscore-attributes.nix
@@ -1,7 +1,7 @@
{
_module.checks._test = {
- enable = true;
+ check = false;
message = "Assertion failed";
};
diff --git a/lib/tests/modules/assertions/warning.nix b/lib/tests/modules/assertions/warning.nix
index 8fed9871aa2..72598ba3fdd 100644
--- a/lib/tests/modules/assertions/warning.nix
+++ b/lib/tests/modules/assertions/warning.nix
@@ -1,7 +1,7 @@
{
_module.checks.test = {
- enable = true;
+ check = false;
type = "warning";
message = "Warning message";
};
diff --git a/nixos/doc/manual/development/assertions.xml b/nixos/doc/manual/development/assertions.xml
index a873345ef43..31d09f958af 100644
--- a/nixos/doc/manual/development/assertions.xml
+++ b/nixos/doc/manual/development/assertions.xml
@@ -25,28 +25,26 @@
Checks can be defined using the option.
- Each check needs an attribute name, under which you have to define an enable
- condition using and a
- message using . Note that
- the enable condition is inverse of what an assertion
- would be: To assert a value being true, the enable condition should be false
- in that case, so that it isn't triggered. For the check message, you can add
+ Each check needs an attribute name, under which you can define a trigger
+ assertion using and a
+ message using .
+ For the message, you can add
options to the module arguments and use
${options.path.to.option} to print a context-aware string
- representation of the option path. Here is an example showing how this can be
+ representation of an option path. Here is an example showing how this can be
done.
{ config, options, ... }: {
_module.checks.gpgSshAgent = {
- enable = config.programs.gnupg.agent.enableSSHSupport && config.programs.ssh.startAgent;
- message = "You can't enable both ${options.programs.ssh.startAgent}"
- + " and ${options.programs.gnupg.agent.enableSSHSupport}!";
+ 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 = {
- enable = config.services.grafana.database.password != "";
+ 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
@@ -74,8 +72,8 @@
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] You can't enable both programs.ssh.startAgent and
- programs.gnupg.agent.enableSSHSupport!
+- [gpgSshAgent] If you have programs.gnupg.agent.enableSSHSupport
+ enabled, you can't enable programs.ssh.startAgent as well!
@@ -87,12 +85,12 @@ error: Failed checks:
-{ 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 = lib.mkForce false;
+ _module.checks.grafanaPassword.enable = false;
}
@@ -113,7 +111,7 @@ error: Failed checks:
options.port = lib.mkOption {};
config._module.checks.portConflict = {
- enable = config.port == 80;
+ check = config.port != 80;
message = "Port ${toString config.port} defined using"
+ " ${options.port} is usually used for HTTP";
type = "warning";
@@ -143,8 +141,8 @@ trace: warning: [myServices.foo/portConflict] Port 80 defined using
-{ lib, ... }: {
- myServices.foo._module.checks.portConflict.enable = lib.mkForce false;
+{
+ myServices.foo._module.checks.portConflict.enable = false;
}
diff --git a/nixos/modules/misc/assertions.nix b/nixos/modules/misc/assertions.nix
index 6a26a2332f2..d7cdb32491d 100644
--- a/nixos/modules/misc/assertions.nix
+++ b/nixos/modules/misc/assertions.nix
@@ -36,7 +36,7 @@ with lib;
name = "_${toString n}";
isWarning = lib.isString value;
result = {
- enable = if isWarning then true else ! value.assertion;
+ check = if isWarning then false else value.assertion;
type = if isWarning then "warning" else "error";
message = if isWarning then value else value.message;
};