summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorNahum Shalman <nshalman@omniti.com>2016-04-08 13:53:27 +0000
committerDomen Kožar <domen@dev.si>2016-04-29 10:42:39 +0100
commit83c0aca062369aa43d5e692f22ff22e8d2e787a1 (patch)
treef2a53e3e9e7ddab85f6688bed0eaa348352c59de /nixos
parentecfc523d32b6969fbb0c5641fb2d155812e2b9f8 (diff)
downloadnixlib-83c0aca062369aa43d5e692f22ff22e8d2e787a1.tar
nixlib-83c0aca062369aa43d5e692f22ff22e8d2e787a1.tar.gz
nixlib-83c0aca062369aa43d5e692f22ff22e8d2e787a1.tar.bz2
nixlib-83c0aca062369aa43d5e692f22ff22e8d2e787a1.tar.lz
nixlib-83c0aca062369aa43d5e692f22ff22e8d2e787a1.tar.xz
nixlib-83c0aca062369aa43d5e692f22ff22e8d2e787a1.tar.zst
nixlib-83c0aca062369aa43d5e692f22ff22e8d2e787a1.zip
installer: simple PXE bootable NixOS installer
The Nix store squashfs is stored inside the initrd instead of separately

(cherry picked from commit 976fd407796877b538c470d3a5253ad3e1f7bc68)
Signed-off-by: Domen Kožar <domen@dev.si>
Diffstat (limited to 'nixos')
-rw-r--r--nixos/modules/installer/netboot/netboot-base.nix20
-rw-r--r--nixos/modules/installer/netboot/netboot-minimal.nix10
-rw-r--r--nixos/modules/installer/netboot/netboot.nix91
-rw-r--r--nixos/release.nix14
-rw-r--r--nixos/tests/boot.nix40
5 files changed, 173 insertions, 2 deletions
diff --git a/nixos/modules/installer/netboot/netboot-base.nix b/nixos/modules/installer/netboot/netboot-base.nix
new file mode 100644
index 000000000000..b12eaccf8707
--- /dev/null
+++ b/nixos/modules/installer/netboot/netboot-base.nix
@@ -0,0 +1,20 @@
+# This module contains the basic configuration for building netboot
+# images
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  imports =
+    [ ./netboot.nix
+
+      # Profiles of this basic netboot media
+      ../../profiles/all-hardware.nix
+      ../../profiles/base.nix
+      ../../profiles/installation-device.nix
+    ];
+
+  # Allow the user to log in as root without a password.
+  users.extraUsers.root.initialHashedPassword = "";
+}
diff --git a/nixos/modules/installer/netboot/netboot-minimal.nix b/nixos/modules/installer/netboot/netboot-minimal.nix
new file mode 100644
index 000000000000..8ad6234edc77
--- /dev/null
+++ b/nixos/modules/installer/netboot/netboot-minimal.nix
@@ -0,0 +1,10 @@
+# This module defines a small netboot environment.
+
+{ config, lib, ... }:
+
+{
+  imports =
+    [ ./netboot-base.nix
+      ../../profiles/minimal.nix
+    ];
+}
diff --git a/nixos/modules/installer/netboot/netboot.nix b/nixos/modules/installer/netboot/netboot.nix
new file mode 100644
index 000000000000..366591a81148
--- /dev/null
+++ b/nixos/modules/installer/netboot/netboot.nix
@@ -0,0 +1,91 @@
+# This module creates netboot media containing the given NixOS
+# configuration.
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  options = {
+
+    netboot.storeContents = mkOption {
+      example = literalExample "[ pkgs.stdenv ]";
+      description = ''
+        This option lists additional derivations to be included in the
+        Nix store in the generated netboot image.
+      '';
+    };
+
+  };
+
+  config = {
+
+    boot.loader.grub.version = 2;
+
+    # 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;
+
+    boot.initrd.postMountCommands = ''
+      mkdir -p /mnt-root/nix/store
+      mount -t squashfs /nix-store.squashfs /mnt-root/nix/store
+    '';
+
+    # !!! Hack - attributes expected by other modules.
+    system.boot.loader.kernelFile = "bzImage";
+    environment.systemPackages = [ pkgs.grub2 pkgs.grub2_efi pkgs.syslinux ];
+
+    boot.consoleLogLevel = mkDefault 7;
+
+    fileSystems."/" =
+      { fsType = "tmpfs";
+        options = [ "mode=0755" ];
+      };
+
+    boot.initrd.availableKernelModules = [ "squashfs" ];
+
+    boot.initrd.kernelModules = [ "loop" ];
+
+    # Closures to be copied to the Nix store, namely the init
+    # script and the top-level system configuration directory.
+   netboot.storeContents =
+      [ config.system.build.toplevel ];
+
+    # Create the squashfs image that contains the Nix store.
+    system.build.squashfsStore = import ../../../lib/make-squashfs.nix {
+      inherit (pkgs) stdenv squashfsTools perl pathsFromGraph;
+      storeContents = config.netboot.storeContents;
+    };
+
+
+    # Create the initrd
+    system.build.netbootRamdisk = pkgs.makeInitrd {
+      inherit (config.boot.initrd) compressor;
+      prepend = [ "${config.system.build.initialRamdisk}/initrd" ];
+
+      contents =
+        [ { object = config.system.build.squashfsStore;
+            symlink = "/nix-store.squashfs";
+          }
+        ];
+    };
+
+    system.build.netbootIpxeScript = pkgs.writeTextDir "netboot.ipxe" "#!ipxe\nkernel bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams}\ninitrd initrd\nboot";
+
+    boot.loader.timeout = 10;
+
+    boot.postBootCommands =
+      ''
+        # After booting, register the contents of the Nix store
+        # in the Nix database in the tmpfs.
+        ${config.nix.package}/bin/nix-store --load-db < /nix/store/nix-path-registration
+
+        # 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
+      '';
+
+  };
+
+}
diff --git a/nixos/release.nix b/nixos/release.nix
index d78c1bb1c150..fa4a98601509 100644
--- a/nixos/release.nix
+++ b/nixos/release.nix
@@ -104,6 +104,20 @@ in rec {
   initialRamdisk = buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.initialRamdisk);
 
 
