1{ config, lib, options, pkgs, ... }:
2
3let
4 cfg = config.system.nixos;
5 opt = options.system.nixos;
6
7 inherit (lib)
8 concatStringsSep mapAttrsToList toLower
9 literalExpression mkRenamedOptionModule mkDefault mkOption trivial types;
10
11 needsEscaping = s: null != builtins.match "[a-zA-Z0-9]+" s;
12 escapeIfNecessary = s: if needsEscaping s then s else ''"${lib.escape [ "\$" "\"" "\\" "\`" ] s}"'';
13 attrsToText = attrs:
14 concatStringsSep "\n" (
15 mapAttrsToList (n: v: ''${n}=${escapeIfNecessary (toString v)}'') attrs
16 ) + "\n";
17
18 osReleaseContents = {
19 NAME = "${cfg.distroName}";
20 ID = "${cfg.distroId}";
21 VERSION = "${cfg.release} (${cfg.codeName})";
22 VERSION_CODENAME = toLower cfg.codeName;
23 VERSION_ID = cfg.release;
24 BUILD_ID = cfg.version;
25 PRETTY_NAME = "${cfg.distroName} ${cfg.release} (${cfg.codeName})";
26 LOGO = "nix-snowflake";
27 HOME_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/";
28 DOCUMENTATION_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/learn.html";
29 SUPPORT_URL = lib.optionalString (cfg.distroId == "nixos") "https://nixos.org/community.html";
30 BUG_REPORT_URL = lib.optionalString (cfg.distroId == "nixos") "https://github.com/NixOS/nixpkgs/issues";
31 } // lib.optionalAttrs (cfg.variant_id != null) {
32 VARIANT_ID = cfg.variant_id;
33 };
34
35 initrdReleaseContents = osReleaseContents // {
36 PRETTY_NAME = "${osReleaseContents.PRETTY_NAME} (Initrd)";
37 };
38 initrdRelease = pkgs.writeText "initrd-release" (attrsToText initrdReleaseContents);
39
40in
41{
42 imports = [
43 ./label.nix
44 (mkRenamedOptionModule [ "system" "nixosVersion" ] [ "system" "nixos" "version" ])
45 (mkRenamedOptionModule [ "system" "nixosVersionSuffix" ] [ "system" "nixos" "versionSuffix" ])
46 (mkRenamedOptionModule [ "system" "nixosRevision" ] [ "system" "nixos" "revision" ])
47 (mkRenamedOptionModule [ "system" "nixosLabel" ] [ "system" "nixos" "label" ])
48 ];
49
50 options.boot.initrd.osRelease = mkOption {
51 internal = true;
52 readOnly = true;
53 default = initrdRelease;
54 };
55
56 options.system = {
57
58 nixos.version = mkOption {
59 internal = true;
60 type = types.str;
61 description = lib.mdDoc "The full NixOS version (e.g. `16.03.1160.f2d4ee1`).";
62 };
63
64 nixos.release = mkOption {
65 readOnly = true;
66 type = types.str;
67 default = trivial.release;
68 description = lib.mdDoc "The NixOS release (e.g. `16.03`).";
69 };
70
71 nixos.versionSuffix = mkOption {
72 internal = true;
73 type = types.str;
74 default = trivial.versionSuffix;
75 description = lib.mdDoc "The NixOS version suffix (e.g. `1160.f2d4ee1`).";
76 };
77
78 nixos.revision = mkOption {
79 internal = true;
80 type = types.nullOr types.str;
81 default = trivial.revisionWithDefault null;
82 description = lib.mdDoc "The Git revision from which this NixOS configuration was built.";
83 };
84
85 nixos.codeName = mkOption {
86 readOnly = true;
87 type = types.str;
88 default = trivial.codeName;
89 description = lib.mdDoc "The NixOS release code name (e.g. `Emu`).";
90 };
91
92 nixos.distroId = mkOption {
93 internal = true;
94 type = types.str;
95 default = "nixos";
96 description = lib.mdDoc "The id of the operating system";
97 };
98
99 nixos.distroName = mkOption {
100 internal = true;
101 type = types.str;
102 default = "NixOS";
103 description = lib.mdDoc "The name of the operating system";
104 };
105
106 nixos.variant_id = mkOption {
107 type = types.nullOr (types.strMatching "^[a-z0-9._-]+$");
108 default = null;
109 description = lib.mdDoc "A lower-case string identifying a specific variant or edition of the operating system";
110 example = "installer";
111 };
112
113 stateVersion = mkOption {
114 type = types.str;
115 # TODO Remove this and drop the default of the option so people are forced to set it.
116 # Doing this also means fixing the comment in nixos/modules/testing/test-instrumentation.nix
117 apply = v:
118 lib.warnIf (options.system.stateVersion.highestPrio == (lib.mkOptionDefault { }).priority)
119 "system.stateVersion is not set, defaulting to ${v}. Read why this matters on https://nixos.org/manual/nixos/stable/options.html#opt-system.stateVersion."
120 v;
121 default = cfg.release;
122 defaultText = literalExpression "config.${opt.release}";
123 description = lib.mdDoc ''
124 Every once in a while, a new NixOS release may change
125 configuration defaults in a way incompatible with stateful
126 data. For instance, if the default version of PostgreSQL
127 changes, the new version will probably be unable to read your
128 existing databases. To prevent such breakage, you should set the
129 value of this option to the NixOS release with which you want
130 to be compatible. The effect is that NixOS will use
131 defaults corresponding to the specified release (such as using
132 an older version of PostgreSQL).
133 It’s perfectly fine and recommended to leave this value at the
134 release version of the first install of this system.
135 Changing this option will not upgrade your system. In fact it
136 is meant to stay constant exactly when you upgrade your system.
137 You should only bump this option, if you are sure that you can
138 or have migrated all state on your system which is affected
139 by this option.
140 '';
141 };
142
143 defaultChannel = mkOption {
144 internal = true;
145 type = types.str;
146 default = "https://nixos.org/channels/nixos-unstable";
147 description = lib.mdDoc "Default NixOS channel to which the root user is subscribed.";
148 };
149
150 configurationRevision = mkOption {
151 type = types.nullOr types.str;
152 default = null;
153 description = lib.mdDoc "The Git revision of the top-level flake from which this configuration was built.";
154 };
155
156 };
157
158 config = {
159
160 system.nixos = {
161 # These defaults are set here rather than up there so that
162 # changing them would not rebuild the manual
163 version = mkDefault (cfg.release + cfg.versionSuffix);
164 };
165
166 # Generate /etc/os-release. See
167 # https://www.freedesktop.org/software/systemd/man/os-release.html for the
168 # format.
169 environment.etc = {
170 "lsb-release".text = attrsToText {
171 LSB_VERSION = "${cfg.release} (${cfg.codeName})";
172 DISTRIB_ID = "${cfg.distroId}";
173 DISTRIB_RELEASE = cfg.release;
174 DISTRIB_CODENAME = toLower cfg.codeName;
175 DISTRIB_DESCRIPTION = "${cfg.distroName} ${cfg.release} (${cfg.codeName})";
176 };
177
178 "os-release".text = attrsToText osReleaseContents;
179 };
180
181 };
182
183 # uses version info nixpkgs, which requires a full nixpkgs path
184 meta.buildDocsInSandbox = false;
185}