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>
This commit is contained in:
parent
ecfc523d32
commit
83c0aca062
20
nixos/modules/installer/netboot/netboot-base.nix
Normal file
20
nixos/modules/installer/netboot/netboot-base.nix
Normal file
@ -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 = "";
|
||||||
|
}
|
10
nixos/modules/installer/netboot/netboot-minimal.nix
Normal file
10
nixos/modules/installer/netboot/netboot-minimal.nix
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# This module defines a small netboot environment.
|
||||||
|
|
||||||
|
{ config, lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ ./netboot-base.nix
|
||||||
|
../../profiles/minimal.nix
|
||||||
|
];
|
||||||
|
}
|
91
nixos/modules/installer/netboot/netboot.nix
Normal file
91
nixos/modules/installer/netboot/netboot.nix
Normal file
@ -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
|
||||||
|
'';
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -104,6 +104,20 @@ in rec {
|
|||||||
initialRamdisk = buildFromConfig ({ pkgs, ... }: { }) (config: config.system.build.initialRamdisk);
|
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 {
|
iso_minimal = forAllSystems (system: makeIso {
|
||||||
module = ./modules/installer/cd-dvd/installation-cd-minimal.nix;
|
module = ./modules/installer/cd-dvd/installation-cd-minimal.nix;
|
||||||
type = "minimal";
|
type = "minimal";
|
||||||
|
@ -44,5 +44,41 @@ in {
|
|||||||
usb => glob("${iso}/iso/*.iso"),
|
usb => glob("${iso}/iso/*.iso"),
|
||||||
bios => '${pkgs.OVMF}/FV/OVMF.fd'
|
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;
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user