+  netboot = let build = (import lib/eval-config.nix {
+      system = "x86_64-linux";
+      modules = [
+        ./modules/installer/netboot/netboot-minimal.nix
+        versionModule
+      ];
+    }).config.system.build;
+  in
+    pkgs.symlinkJoin "netboot" [
+      build.netbootRamdisk
+      build.kernel
+      build.netbootIpxeScript
+    ];
+
   iso_minimal = forAllSystems (system: makeIso {
     module = ./modules/installer/cd-dvd/installation-cd-minimal.nix;
     type = "minimal";
diff --git a/nixos/tests/boot.nix b/nixos/tests/boot.nix
index 905d16458825..a138ba4bcf08 100644
--- a/nixos/tests/boot.nix
+++ b/nixos/tests/boot.nix
@@ -44,5 +44,41 @@ in {
         usb => glob("${iso}/iso/*.iso"),
         bios => '${pkgs.OVMF}/FV/OVMF.fd'
       '';
-  }
-
+    netboot = let
+      config = (import ../lib/eval-config.nix {
+          inherit system;
+          modules =
+            [ ../modules/installer/netboot/netboot.nix
+              ../modules/testing/test-instrumentation.nix
+              { key = "serial"; }
+            ];
+        }).config;
+      ipxeScriptDir = pkgs.writeTextFile {
+        name = "ipxeScriptDir";
+        text = ''
+          #!ipxe
+          dhcp
+          kernel bzImage init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} console=ttyS0
+          initrd initrd
+          boot
+        '';
+        destination = "/boot.ipxe";
+      };
+      ipxeBootDir = pkgs.symlinkJoin "ipxeBootDir" [
+        config.system.build.netbootRamdisk
+        config.system.build.kernel
+        ipxeScriptDir
+      ];
+    in
+      makeTest {
+        name = "boot-netboot";
+        nodes = { };
+        testScript =
+          ''
+            my $machine = createMachine({ qemuFlags => '-boot order=n -net nic,model=e1000 -net user,tftp=${ipxeBootDir}/,bootfile=boot.ipxe -m 2000M' });
+            $machine->start;
+            $machine->waitForUnit("multi-user.target");
+            $machine->shutdown;
+          '';
+      };
+}
\ No newline at end of file