at 22.05-pre 11 kB view raw
1{ config, lib, pkgs, modules, baseModules, specialArgs, ... }: 2 3with lib; 4 5let 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 = mapAttrs (childName: childConfig: 15 (import ../../../lib/eval-config.nix { 16 inherit lib baseModules specialArgs; 17 system = config.nixpkgs.initialSystem; 18 modules = 19 (optionals childConfig.inheritParentConfig modules) 20 ++ [ ./no-clone.nix ] 21 ++ [ childConfig.configuration ]; 22 }).config.system.build.toplevel 23 ) config.specialisation; 24 25 systemBuilder = 26 let 27 kernelPath = "${config.boot.kernelPackages.kernel}/" + 28 "${config.system.boot.loader.kernelFile}"; 29 initrdPath = "${config.system.build.initialRamdisk}/" + 30 "${config.system.boot.loader.initrdFile}"; 31 in '' 32 mkdir $out 33 34 # Containers don't have their own kernel or initrd. They boot 35 # directly into stage 2. 36 ${optionalString (!config.boot.isContainer) '' 37 if [ ! -f ${kernelPath} ]; then 38 echo "The bootloader cannot find the proper kernel image." 39 echo "(Expecting ${kernelPath})" 40 false 41 fi 42 43 ln -s ${kernelPath} $out/kernel 44 ln -s ${config.system.modulesTree} $out/kernel-modules 45 ${optionalString (config.hardware.deviceTree.package != null) '' 46 ln -s ${config.hardware.deviceTree.package} $out/dtbs 47 ''} 48 49 echo -n "$kernelParams" > $out/kernel-params 50 51 ln -s ${initrdPath} $out/initrd 52 53 ln -s ${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets $out 54 55 ln -s ${config.hardware.firmware}/lib/firmware $out/firmware 56 ''} 57 58 echo "$activationScript" > $out/activate 59 echo "$dryActivationScript" > $out/dry-activate 60 substituteInPlace $out/activate --subst-var out 61 substituteInPlace $out/dry-activate --subst-var out 62 chmod u+x $out/activate $out/dry-activate 63 unset activationScript dryActivationScript 64 ${pkgs.stdenv.shell} -n $out/activate 65 ${pkgs.stdenv.shell} -n $out/dry-activate 66 67 cp ${config.system.build.bootStage2} $out/init 68 substituteInPlace $out/init --subst-var-by systemConfig $out 69 70 ln -s ${config.system.build.etc}/etc $out/etc 71 ln -s ${config.system.path} $out/sw 72 ln -s "$systemd" $out/systemd 73 74 echo -n "$configurationName" > $out/configuration-name 75 echo -n "systemd ${toString config.systemd.package.interfaceVersion}" > $out/init-interface-version 76 echo -n "$nixosLabel" > $out/nixos-version 77 echo -n "${config.boot.kernelPackages.stdenv.hostPlatform.system}" > $out/system 78 79 mkdir $out/specialisation 80 ${concatStringsSep "\n" 81 (mapAttrsToList (name: path: "ln -s ${path} $out/specialisation/${name}") children)} 82 83 mkdir $out/bin 84 export localeArchive="${config.i18n.glibcLocales}/lib/locale/locale-archive" 85 substituteAll ${./switch-to-configuration.pl} $out/bin/switch-to-configuration 86 chmod +x $out/bin/switch-to-configuration 87 ${optionalString (pkgs.stdenv.hostPlatform == pkgs.stdenv.buildPlatform) '' 88 if ! output=$($perl/bin/perl -c $out/bin/switch-to-configuration 2>&1); then 89 echo "switch-to-configuration syntax is not valid:" 90 echo "$output" 91 exit 1 92 fi 93 ''} 94 95 echo -n "${toString config.system.extraDependencies}" > $out/extra-dependencies 96 97 ${config.system.extraSystemBuilderCmds} 98 ''; 99 100 # Putting it all together. This builds a store path containing 101 # symlinks to the various parts of the built configuration (the 102 # kernel, systemd units, init scripts, etc.) as well as a script 103 # `switch-to-configuration' that activates the configuration and 104 # makes it bootable. 105 baseSystem = pkgs.stdenvNoCC.mkDerivation { 106 name = "nixos-system-${config.system.name}-${config.system.nixos.label}"; 107 preferLocalBuild = true; 108 allowSubstitutes = false; 109 buildCommand = systemBuilder; 110 111 inherit (pkgs) coreutils; 112 systemd = config.systemd.package; 113 shell = "${pkgs.bash}/bin/sh"; 114 su = "${pkgs.shadow.su}/bin/su"; 115 utillinux = pkgs.util-linux; 116 117 kernelParams = config.boot.kernelParams; 118 installBootLoader = 119 config.system.build.installBootLoader 120 or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true"; 121 activationScript = config.system.activationScripts.script; 122 dryActivationScript = config.system.dryActivationScript; 123 nixosLabel = config.system.nixos.label; 124 125 configurationName = config.boot.loader.grub.configurationName; 126 127 # Needed by switch-to-configuration. 128 perl = pkgs.perl.withPackages (p: with p; [ FileSlurp NetDBus XMLParser XMLTwig ]); 129 }; 130 131 # Handle assertions and warnings 132 133 failedAssertions = map (x: x.message) (filter (x: !x.assertion) config.assertions); 134 135 baseSystemAssertWarn = if failedAssertions != [] 136 then throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failedAssertions)}" 137 else showWarnings config.warnings baseSystem; 138 139 # Replace runtime dependencies 140 system = foldr ({ oldDependency, newDependency }: drv: 141 pkgs.replaceDependency { inherit oldDependency newDependency drv; } 142 ) baseSystemAssertWarn config.system.replaceRuntimeDependencies; 143 144in 145 146{ 147 imports = [ 148 (mkRemovedOptionModule [ "nesting" "clone" ] "Use `specialisation.«name» = { inheritParentConfig = true; configuration = { ... }; }` instead.") 149 (mkRemovedOptionModule [ "nesting" "children" ] "Use `specialisation.«name».configuration = { ... }` instead.") 150 ]; 151 152 options = { 153 154 system.build = mkOption { 155 internal = true; 156 default = {}; 157 type = types.attrs; 158 description = '' 159 Attribute set of derivations used to setup the system. 160 ''; 161 }; 162 163 specialisation = mkOption { 164 default = {}; 165 example = lib.literalExpression "{ fewJobsManyCores.configuration = { nix.buildCores = 0; nix.maxJobs = 1; }; }"; 166 description = '' 167 Additional configurations to build. If 168 <literal>inheritParentConfig</literal> is true, the system 169 will be based on the overall system configuration. 170 171 To switch to a specialised configuration 172 (e.g. <literal>fewJobsManyCores</literal>) at runtime, run: 173 174 <screen> 175 <prompt># </prompt>sudo /run/current-system/specialisation/fewJobsManyCores/bin/switch-to-configuration test 176 </screen> 177 ''; 178 type = types.attrsOf (types.submodule ( 179 { ... }: { 180 options.inheritParentConfig = mkOption { 181 type = types.bool; 182 default = true; 183 description = "Include the entire system's configuration. Set to false to make a completely differently configured system."; 184 }; 185 186 options.configuration = mkOption { 187 default = {}; 188 description = "Arbitrary NixOS configuration options."; 189 }; 190 }) 191 ); 192 }; 193 194 system.boot.loader.id = mkOption { 195 internal = true; 196 default = ""; 197 description = '' 198 Id string of the used bootloader. 199 ''; 200 }; 201 202 system.boot.loader.kernelFile = mkOption { 203 internal = true; 204 default = pkgs.stdenv.hostPlatform.linux-kernel.target; 205 type = types.str; 206 description = '' 207 Name of the kernel file to be passed to the bootloader. 208 ''; 209 }; 210 211 system.boot.loader.initrdFile = mkOption { 212 internal = true; 213 default = "initrd"; 214 type = types.str; 215 description = '' 216 Name of the initrd file to be passed to the bootloader. 217 ''; 218 }; 219 220 system.copySystemConfiguration = mkOption { 221 type = types.bool; 222 default = false; 223 description = '' 224 If enabled, copies the NixOS configuration file 225 (usually <filename>/etc/nixos/configuration.nix</filename>) 226 and links it from the resulting system 227 (getting to <filename>/run/current-system/configuration.nix</filename>). 228 Note that only this single file is copied, even if it imports others. 229 ''; 230 }; 231 232 system.extraSystemBuilderCmds = mkOption { 233 type = types.lines; 234 internal = true; 235 default = ""; 236 description = '' 237 This code will be added to the builder creating the system store path. 238 ''; 239 }; 240 241 system.extraDependencies = mkOption { 242 type = types.listOf types.package; 243 default = []; 244 description = '' 245 A list of packages that should be included in the system 246 closure but not otherwise made available to users. This is 247 primarily used by the installation tests. 248 ''; 249 }; 250 251 system.replaceRuntimeDependencies = mkOption { 252 default = []; 253 example = lib.literalExpression "[ ({ original = pkgs.openssl; replacement = pkgs.callPackage /path/to/openssl { }; }) ]"; 254 type = types.listOf (types.submodule ( 255 { ... }: { 256 options.original = mkOption { 257 type = types.package; 258 description = "The original package to override."; 259 }; 260 261 options.replacement = mkOption { 262 type = types.package; 263 description = "The replacement package."; 264 }; 265 }) 266 ); 267 apply = map ({ original, replacement, ... }: { 268 oldDependency = original; 269 newDependency = replacement; 270 }); 271 description = '' 272 List of packages to override without doing a full rebuild. 273 The original derivation and replacement derivation must have the same 274 name length, and ideally should have close-to-identical directory layout. 275 ''; 276 }; 277 278 system.name = mkOption { 279 type = types.str; 280 default = 281 if config.networking.hostName == "" 282 then "unnamed" 283 else config.networking.hostName; 284 defaultText = literalExpression '' 285 if config.networking.hostName == "" 286 then "unnamed" 287 else config.networking.hostName; 288 ''; 289 description = '' 290 The name of the system used in the <option>system.build.toplevel</option> derivation. 291 </para><para> 292 That derivation has the following name: 293 <literal>"nixos-system-''${config.system.name}-''${config.system.nixos.label}"</literal> 294 ''; 295 }; 296 297 }; 298 299 300 config = { 301 302 system.extraSystemBuilderCmds = 303 optionalString 304 config.system.copySystemConfiguration 305 ''ln -s '${import ../../../lib/from-env.nix "NIXOS_CONFIG" <nixos-config>}' \ 306 "$out/configuration.nix" 307 ''; 308 309 system.build.toplevel = system; 310 311 }; 312 313}