···1+{ config, lib, pkgs, extendModules, noUserModules, ... }:
2+3+let
4+ inherit (lib)
5+ concatStringsSep
6+ mapAttrs
7+ mapAttrsToList
8+ mkOption
9+ types
10+ ;
11+12+ # This attribute is responsible for creating boot entries for
13+ # child configuration. They are only (directly) accessible
14+ # when the parent configuration is boot default. For example,
15+ # you can provide an easy way to boot the same configuration
16+ # as you use, but with another kernel
17+ # !!! fix this
18+ children =
19+ mapAttrs
20+ (childName: childConfig: childConfig.configuration.system.build.toplevel)
21+ config.specialisation;
22+23+in
24+{
25+ options = {
26+27+ specialisation = mkOption {
28+ default = { };
29+ example = lib.literalExpression "{ fewJobsManyCores.configuration = { nix.settings = { core = 0; max-jobs = 1; }; }; }";
30+ description = lib.mdDoc ''
31+ Additional configurations to build. If
32+ `inheritParentConfig` is true, the system
33+ will be based on the overall system configuration.
34+35+ To switch to a specialised configuration
36+ (e.g. `fewJobsManyCores`) at runtime, run:
37+38+ ```
39+ sudo /run/current-system/specialisation/fewJobsManyCores/bin/switch-to-configuration test
40+ ```
41+ '';
42+ type = types.attrsOf (types.submodule (
43+ local@{ ... }:
44+ let
45+ extend =
46+ if local.config.inheritParentConfig
47+ then extendModules
48+ else noUserModules.extendModules;
49+ in
50+ {
51+ options.inheritParentConfig = mkOption {
52+ type = types.bool;
53+ default = true;
54+ description = lib.mdDoc "Include the entire system's configuration. Set to false to make a completely differently configured system.";
55+ };
56+57+ options.configuration = mkOption {
58+ default = { };
59+ description = lib.mdDoc ''
60+ Arbitrary NixOS configuration.
61+62+ Anything you can add to a normal NixOS configuration, you can add
63+ here, including imports and config values, although nested
64+ specialisations will be ignored.
65+ '';
66+ visible = "shallow";
67+ inherit (extend { modules = [ ./no-clone.nix ]; }) type;
68+ };
69+ }
70+ ));
71+ };
72+73+ };
74+75+ config = {
76+ system.systemBuilderCommands = ''
77+ mkdir $out/specialisation
78+ ${concatStringsSep "\n"
79+ (mapAttrsToList (name: path: "ln -s ${path} $out/specialisation/${name}") children)}
80+ '';
81+ };
82+83+ # uses extendModules to generate a type
84+ meta.buildDocsInSandbox = false;
85+}
+24-79
nixos/modules/system/activation/top-level.nix
···1-{ config, lib, pkgs, extendModules, noUserModules, ... }:
23with lib;
45let
6-7-8- # This attribute is responsible for creating boot entries for
9- # child configuration. They are only (directly) accessible
10- # when the parent configuration is boot default. For example,
11- # you can provide an easy way to boot the same configuration
12- # as you use, but with another kernel
13- # !!! fix this
14- children =
15- mapAttrs
16- (childName: childConfig: childConfig.configuration.system.build.toplevel)
17- config.specialisation;
18-19 systemBuilder =
20 let
21 kernelPath = "${config.boot.kernelPackages.kernel}/" +
···72 ln -s ${config.system.path} $out/sw
73 ln -s "$systemd" $out/systemd
7475- echo -n "$configurationName" > $out/configuration-name
76 echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version
77 echo -n "$nixosLabel" > $out/nixos-version
78 echo -n "${config.boot.kernelPackages.stdenv.hostPlatform.system}" > $out/system
79-80- mkdir $out/specialisation
81- ${concatStringsSep "\n"
82- (mapAttrsToList (name: path: "ln -s ${path} $out/specialisation/${name}") children)}
8384 mkdir $out/bin
85 export localeArchive="${config.i18n.glibcLocales}/lib/locale/locale-archive"
···93 fi
94 ''}
950096 echo -n "${toString config.system.extraDependencies}" > $out/extra-dependencies
9798 ${config.system.extraSystemBuilderCmds}
···103 # kernel, systemd units, init scripts, etc.) as well as a script
104 # `switch-to-configuration' that activates the configuration and
105 # makes it bootable.
106- baseSystem = pkgs.stdenvNoCC.mkDerivation {
107 name = "nixos-system-${config.system.name}-${config.system.nixos.label}";
108 preferLocalBuild = true;
109 allowSubstitutes = false;
···120 activationScript = config.system.activationScripts.script;
121 dryActivationScript = config.system.dryActivationScript;
122 nixosLabel = config.system.nixos.label;
123-124- configurationName = config.boot.loader.grub.configurationName;
125126 # Needed by switch-to-configuration.
127 perl = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]);
128- };
129130 # Handle assertions and warnings
131···140 pkgs.replaceDependency { inherit oldDependency newDependency drv; }
141 ) baseSystemAssertWarn config.system.replaceRuntimeDependencies;
142143- /* Workaround until https://github.com/NixOS/nixpkgs/pull/156533
144- Call can be replaced by argument when that's merged.
145- */
146- tmpFixupSubmoduleBoundary = subopts:
147- lib.mkOption {
148- type = lib.types.submoduleWith {
149- modules = [ { options = subopts; } ];
150- };
151- };
152-153in
154155{
···161162 options = {
163164- specialisation = mkOption {
165- default = {};
166- example = lib.literalExpression "{ fewJobsManyCores.configuration = { nix.settings = { core = 0; max-jobs = 1; }; }; }";
167- description = lib.mdDoc ''
168- Additional configurations to build. If
169- `inheritParentConfig` is true, the system
170- will be based on the overall system configuration.
171-172- To switch to a specialised configuration
173- (e.g. `fewJobsManyCores`) at runtime, run:
174-175- ```
176- sudo /run/current-system/specialisation/fewJobsManyCores/bin/switch-to-configuration test
177- ```
178- '';
179- type = types.attrsOf (types.submodule (
180- local@{ ... }: let
181- extend = if local.config.inheritParentConfig
182- then extendModules
183- else noUserModules.extendModules;
184- in {
185- options.inheritParentConfig = mkOption {
186- type = types.bool;
187- default = true;
188- description = lib.mdDoc "Include the entire system's configuration. Set to false to make a completely differently configured system.";
189- };
190-191- options.configuration = mkOption {
192- default = {};
193- description = lib.mdDoc ''
194- Arbitrary NixOS configuration.
195-196- Anything you can add to a normal NixOS configuration, you can add
197- here, including imports and config values, although nested
198- specialisations will be ignored.
199- '';
200- visible = "shallow";
201- inherit (extend { modules = [ ./no-clone.nix ]; }) type;
202- };
203- })
204- );
205- };
206-207 system.boot.loader.id = mkOption {
208 internal = true;
209 default = "";
···231 '';
232 };
233234- system.build = tmpFixupSubmoduleBoundary {
235 installBootLoader = mkOption {
236 internal = true;
237 # "; true" => make the `$out` argument from switch-to-configuration.pl
···276 '';
277 };
278000000000000000000279 system.extraSystemBuilderCmds = mkOption {
280 type = types.lines;
281 internal = true;
···357358 };
359360- # uses extendModules to generate a type
361- meta.buildDocsInSandbox = false;
362}
···1+{ config, lib, pkgs, ... }:
23with lib;
45let
00000000000006 systemBuilder =
7 let
8 kernelPath = "${config.boot.kernelPackages.kernel}/" +
···59 ln -s ${config.system.path} $out/sw
60 ln -s "$systemd" $out/systemd
61062 echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version
63 echo -n "$nixosLabel" > $out/nixos-version
64 echo -n "${config.boot.kernelPackages.stdenv.hostPlatform.system}" > $out/system
00006566 mkdir $out/bin
67 export localeArchive="${config.i18n.glibcLocales}/lib/locale/locale-archive"
···75 fi
76 ''}
7778+ ${config.system.systemBuilderCommands}
79+80 echo -n "${toString config.system.extraDependencies}" > $out/extra-dependencies
8182 ${config.system.extraSystemBuilderCmds}
···87 # kernel, systemd units, init scripts, etc.) as well as a script
88 # `switch-to-configuration' that activates the configuration and
89 # makes it bootable.
90+ baseSystem = pkgs.stdenvNoCC.mkDerivation ({
91 name = "nixos-system-${config.system.name}-${config.system.nixos.label}";
92 preferLocalBuild = true;
93 allowSubstitutes = false;
···104 activationScript = config.system.activationScripts.script;
105 dryActivationScript = config.system.dryActivationScript;
106 nixosLabel = config.system.nixos.label;
00107108 # Needed by switch-to-configuration.
109 perl = pkgs.perl.withPackages (p: with p; [ ConfigIniFiles FileSlurp ]);
110+ } // config.system.systemBuilderArgs);
111112 # Handle assertions and warnings
113···122 pkgs.replaceDependency { inherit oldDependency newDependency drv; }
123 ) baseSystemAssertWarn config.system.replaceRuntimeDependencies;
1240000000000125in
126127{
···133134 options = {
1350000000000000000000000000000000000000000000136 system.boot.loader.id = mkOption {
137 internal = true;
138 default = "";
···160 '';
161 };
162163+ system.build = {
164 installBootLoader = mkOption {
165 internal = true;
166 # "; true" => make the `$out` argument from switch-to-configuration.pl
···205 '';
206 };
207208+ system.systemBuilderCommands = mkOption {
209+ type = types.lines;
210+ internal = true;
211+ default = "";
212+ description = ''
213+ This code will be added to the builder creating the system store path.
214+ '';
215+ };
216+217+ system.systemBuilderArgs = mkOption {
218+ type = types.attrsOf types.unspecified;
219+ internal = true;
220+ default = {};
221+ description = lib.mdDoc ''
222+ `lib.mkDerivation` attributes that will be passed to the top level system builder.
223+ '';
224+ };
225+226 system.extraSystemBuilderCmds = mkOption {
227 type = types.lines;
228 internal = true;
···304305 };
30600307}