nixos/iso-image: Support specialisations.
This commit is contained in:
@@ -8,57 +8,63 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
/**
|
||||
Given a list of `options`, concats the result of mapping each options
|
||||
to a menuentry for use in grub.
|
||||
|
||||
* defaults: {name, image, params, initrd}
|
||||
* options: [ option... ]
|
||||
* option: {name, params, class}
|
||||
*/
|
||||
# Builds a single menu entry
|
||||
menuBuilderGrub2 =
|
||||
defaults: options:
|
||||
lib.concatStrings (
|
||||
map (option: ''
|
||||
menuentry '${defaults.name} ${
|
||||
# Name appended to menuentry defaults to params if no specific name given.
|
||||
option.name or (lib.optionalString (option ? params) "(${option.params})")
|
||||
}' ${lib.optionalString (option ? class) " --class ${option.class}"} {
|
||||
# Fallback to UEFI console for boot, efifb sometimes has difficulties.
|
||||
terminal_output console
|
||||
{
|
||||
name,
|
||||
class,
|
||||
image,
|
||||
params,
|
||||
initrd,
|
||||
}:
|
||||
''
|
||||
menuentry '${name}' --class ${class} {
|
||||
# Fallback to UEFI console for boot, efifb sometimes has difficulties.
|
||||
terminal_output console
|
||||
|
||||
linux ${defaults.image} \''${isoboot} ${defaults.params} ${option.params or ""}
|
||||
initrd ${defaults.initrd}
|
||||
}
|
||||
'') options
|
||||
);
|
||||
linux ${image} \''${isoboot} ${params}
|
||||
initrd ${initrd}
|
||||
}
|
||||
'';
|
||||
|
||||
/**
|
||||
Builds the default options.
|
||||
*/
|
||||
buildMenuGrub2 = buildMenuAdditionalParamsGrub2 "";
|
||||
# Builds all menu entries
|
||||
buildMenuGrub2 =
|
||||
{
|
||||
cfg ? config,
|
||||
params ? [ ],
|
||||
}:
|
||||
let
|
||||
menuConfig = {
|
||||
name = lib.concatStrings [
|
||||
cfg.isoImage.prependToMenuLabel
|
||||
cfg.system.nixos.distroName
|
||||
" "
|
||||
cfg.system.nixos.label
|
||||
cfg.isoImage.appendToMenuLabel
|
||||
(lib.optionalString (cfg.isoImage.configurationName != null) (" " + cfg.isoImage.configurationName))
|
||||
];
|
||||
params = "init=${cfg.system.build.toplevel}/init ${toString cfg.boot.kernelParams} ${toString params}";
|
||||
image = "/boot/${cfg.boot.kernelPackages.kernel + "/" + cfg.system.boot.loader.kernelFile}";
|
||||
initrd = "/boot/${cfg.system.build.initialRamdisk + "/" + cfg.system.boot.loader.initrdFile}";
|
||||
class = "installer";
|
||||
};
|
||||
in
|
||||
''
|
||||
${lib.optionalString cfg.isoImage.showConfiguration (menuBuilderGrub2 menuConfig)}
|
||||
${lib.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList (
|
||||
specName:
|
||||
{ configuration, ... }:
|
||||
buildMenuGrub2 {
|
||||
cfg = configuration;
|
||||
inherit params;
|
||||
}
|
||||
) cfg.specialisation
|
||||
)}
|
||||
'';
|
||||
|
||||
targetArch = if config.boot.loader.grub.forcei686 then "ia32" else pkgs.stdenv.hostPlatform.efiArch;
|
||||
|
||||
/**
|
||||
Given params to add to `params`, build a set of default options.
|
||||
Use this one when creating a variant (e.g. hidpi)
|
||||
*/
|
||||
buildMenuAdditionalParamsGrub2 =
|
||||
additional:
|
||||
let
|
||||
finalCfg = {
|
||||
name = "${config.isoImage.prependToMenuLabel}${config.system.nixos.distroName} ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}";
|
||||
params = "init=${config.system.build.toplevel}/init ${additional} ${toString config.boot.kernelParams}";
|
||||
image = "/boot/${config.system.boot.loader.kernelFile}";
|
||||
initrd = "/boot/initrd";
|
||||
};
|
||||
|
||||
in
|
||||
menuBuilderGrub2 finalCfg [
|
||||
{ class = "installer"; }
|
||||
];
|
||||
|
||||
# Timeout in syslinux is in units of 1/10 of a second.
|
||||
# null means max timeout (35996, just under 1h in 1/10 seconds)
|
||||
# 0 means disable timeout
|
||||
@@ -137,13 +143,32 @@ let
|
||||
# result in incorrect boot entries.
|
||||
|
||||
menuBuilderIsolinux =
|
||||
{ label, params }:
|
||||
{
|
||||
cfg ? config,
|
||||
label,
|
||||
params ? [ ],
|
||||
}:
|
||||
''
|
||||
LABEL ${label}
|
||||
MENU LABEL ${config.isoImage.prependToMenuLabel}${config.system.nixos.distroName} ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}
|
||||
LINUX /boot/${config.system.boot.loader.kernelFile}
|
||||
APPEND init=${config.system.build.toplevel}/init ${toString config.boot.kernelParams} ${toString params}
|
||||
INITRD /boot/${config.system.boot.loader.initrdFile}
|
||||
${lib.optionalString cfg.isoImage.showConfiguration ''
|
||||
LABEL ${label}
|
||||
MENU LABEL ${cfg.isoImage.prependToMenuLabel}${cfg.system.nixos.distroName} ${cfg.system.nixos.label}${cfg.isoImage.appendToMenuLabel}${
|
||||
lib.optionalString (cfg.isoImage.configurationName != null) (" " + cfg.isoImage.configurationName)
|
||||
}
|
||||
LINUX /boot/${cfg.boot.kernelPackages.kernel + "/" + cfg.system.boot.loader.kernelFile}
|
||||
APPEND init=${cfg.system.build.toplevel}/init ${toString cfg.boot.kernelParams} ${toString params}
|
||||
INITRD /boot/${cfg.system.build.initialRamdisk + "/" + cfg.system.boot.loader.initrdFile}
|
||||
''}
|
||||
|
||||
${lib.concatStringsSep "\n\n" (
|
||||
lib.mapAttrsToList (
|
||||
name: specCfg:
|
||||
menuBuilderIsolinux {
|
||||
cfg = specCfg.configuration;
|
||||
label = "${label}-${name}";
|
||||
inherit params;
|
||||
}
|
||||
) cfg.specialisation
|
||||
)}
|
||||
'';
|
||||
|
||||
baseIsolinuxCfg = ''
|
||||
@@ -156,10 +181,7 @@ let
|
||||
|
||||
DEFAULT boot
|
||||
|
||||
${menuBuilderIsolinux {
|
||||
label = "boot";
|
||||
params = [ ];
|
||||
}}
|
||||
${menuBuilderIsolinux { label = "boot"; }}
|
||||
|
||||
MENU BEGIN Options
|
||||
|
||||
@@ -209,6 +231,8 @@ let
|
||||
grubPkgs = if config.boot.loader.grub.forcei686 then pkgs.pkgsi686Linux else pkgs;
|
||||
|
||||
grubMenuCfg = ''
|
||||
set textmode=${lib.boolToString (config.isoImage.forceTextMode)}
|
||||
|
||||
#
|
||||
# Menu configuration
|
||||
#
|
||||
@@ -273,6 +297,20 @@ let
|
||||
fi
|
||||
''
|
||||
}
|
||||
|
||||
hiddenentry 'Text mode' --hotkey 't' {
|
||||
loadfont (\$root)/EFI/BOOT/unicode.pf2
|
||||
set textmode=true
|
||||
terminal_output console
|
||||
}
|
||||
|
||||
${lib.optionalString (config.isoImage.grubTheme != null) ''
|
||||
hiddenentry 'GUI mode' --hotkey 'g' {
|
||||
$(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/BOOT/grub-theme/%P\n")
|
||||
set textmode=false
|
||||
terminal_output gfxterm
|
||||
}
|
||||
''}
|
||||
'';
|
||||
|
||||
# The EFI boot image.
|
||||
@@ -368,7 +406,6 @@ let
|
||||
|
||||
cat <<EOF > $out/EFI/BOOT/grub.cfg
|
||||
|
||||
set textmode=${lib.boolToString (config.isoImage.forceTextMode)}
|
||||
set timeout=${toString grubEfiTimeout}
|
||||
|
||||
clear
|
||||
@@ -381,20 +418,6 @@ let
|
||||
|
||||
${grubMenuCfg}
|
||||
|
||||
hiddenentry 'Text mode' --hotkey 't' {
|
||||
loadfont (\$root)/EFI/BOOT/unicode.pf2
|
||||
set textmode=true
|
||||
terminal_output console
|
||||
}
|
||||
|
||||
${lib.optionalString (config.isoImage.grubTheme != null) ''
|
||||
hiddenentry 'GUI mode' --hotkey 'g' {
|
||||
$(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/BOOT/grub-theme/%P\n")
|
||||
set textmode=false
|
||||
terminal_output gfxterm
|
||||
}
|
||||
''}
|
||||
|
||||
# If the parameter iso_path is set, append the findiso parameter to the kernel
|
||||
# line. We need this to allow the nixos iso to be booted from grub directly.
|
||||
if [ \''${iso_path} ] ; then
|
||||
@@ -405,7 +428,7 @@ let
|
||||
# Menu entries
|
||||
#
|
||||
|
||||
${buildMenuGrub2}
|
||||
${buildMenuGrub2 { }}
|
||||
submenu "Options" --class submenu --class hidpi {
|
||||
${grubMenuCfg}
|
||||
|
||||
@@ -418,7 +441,7 @@ let
|
||||
''
|
||||
submenu "${title}" --class ${class} {
|
||||
${grubMenuCfg}
|
||||
${buildMenuAdditionalParamsGrub2 (toString params)}
|
||||
${buildMenuGrub2 { inherit params; }}
|
||||
}
|
||||
''
|
||||
) optionsSubMenus}
|
||||
@@ -721,6 +744,19 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
isoImage.configurationName = lib.mkOption {
|
||||
default = null;
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
example = "GNOME";
|
||||
description = ''
|
||||
The name of the configuration in the title of the boot entry.
|
||||
'';
|
||||
};
|
||||
|
||||
isoImage.showConfiguration = lib.mkEnableOption "show this configuration in the menu" // {
|
||||
default = true;
|
||||
};
|
||||
|
||||
isoImage.forceTextMode = lib.mkOption {
|
||||
default = false;
|
||||
type = lib.types.bool;
|
||||
@@ -806,6 +842,25 @@ in
|
||||
in
|
||||
"isoImage.volumeID ${config.isoImage.volumeID} is ${howmany} characters. That is ${toomany} characters longer than the limit of 32.";
|
||||
}
|
||||
(
|
||||
let
|
||||
badSpecs = lib.filterAttrs (
|
||||
specName: specCfg: specCfg.configuration.isoImage.volumeID != config.isoImage.volumeID
|
||||
) config.specialisation;
|
||||
in
|
||||
{
|
||||
assertion = badSpecs == { };
|
||||
message = ''
|
||||
All specialisations must use the same 'isoImage.volumeID'.
|
||||
|
||||
Specialisations with different volumeIDs:
|
||||
|
||||
${lib.concatMapStringsSep "\n" (specName: ''
|
||||
- ${specName}
|
||||
'') (builtins.attrNames badSpecs)}
|
||||
'';
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
# Don't build the GRUB menu builder script, since we don't need it
|
||||
@@ -853,20 +908,30 @@ in
|
||||
# Individual files to be included on the CD, outside of the Nix
|
||||
# store on the CD.
|
||||
isoImage.contents =
|
||||
let
|
||||
cfgFiles =
|
||||
cfg:
|
||||
lib.optionals cfg.isoImage.showConfiguration ([
|
||||
{
|
||||
source = cfg.boot.kernelPackages.kernel + "/" + cfg.system.boot.loader.kernelFile;
|
||||
target = "/boot/" + cfg.boot.kernelPackages.kernel + "/" + cfg.system.boot.loader.kernelFile;
|
||||
}
|
||||
{
|
||||
source = cfg.system.build.initialRamdisk + "/" + cfg.system.boot.loader.initrdFile;
|
||||
target = "/boot/" + cfg.system.build.initialRamdisk + "/" + cfg.system.boot.loader.initrdFile;
|
||||
}
|
||||
])
|
||||
++ lib.concatLists (
|
||||
lib.mapAttrsToList (_: { configuration, ... }: cfgFiles configuration) cfg.specialisation
|
||||
);
|
||||
in
|
||||
[
|
||||
{
|
||||
source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
|
||||
target = "/boot/" + config.system.boot.loader.kernelFile;
|
||||
}
|
||||
{
|
||||
source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile;
|
||||
target = "/boot/" + config.system.boot.loader.initrdFile;
|
||||
}
|
||||
{
|
||||
source = pkgs.writeText "version" config.system.nixos.label;
|
||||
target = "/version.txt";
|
||||
}
|
||||
]
|
||||
++ lib.unique (cfgFiles config)
|
||||
++ lib.optionals (config.isoImage.makeBiosBootable) [
|
||||
{
|
||||
source = config.isoImage.splashImage;
|
||||
|
||||
Reference in New Issue
Block a user