252 lines
7.7 KiB
Nix
252 lines
7.7 KiB
Nix
{ lib, pkgs, extendModules, modulesPath, options, config, ... }:
|
|
let
|
|
inherit (lib) recursiveUpdate mkOption mkDefault mkIf mkMerge mkForce flatten optional;
|
|
inherit (lib.my) mkBoolOpt' dummyOption;
|
|
|
|
cfg = config.my.build;
|
|
|
|
allHardware = (optional config.my.build.allHardware { imports = [ "${modulesPath}/profiles/all-hardware.nix" ]; });
|
|
|
|
asDevVM = extendModules {
|
|
modules = [
|
|
"${modulesPath}/virtualisation/qemu-vm.nix"
|
|
{ my.build.isDevVM = true; }
|
|
];
|
|
};
|
|
asISO = extendModules {
|
|
modules = flatten [
|
|
"${modulesPath}/installer/cd-dvd/iso-image.nix"
|
|
allHardware
|
|
{
|
|
# Doesn't work right now... (missing /dev/root)
|
|
boot.initrd.systemd.enable = false;
|
|
|
|
isoImage = {
|
|
makeEfiBootable = true;
|
|
makeUsbBootable = true;
|
|
# Not necessarily an installer
|
|
appendToMenuLabel = mkDefault "";
|
|
|
|
squashfsCompression = "zstd -Xcompression-level 8";
|
|
};
|
|
}
|
|
];
|
|
};
|
|
asContainer = extendModules {
|
|
modules = [
|
|
{
|
|
boot.isContainer = true;
|
|
}
|
|
];
|
|
};
|
|
asKexecTree = extendModules {
|
|
modules = flatten [
|
|
"${modulesPath}/installer/netboot/netboot.nix"
|
|
allHardware
|
|
];
|
|
};
|
|
|
|
asNetboot = extendModules {
|
|
modules = flatten [
|
|
allHardware
|
|
({ pkgs, config, ... }: {
|
|
boot = {
|
|
loader.grub.enable = false;
|
|
initrd = {
|
|
kernelModules = [ "nbd" ];
|
|
availableKernelModules = [ "igb" "igc" ];
|
|
|
|
systemd = {
|
|
storePaths = with pkgs; [
|
|
gnused
|
|
nbd
|
|
netcat
|
|
];
|
|
extraBin = with pkgs; {
|
|
dmesg = "${util-linux}/bin/dmesg";
|
|
ip = "${iproute2}/bin/ip";
|
|
nbd-client = "${nbd}/bin/nbd-client";
|
|
};
|
|
extraConfig = ''
|
|
DefaultTimeoutStartSec=20
|
|
DefaultDeviceTimeoutSec=20
|
|
'';
|
|
|
|
network = {
|
|
enable = true;
|
|
wait-online.enable = true;
|
|
|
|
networks."10-netboot" = {
|
|
matchConfig.Name = "et-boot";
|
|
DHCP = "yes";
|
|
};
|
|
};
|
|
|
|
services = {
|
|
nbd = {
|
|
description = "NBD Root FS";
|
|
|
|
script = ''
|
|
get_cmdline() {
|
|
${pkgs.gnused}/bin/sed -rn "s/^.*$1=(\\S+).*\$/\\1/p" < /proc/cmdline
|
|
}
|
|
|
|
s="$(get_cmdline nbd_server)"
|
|
until ${pkgs.netcat}/bin/nc -zv "$s" 22; do
|
|
sleep 0.1
|
|
done
|
|
|
|
exec ${pkgs.nbd}/bin/nbd-client -systemd-mark -N "$(get_cmdline nbd_export)" "$s" /dev/nbd0
|
|
'';
|
|
unitConfig = {
|
|
IgnoreOnIsolate = "yes";
|
|
DefaultDependencies = "no";
|
|
};
|
|
serviceConfig = {
|
|
Type = "forking";
|
|
Restart = "on-failure";
|
|
RestartSec = 10;
|
|
};
|
|
|
|
wantedBy = [ "initrd-root-device.target" ];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
postBootCommands = ''
|
|
# After booting, register the contents of the Nix store
|
|
# in the Nix database in the COW root.
|
|
${config.nix.package}/bin/nix-store --load-db < /nix-path-registration
|
|
|
|
# nixos-rebuild also requires a "system" profile and an
|
|
# /etc/NIXOS tag.
|
|
touch /etc/NIXOS
|
|
${config.nix.package.out}/bin/nix-env -p /nix/var/nix/profiles/system --set /run/current-system
|
|
'';
|
|
};
|
|
|
|
programs.nbd.enable = true;
|
|
|
|
fileSystems = {
|
|
"/" = {
|
|
fsType = "ext4";
|
|
device = "/dev/nbd0";
|
|
noCheck = true;
|
|
autoResize = true;
|
|
};
|
|
};
|
|
|
|
networking.useNetworkd = mkForce true;
|
|
|
|
systemd = {
|
|
network.networks."10-boot" = {
|
|
matchConfig.Name = "et-boot";
|
|
DHCP = "yes";
|
|
networkConfig.KeepConfiguration = "yes";
|
|
};
|
|
};
|
|
|
|
system.build = {
|
|
rootImage = pkgs.callPackage "${modulesPath}/../lib/make-ext4-fs.nix" {
|
|
storePaths = [ config.system.build.toplevel ];
|
|
volumeLabel = "netboot-root";
|
|
};
|
|
netbootScript = pkgs.writeText "boot.ipxe" ''
|
|
#!ipxe
|
|
kernel ${pkgs.stdenv.hostPlatform.linux-kernel.target} init=${config.system.build.toplevel}/init initrd=initrd ifname=et-boot:''${mac} nbd_server=''${next-server} ${toString config.boot.kernelParams} ''${cmdline}
|
|
initrd initrd
|
|
boot
|
|
'';
|
|
|
|
netbootTree = pkgs.linkFarm "netboot-${config.system.name}" [
|
|
{
|
|
name = config.system.boot.loader.kernelFile;
|
|
path = "${config.system.build.kernel}/${config.system.boot.loader.kernelFile}";
|
|
}
|
|
{
|
|
name = "initrd";
|
|
path = "${config.system.build.initialRamdisk}/initrd";
|
|
}
|
|
{
|
|
name = "rootfs.ext4";
|
|
path = config.system.build.rootImage;
|
|
}
|
|
{
|
|
name = "boot.ipxe";
|
|
path = config.system.build.netbootScript;
|
|
}
|
|
];
|
|
netbootArchive = pkgs.runCommand "netboot-${config.system.name}.tar.zst" { } ''
|
|
export PATH=${pkgs.zstd}/bin:$PATH
|
|
${pkgs.gnutar}/bin/tar --dereference --zstd -cvC ${config.system.build.netbootTree} -f "$out" .
|
|
'';
|
|
};
|
|
})
|
|
];
|
|
};
|
|
|
|
mkAsOpt = ext: desc: with lib.types; mkOption {
|
|
type = unspecified;
|
|
default = ext;
|
|
visible = "shallow";
|
|
description = "Configuration as ${desc}.";
|
|
};
|
|
in
|
|
{
|
|
options = {
|
|
my = {
|
|
build = {
|
|
isDevVM = mkBoolOpt' false "Whether the system is a development VM.";
|
|
allHardware = mkBoolOpt' false
|
|
("Whether to enable a lot of firmware and kernel modules for a wide range of hardware." +
|
|
"Only applies to some build targets.");
|
|
};
|
|
|
|
asDevVM = mkAsOpt asDevVM "a development VM";
|
|
asISO = mkAsOpt asISO "a bootable .iso image";
|
|
asContainer = mkAsOpt asContainer "a container";
|
|
asKexecTree = mkAsOpt asKexecTree "a kexec-able kernel and initrd";
|
|
asNetboot = mkAsOpt asNetboot "a netboot-able kernel initrd, and iPXE script";
|
|
|
|
buildAs = options.system.build;
|
|
};
|
|
|
|
# Forward declare options that won't exist until the VM module is actually imported
|
|
virtualisation = {
|
|
diskImage = dummyOption;
|
|
forwardPorts = dummyOption;
|
|
sharedDirectories = dummyOption;
|
|
cores = dummyOption;
|
|
memorySize = dummyOption;
|
|
qemu.options = dummyOption;
|
|
};
|
|
isoImage = {
|
|
isoBaseName = dummyOption;
|
|
volumeID = dummyOption;
|
|
edition = dummyOption;
|
|
appendToMenuLabel = dummyOption;
|
|
};
|
|
};
|
|
|
|
config = {
|
|
virtualisation = {
|
|
diskImage = mkDefault "./.vms/${config.system.name}.qcow2";
|
|
};
|
|
|
|
my = {
|
|
buildAs = {
|
|
# The meta.mainProgram should probably be set upstream but oh well...
|
|
devVM = recursiveUpdate config.my.asDevVM.config.system.build.vm { meta.mainProgram = "run-${config.system.name}-vm"; };
|
|
iso = config.my.asISO.config.system.build.isoImage;
|
|
container = config.my.asContainer.config.system.build.toplevel;
|
|
kexecTree = config.my.asKexecTree.config.system.build.kexecTree;
|
|
netbootTree = config.my.asNetboot.config.system.build.netbootTree;
|
|
netbootArchive = config.my.asNetboot.config.system.build.netbootArchive;
|
|
};
|
|
};
|
|
};
|
|
|
|
meta.buildDocsInSandbox = false;
|
|
}
|