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 = literalExample "[ pkgs.stdenv ]";
13 description = ''
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 = rec {
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.system == "aarch64-linux"
29 then []
30 else [ pkgs.grub2 pkgs.syslinux ]);
31 system.boot.loader.kernelFile = pkgs.stdenv.platform.kernelTarget;
32
33 fileSystems."/" =
34 { fsType = "tmpfs";
35 options = [ "mode=0755" ];
36 };
37
38 # In stage 1, mount a tmpfs on top of /nix/store (the squashfs
39 # image) to make this a live CD.
40 fileSystems."/nix/.ro-store" =
41 { fsType = "squashfs";
42 device = "../nix-store.squashfs";
43 options = [ "loop" ];
44 neededForBoot = true;
45 };
46
47 fileSystems."/nix/.rw-store" =
48 { fsType = "tmpfs";
49 options = [ "mode=0755" ];
50 neededForBoot = true;
51 };
52
53 fileSystems."/nix/store" =
54 { fsType = "unionfs-fuse";
55 device = "unionfs";
56 options = [ "allow_other" "cow" "nonempty" "chroot=/mnt-root" "max_files=32768" "hide_meta_files" "dirs=/nix/.rw-store=rw:/nix/.ro-store=ro" ];
57 };
58
59 boot.initrd.availableKernelModules = [ "squashfs" ];
60
61 boot.initrd.kernelModules = [ "loop" ];
62
63 # Closures to be copied to the Nix store, namely the init
64 # script and the top-level system configuration directory.
65 netboot.storeContents =
66 [ config.system.build.toplevel ];
67
68 # Create the squashfs image that contains the Nix store.
69 system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
70 inherit (pkgs) stdenv squashfsTools closureInfo;
71 storeContents = config.netboot.storeContents;
72 };
73
74
75 # Create the initrd
76 system.build.netbootRamdisk = pkgs.makeInitrd {
77 inherit (config.boot.initrd) compressor;
78 prepend = [ "${config.system.build.initialRamdisk}/initrd" ];
79
80 contents =
81 [ { object = config.system.build.squashfsStore;
82 symlink = "/nix-store.squashfs";
83 }
84 ];
85 };
86
87 system.build.netbootIpxeScript = pkgs.writeTextDir "netboot.ipxe" ''
88 #!ipxe
89 kernel ${pkgs.stdenv.platform.kernelTarget} init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}
90 initrd initrd
91 boot
92 '';
93
94 boot.loader.timeout = 10;
95
96 boot.postBootCommands =
97 ''
98 # After booting, register the contents of the Nix store
99 # in the Nix database in the tmpfs.
100 ${config.nix.package}/bin/nix-store --load-db < /nix/store/nix-path-registration
101
102 # nixos-rebuild also requires a "system" profile and an
103 # /etc/NIXOS tag.
104 touch /etc/NIXOS
105 ${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
106 '';
107
108 };
109
110}