summaryrefslogtreecommitdiff
path: root/installer-profiles/nfsroot.nix
blob: 9db415a86c335a343b8b04365685aef050a69b71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
{ config, pkgs, lib, flakeInputs, ... }:

with lib;

let
  cfg = config.nfsroot;
in {
  imports = [
    "${flakeInputs.nixpkgs.outPath}/nixos/modules/profiles/minimal.nix"
    "${flakeInputs.nixpkgs.outPath}/nixos/modules/profiles/all-hardware.nix"
    "${flakeInputs.nixpkgs.outPath}/nixos/modules/profiles/base.nix"
    "${flakeInputs.nixpkgs.outPath}/nixos/modules/profiles/installation-device.nix"
  ];

  options = {
    nfsroot = {
      storeDevice = mkOption {
        type = types.str;
      };
    };
  };

  config = {
    # Don't build the GRUB menu builder script, since we don't need it
    # here and it causes a cyclic dependency.
    boot.loader.grub.enable = false;

    # !!! Hack - attributes expected by other modules.
    environment.systemPackages = [ pkgs.grub2_efi ]
      ++ (if pkgs.stdenv.hostPlatform.system == "aarch64-linux"
          then []
          else [ pkgs.grub2 pkgs.syslinux ]);

    fileSystems."/" = mkImageMediaOverride
      { fsType = "tmpfs";
        options = [ "mode=0755" ];
      };

    # In stage 1, mount a tmpfs on top of /nix/store (the squashfs
    # image) to make this a live CD.
    fileSystems."/nix/.ro-store" = mkImageMediaOverride
      { fsType = "nfs4";
        device = cfg.storeDevice;
        options = [ "ro" ];
        neededForBoot = true;
      };

    fileSystems."/nix/.rw-store" = mkImageMediaOverride
      { fsType = "tmpfs";
        options = [ "mode=0755" ];
        neededForBoot = true;
      };

    fileSystems."/nix/store" = mkImageMediaOverride
      { fsType = "overlay";
        device = "overlay";
        options = [
          "lowerdir=/nix/.ro-store"
          "upperdir=/nix/.rw-store/store"
          "workdir=/nix/.rw-store/work"
        ];

        depends = [
          "/nix/.ro-store"
          "/nix/.rw-store/store"
          "/nix/.rw-store/work"
        ];
      };

    boot.initrd.availableKernelModules = [ "nfs" "nfsv4" "overlay" ];
    boot.initrd.supportedFilesystems = [ "nfs" "nfsv4" "overlay" ];

    boot.initrd.network.enable = true;
    boot.initrd.network.flushBeforeStage2 = false; # otherwise nfs dosen't work
    networking.useDHCP = true;


    system.build.netbootIpxeScript = pkgs.writeTextDir "netboot.ipxe" ''
      #!ipxe
      # Use the cmdline variable to allow the user to specify custom kernel params
      # when chainloading this script from other iPXE scripts like netboot.xyz
      kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ${toString config.boot.kernelParams} ''${cmdline}
      initrd initrd
      boot
    '';

    boot.postBootCommands =
      ''
        # nixos-rebuild also requires a "system" profile and an
        # /etc/NIXOS tag.
        touch /etc/NIXOS
        ${config.nix.package}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
      '';
  };
}