at 23.05-pre 4.7 kB view raw
1# This module creates netboot media containing the given NixOS 2# configuration. 3 4{ config, lib, pkgs, ... }: 5 6with lib; 7 8{ 9 options = { 10 11 netboot.storeContents = mkOption { 12 example = literalExpression "[ pkgs.stdenv ]"; 13 description = lib.mdDoc '' 14 This option lists additional derivations to be included in the 15 Nix store in the generated netboot image. 16 ''; 17 }; 18 19 }; 20 21 config = { 22 # Don't build the GRUB menu builder script, since we don't need it 23 # here and it causes a cyclic dependency. 24 boot.loader.grub.enable = false; 25 26 # !!! Hack - attributes expected by other modules. 27 environment.systemPackages = [ pkgs.grub2_efi ] 28 ++ (if pkgs.stdenv.hostPlatform.system == "aarch64-linux" 29 then [] 30 else [ pkgs.grub2 pkgs.syslinux ]); 31 32 fileSystems."/" = mkImageMediaOverride 33 { fsType = "tmpfs"; 34 options = [ "mode=0755" ]; 35 }; 36 37 # In stage 1, mount a tmpfs on top of /nix/store (the squashfs 38 # image) to make this a live CD. 39 fileSystems."/nix/.ro-store" = mkImageMediaOverride 40 { fsType = "squashfs"; 41 device = "../nix-store.squashfs"; 42 options = [ "loop" ]; 43 neededForBoot = true; 44 }; 45 46 fileSystems."/nix/.rw-store" = mkImageMediaOverride 47 { fsType = "tmpfs"; 48 options = [ "mode=0755" ]; 49 neededForBoot = true; 50 }; 51 52 fileSystems."/nix/store" = mkImageMediaOverride 53 { fsType = "overlay"; 54 device = "overlay"; 55 options = [ 56 "lowerdir=/nix/.ro-store" 57 "upperdir=/nix/.rw-store/store" 58 "workdir=/nix/.rw-store/work" 59 ]; 60 61 depends = [ 62 "/nix/.ro-store" 63 "/nix/.rw-store/store" 64 "/nix/.rw-store/work" 65 ]; 66 }; 67 68 boot.initrd.availableKernelModules = [ "squashfs" "overlay" ]; 69 70 boot.initrd.kernelModules = [ "loop" "overlay" ]; 71 72 # Closures to be copied to the Nix store, namely the init 73 # script and the top-level system configuration directory. 74 netboot.storeContents = 75 [ config.system.build.toplevel ]; 76 77 # Create the squashfs image that contains the Nix store. 78 system.build.squashfsStore = pkgs.callPackage ../../../lib/make-squashfs.nix { 79 storeContents = config.netboot.storeContents; 80 }; 81 82 83 # Create the initrd 84 system.build.netbootRamdisk = pkgs.makeInitrdNG { 85 inherit (config.boot.initrd) compressor; 86 prepend = [ "${config.system.build.initialRamdisk}/initrd" ]; 87 88 contents = 89 [ { object = config.system.build.squashfsStore; 90 symlink = "/nix-store.squashfs"; 91 } 92 ]; 93 }; 94 95 system.build.netbootIpxeScript = pkgs.writeTextDir "netboot.ipxe" '' 96 #!ipxe 97 # Use the cmdline variable to allow the user to specify custom kernel params 98 # when chainloading this script from other iPXE scripts like netboot.xyz 99 kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ${toString config.boot.kernelParams} ''${cmdline} 100 initrd initrd 101 boot 102 ''; 103 104 # A script invoking kexec on ./bzImage and ./initrd.gz. 105 # Usually used through system.build.kexecTree, but exposed here for composability. 106 system.build.kexecScript = pkgs.writeScript "kexec-boot" '' 107 #!/usr/bin/env bash 108 if ! kexec -v >/dev/null 2>&1; then 109 echo "kexec not found: please install kexec-tools" 2>&1 110 exit 1 111 fi 112 SCRIPT_DIR=$( cd -- "$( dirname -- "''${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 113 kexec --load ''${SCRIPT_DIR}/bzImage \ 114 --initrd=''${SCRIPT_DIR}/initrd.gz \ 115 --command-line "init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}" 116 kexec -e 117 ''; 118 119 # A tree containing initrd.gz, bzImage and a kexec-boot script. 120 system.build.kexecTree = pkgs.linkFarm "kexec-tree" [ 121 { 122 name = "initrd.gz"; 123 path = "${config.system.build.netbootRamdisk}/initrd"; 124 } 125 { 126 name = "bzImage"; 127 path = "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}"; 128 } 129 { 130 name = "kexec-boot"; 131 path = config.system.build.kexecScript; 132 } 133 ]; 134 135 boot.loader.timeout = 10; 136 137 boot.postBootCommands = 138 '' 139 # After booting, register the contents of the Nix store 140 # in the Nix database in the tmpfs. 141 ${config.nix.package}/bin/nix-store --load-db < /nix/store/nix-path-registration 142 143 # nixos-rebuild also requires a "system" profile and an 144 # /etc/NIXOS tag. 145 touch /etc/NIXOS 146 ${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system 147 ''; 148 149 }; 150 151}