at 18.09-beta 8.9 kB view raw
1{ config, lib, pkgs, modules, baseModules, ... }: 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 cloner = inheritParent: list: 15 map (childConfig: 16 (import ../../../lib/eval-config.nix { 17 inherit baseModules; 18 modules = 19 (optionals inheritParent modules) 20 ++ [ ./no-clone.nix ] 21 ++ [ childConfig ]; 22 }).config.system.build.toplevel 23 ) list; 24 25 children = 26 cloner false config.nesting.children 27 ++ cloner true config.nesting.clone; 28 29 systemBuilder = 30 let 31 kernelPath = "${config.boot.kernelPackages.kernel}/" + 32 "${config.system.boot.loader.kernelFile}"; 33 initrdPath = "${config.system.build.initialRamdisk}/" + 34 "${config.system.boot.loader.initrdFile}"; 35 in '' 36 mkdir $out 37 38 # Containers don't have their own kernel or initrd. They boot 39 # directly into stage 2. 40 ${optionalString (!config.boot.isContainer) '' 41 if [ ! -f ${kernelPath} ]; then 42 echo "The bootloader cannot find the proper kernel image." 43 echo "(Expecting ${kernelPath})" 44 false 45 fi 46 47 ln -s ${kernelPath} $out/kernel 48 ln -s ${config.system.modulesTree} $out/kernel-modules 49 ${optionalString (pkgs.stdenv.hostPlatform.platform.kernelDTB or false) '' 50 ln -s ${config.boot.kernelPackages.kernel}/dtbs $out/dtbs 51 ''} 52 53 echo -n "$kernelParams" > $out/kernel-params 54 55 ln -s ${initrdPath} $out/initrd 56 57 ln -s ${config.system.build.initialRamdiskSecretAppender}/bin/append-initrd-secrets $out 58 59 ln -s ${config.hardware.firmware}/lib/firmware $out/firmware 60 ''} 61 62 echo "$activationScript" > $out/activate 63 substituteInPlace $out/activate --subst-var out 64 chmod u+x $out/activate 65 unset activationScript 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 "${pkgs.stdenv.hostPlatform.system}" > $out/system 78 79 mkdir $out/fine-tune 80 childCount=0 81 for i in $children; do 82 childCount=$(( childCount + 1 )) 83 ln -s $i $out/fine-tune/child-$childCount 84 done 85 86 mkdir $out/bin 87 export localeArchive="${config.i18n.glibcLocales}/lib/locale/locale-archive" 88 substituteAll ${./switch-to-configuration.pl} $out/bin/switch-to-configuration 89 chmod +x $out/bin/switch-to-configuration 90 91 echo -n "${toString config.system.extraDependencies}" > $out/extra-dependencies 92 93 ${config.system.extraSystemBuilderCmds} 94 ''; 95 96 # Handle assertions 97 98 failed = map (x: x.message) (filter (x: !x.assertion) config.assertions); 99 100 showWarnings = res: fold (w: x: builtins.trace "warning: ${w}" x) res config.warnings; 101 102 # Putting it all together. This builds a store path containing 103 # symlinks to the various parts of the built configuration (the 104 # kernel, systemd units, init scripts, etc.) as well as a script 105 # `switch-to-configuration' that activates the configuration and 106 # makes it bootable. 107 baseSystem = showWarnings ( 108 if [] == failed then pkgs.stdenvNoCC.mkDerivation { 109 name = let hn = config.networking.hostName; 110 nn = if (hn != "") then hn else "unnamed"; 111 in "nixos-system-${nn}-${config.system.nixos.label}"; 112 preferLocalBuild = true; 113 allowSubstitutes = false; 114 buildCommand = systemBuilder; 115 116 inherit (pkgs) utillinux coreutils; 117 systemd = config.systemd.package; 118 119 inherit children; 120 kernelParams = config.boot.kernelParams; 121 installBootLoader = 122 config.system.build.installBootLoader 123 or "echo 'Warning: do not know how to make this configuration bootable; please enable a boot loader.' 1>&2; true"; 124 activationScript = config.system.activationScripts.script; 125 nixosLabel = config.system.nixos.label; 126 127 configurationName = config.boot.loader.grub.configurationName; 128 129 # Needed by switch-to-configuration. 130 131 perl = "${pkgs.perl}/bin/perl " + (concatMapStringsSep " " (lib: "-I${lib}/${pkgs.perl.libPrefix}") (with pkgs.perlPackages; [ FileSlurp NetDBus XMLParser XMLTwig ])); 132 } else throw "\nFailed assertions:\n${concatStringsSep "\n" (map (x: "- ${x}") failed)}"); 133 134 # Replace runtime dependencies 135 system = fold ({ oldDependency, newDependency }: drv: 136 pkgs.replaceDependency { inherit oldDependency newDependency drv; } 137 ) baseSystem config.system.replaceRuntimeDependencies; 138 139in 140 141{ 142 options = { 143 144 system.build = mkOption { 145 internal = true; 146 default = {}; 147 type = types.attrs; 148 description = '' 149 Attribute set of derivations used to setup the system. 150 ''; 151 }; 152 153 nesting.children = mkOption { 154 default = []; 155 description = '' 156 Additional configurations to build. 157 ''; 158 }; 159 160 nesting.clone = mkOption { 161 default = []; 162 description = '' 163 Additional configurations to build based on the current 164 configuration which then has a lower priority. 165 166 To switch to a cloned configuration (e.g. <literal>child-1</literal>) 167 at runtime, run 168 169 <programlisting> 170 # sudo /run/current-system/fine-tune/child-1/bin/switch-to-configuration test 171 </programlisting> 172 ''; 173 }; 174 175 system.boot.loader.id = mkOption { 176 internal = true; 177 default = ""; 178 description = '' 179 Id string of the used bootloader. 180 ''; 181 }; 182 183 system.boot.loader.kernelFile = mkOption { 184 internal = true; 185 default = pkgs.stdenv.hostPlatform.platform.kernelTarget; 186 type = types.str; 187 description = '' 188 Name of the kernel file to be passed to the bootloader. 189 ''; 190 }; 191 192 system.boot.loader.initrdFile = mkOption { 193 internal = true; 194 default = "initrd"; 195 type = types.str; 196 description = '' 197 Name of the initrd file to be passed to the bootloader. 198 ''; 199 }; 200 201 system.copySystemConfiguration = mkOption { 202 type = types.bool; 203 default = false; 204 description = '' 205 If enabled, copies the NixOS configuration file 206 (usually <filename>/etc/nixos/configuration.nix</filename>) 207 and links it from the resulting system 208 (getting to <filename>/run/current-system/configuration.nix</filename>). 209 Note that only this single file is copied, even if it imports others. 210 ''; 211 }; 212 213 system.extraSystemBuilderCmds = mkOption { 214 type = types.lines; 215 internal = true; 216 default = ""; 217 description = '' 218 This code will be added to the builder creating the system store path. 219 ''; 220 }; 221 222 system.extraDependencies = mkOption { 223 type = types.listOf types.package; 224 default = []; 225 description = '' 226 A list of packages that should be included in the system 227 closure but not otherwise made available to users. This is 228 primarily used by the installation tests. 229 ''; 230 }; 231 232 system.replaceRuntimeDependencies = mkOption { 233 default = []; 234 example = lib.literalExample "[ ({ original = pkgs.openssl; replacement = pkgs.callPackage /path/to/openssl { }; }) ]"; 235 type = types.listOf (types.submodule ( 236 { ... }: { 237 options.original = mkOption { 238 type = types.package; 239 description = "The original package to override."; 240 }; 241 242 options.replacement = mkOption { 243 type = types.package; 244 description = "The replacement package."; 245 }; 246 }) 247 ); 248 apply = map ({ original, replacement, ... }: { 249 oldDependency = original; 250 newDependency = replacement; 251 }); 252 description = '' 253 List of packages to override without doing a full rebuild. 254 The original derivation and replacement derivation must have the same 255 name length, and ideally should have close-to-identical directory layout. 256 ''; 257 }; 258 259 }; 260 261 262 config = { 263 264 system.extraSystemBuilderCmds = 265 optionalString 266 config.system.copySystemConfiguration 267 ''ln -s '${import ../../../lib/from-env.nix "NIXOS_CONFIG" <nixos-config>}' \ 268 "$out/configuration.nix" 269 ''; 270 271 system.build.toplevel = system; 272 273 }; 274 275}