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