diff --git a/lib/modules.nix b/lib/modules.nix
index d7037abfbef..50827e18f10 100644
--- a/lib/modules.nix
+++ b/lib/modules.nix
@@ -261,11 +261,16 @@ rec {
evalOptionValue = loc: opt: defs:
let
# Add in the default value for this option, if any.
- defs' = (optional (opt ? default)
- { file = head opt.declarations; value = mkOptionDefault opt.default; }) ++ defs;
+ defs' =
+ (optional (opt ? default)
+ { file = head opt.declarations; value = mkOptionDefault opt.default; }) ++ defs;
# Handle properties, check types, and merge everything together.
- res = mergeDefinitions loc opt.type defs';
+ res =
+ if opt.readOnly or false && length defs' > 1 then
+ throw "The option `${showOption loc}' is read-only, but it's set multiple times."
+ else
+ mergeDefinitions loc opt.type defs';
# Check whether the option is defined, and apply the ‘apply’
# function to the merged value. This allows options to yield a
diff --git a/lib/options.nix b/lib/options.nix
index 5c543f56bcf..444ec37e6ea 100644
--- a/lib/options.nix
+++ b/lib/options.nix
@@ -19,6 +19,7 @@ rec {
, apply ? null # Function that converts the option value to something else.
, internal ? null # Whether the option is for NixOS developers only.
, visible ? null # Whether the option shows up in the manual.
+ , readOnly ? null # Whether the option can be set only once
, options ? null # Obsolete, used by types.optionSet.
} @ attrs:
attrs // { _type = "option"; };
@@ -90,6 +91,7 @@ rec {
declarations = filter (x: x != unknownModule) opt.declarations;
internal = opt.internal or false;
visible = opt.visible or true;
+ readOnly = opt.readOnly or false;
type = opt.type.name or null;
}
// (if opt ? example then { example = scrubOptionValue opt.example; } else {})
diff --git a/nixos/doc/manual/options-to-docbook.xsl b/nixos/doc/manual/options-to-docbook.xsl
index f588a019e63..3d6ea942701 100644
--- a/nixos/doc/manual/options-to-docbook.xsl
+++ b/nixos/doc/manual/options-to-docbook.xsl
@@ -39,6 +39,10 @@
Type:
+
+
+ (read only)
+
diff --git a/nixos/modules/misc/version.nix b/nixos/modules/misc/version.nix
index 8a52df42dd8..dc8eb4e8832 100644
--- a/nixos/modules/misc/version.nix
+++ b/nixos/modules/misc/version.nix
@@ -29,7 +29,7 @@ with lib;
};
system.nixosRelease = mkOption {
- internal = true;
+ readOnly = true;
type = types.str;
default = readFile "${toString pkgs.path}/.version";
description = "NixOS release.";
@@ -48,7 +48,7 @@ with lib;
};
system.nixosCodeName = mkOption {
- internal = true;
+ readOnly = true;
type = types.str;
description = "NixOS release code name.";
};