Format nix files

This commit is contained in:
Michael Smith 2024-08-19 23:42:25 +02:00
parent d0194a555b
commit 18ad437872
5 changed files with 402 additions and 366 deletions

View File

@ -3,8 +3,7 @@
lib, lib,
inputs, inputs,
... ...
}: }: {
{
imports = [ imports = [
../../modules/installer ../../modules/installer
]; ];

View File

@ -1,12 +1,19 @@
{ config, lib, options, pkgs, inputs, modulesPath, ... }:
with lib;
let
calamares-nixos-autostart = pkgs.makeAutostartItem { name = "io.calamares.calamares"; package = pkgs.calamares-nixos; };
calamares-extensions-desk-os = pkgs.callPackage ../../packages/calamares-extensions {};
in
{ {
config,
lib,
options,
pkgs,
inputs,
modulesPath,
...
}:
with lib; let
calamares-nixos-autostart = pkgs.makeAutostartItem {
name = "io.calamares.calamares";
package = pkgs.calamares-nixos;
};
calamares-extensions-desk-os = pkgs.callPackage ../../packages/calamares-extensions {};
in {
imports = [ imports = [
./iso-image.nix ./iso-image.nix
(modulesPath + "/profiles/all-hardware.nix") (modulesPath + "/profiles/all-hardware.nix")

View File

@ -1,13 +1,15 @@
# This module creates a bootable ISO image containing the given NixOS # This module creates a bootable ISO image containing the given NixOS
# configuration. The derivation for the ISO image will be placed in # configuration. The derivation for the ISO image will be placed in
# config.system.build.isoImage. # config.system.build.isoImage.
{
{ config, lib, pkgs, ... }: config,
lib,
with lib; pkgs,
...
let }:
/** with lib; let
/*
*
* Given a list of `options`, concats the result of mapping each options * Given a list of `options`, concats the result of mapping each options
* to a menuentry for use in grub. * to a menuentry for use in grub.
* *
@ -15,8 +17,8 @@ let
* * options: [ option... ] * * options: [ option... ]
* * option: {name, params, class} * * option: {name, params, class}
*/ */
menuBuilderGrub2 = menuBuilderGrub2 = defaults: options:
defaults: options: lib.concatStrings lib.concatStrings
( (
map map
(option: '' (option: ''
@ -34,56 +36,53 @@ let
} }
'') '')
options options
) );
;
/** /*
*
* Builds the default options. * Builds the default options.
*/ */
buildMenuGrub2 = buildMenuAdditionalParamsGrub2 ""; buildMenuGrub2 = buildMenuAdditionalParamsGrub2 "";
targetArch = targetArch =
if config.boot.loader.grub.forcei686 then if config.boot.loader.grub.forcei686
"ia32" then "ia32"
else else pkgs.stdenv.hostPlatform.efiArch;
pkgs.stdenv.hostPlatform.efiArch;
/** /*
*
* Given params to add to `params`, build a set of default options. * Given params to add to `params`, build a set of default options.
* Use this one when creating a variant (e.g. hidpi) * Use this one when creating a variant (e.g. hidpi)
*/ */
buildMenuAdditionalParamsGrub2 = additional: buildMenuAdditionalParamsGrub2 = additional: let
let
finalCfg = { finalCfg = {
name = "${config.isoImage.prependToMenuLabel}${config.system.nixos.distroName} ${config.system.nixos.label}${config.isoImage.appendToMenuLabel}"; 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}"; params = "init=${config.system.build.toplevel}/init ${additional} ${toString config.boot.kernelParams}";
image = "/boot/${config.system.boot.loader.kernelFile}"; image = "/boot/${config.system.boot.loader.kernelFile}";
initrd = "/boot/initrd"; initrd = "/boot/initrd";
}; };
in in
menuBuilderGrub2 menuBuilderGrub2
finalCfg finalCfg
[ [
{class = "installer";} {class = "installer";}
] ];
;
# Timeout in syslinux is in units of 1/10 of a second. # Timeout in syslinux is in units of 1/10 of a second.
# null means max timeout (35996, just under 1h in 1/10 seconds) # null means max timeout (35996, just under 1h in 1/10 seconds)
# 0 means disable timeout # 0 means disable timeout
syslinuxTimeout = if config.boot.loader.timeout == null then syslinuxTimeout =
35996 if config.boot.loader.timeout == null
else then 35996
config.boot.loader.timeout * 10; else config.boot.loader.timeout * 10;
# Timeout in grub is in seconds. # Timeout in grub is in seconds.
# null means max timeout (infinity) # null means max timeout (infinity)
# 0 means disable timeout # 0 means disable timeout
grubEfiTimeout = if config.boot.loader.timeout == null then grubEfiTimeout =
-1 if config.boot.loader.timeout == null
else then -1
config.boot.loader.timeout; else config.boot.loader.timeout;
# The configuration file for syslinux. # The configuration file for syslinux.
@ -122,23 +121,28 @@ let
APPEND ${toString config.boot.loader.grub.memtest86.params} APPEND ${toString config.boot.loader.grub.memtest86.params}
''; '';
isolinuxCfg = concatStringsSep "\n" isolinuxCfg =
concatStringsSep "\n"
([baseIsolinuxCfg] ++ optional config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry); ([baseIsolinuxCfg] ++ optional config.boot.loader.grub.memtest86.enable isolinuxMemtest86Entry);
refindBinary = if targetArch == "x64" || targetArch == "aa64" then "refind_${targetArch}.efi" else null; refindBinary =
if targetArch == "x64" || targetArch == "aa64"
then "refind_${targetArch}.efi"
else null;
# Setup instructions for rEFInd. # Setup instructions for rEFInd.
refind = refind =
if refindBinary != null then if refindBinary != null
'' then ''
# Adds rEFInd to the ISO. # Adds rEFInd to the ISO.
cp -v ${pkgs.refind}/share/refind/${refindBinary} $out/EFI/boot/ cp -v ${pkgs.refind}/share/refind/${refindBinary} $out/EFI/boot/
'' ''
else else "# No refind for ${targetArch}";
"# No refind for ${targetArch}"
;
grubPkgs = if config.boot.loader.grub.forcei686 then pkgs.pkgsi686Linux else pkgs; grubPkgs =
if config.boot.loader.grub.forcei686
then pkgs.pkgsi686Linux
else pkgs;
grubMenuCfg = '' grubMenuCfg = ''
# #
@ -181,12 +185,14 @@ let
fi fi
${ # When there is a theme configured, use it, otherwise use the background image. ${ # When there is a theme configured, use it, otherwise use the background image.
if config.isoImage.grubTheme != null then '' if config.isoImage.grubTheme != null
then ''
# Sets theme. # Sets theme.
set theme=(\$root)/EFI/boot/grub-theme/theme.txt set theme=(\$root)/EFI/boot/grub-theme/theme.txt
# Load theme fonts # Load theme fonts
$(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/boot/grub-theme/%P\n") $(find ${config.isoImage.grubTheme} -iname '*.pf2' -printf "loadfont (\$root)/EFI/boot/grub-theme/%P\n")
'' else '' ''
else ''
if background_image (\$root)/EFI/boot/efi-background.png; then if background_image (\$root)/EFI/boot/efi-background.png; then
# Black background means transparent background when there # Black background means transparent background when there
# is a background image set... This seems undocumented :( # is a background image set... This seems undocumented :(
@ -197,14 +203,16 @@ let
set menu_color_normal=cyan/blue set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue set menu_color_highlight=white/blue
fi fi
''} ''
}
''; '';
# The EFI boot image. # The EFI boot image.
# Notes about grub: # Notes about grub:
# * Yes, the grubMenuCfg has to be repeated in all submenus. Otherwise you # * Yes, the grubMenuCfg has to be repeated in all submenus. Otherwise you
# will get white-on-black console-like text on sub-menus. *sigh* # will get white-on-black console-like text on sub-menus. *sigh*
efiDir = pkgs.runCommand "efi-directory" { efiDir =
pkgs.runCommand "efi-directory" {
nativeBuildInputs = [pkgs.buildPackages.grub2_efi]; nativeBuildInputs = [pkgs.buildPackages.grub2_efi];
strictDeps = true; strictDeps = true;
} '' } ''
@ -405,7 +413,8 @@ let
${refind} ${refind}
''; '';
efiImg = pkgs.runCommand "efi-image_eltorito" { efiImg =
pkgs.runCommand "efi-image_eltorito" {
nativeBuildInputs = [pkgs.buildPackages.mtools pkgs.buildPackages.libfaketime pkgs.buildPackages.dosfstools]; nativeBuildInputs = [pkgs.buildPackages.mtools pkgs.buildPackages.libfaketime pkgs.buildPackages.dosfstools];
strictDeps = true; strictDeps = true;
} }
@ -443,12 +452,8 @@ let
# Verify the FAT partition. # Verify the FAT partition.
fsck.vfat -vn "$out" fsck.vfat -vn "$out"
''; # */ ''; # */
in {
in
{
options = { options = {
isoImage.isoName = mkOption { isoImage.isoName = mkOption {
default = "${config.isoImage.isoBaseName}.iso"; default = "${config.isoImage.isoBaseName}.iso";
type = lib.types.str; type = lib.types.str;
@ -475,12 +480,13 @@ in
}; };
isoImage.squashfsCompression = mkOption { isoImage.squashfsCompression = mkOption {
default = with pkgs.stdenv.hostPlatform; "xz -Xdict-size 100% " default = with pkgs.stdenv.hostPlatform;
"xz -Xdict-size 100% "
+ lib.optionalString isx86 "-Xbcj x86" + lib.optionalString isx86 "-Xbcj x86"
# Untested but should also reduce size for these platforms # Untested but should also reduce size for these platforms
+ lib.optionalString isAarch "-Xbcj arm" + lib.optionalString isAarch "-Xbcj arm"
+ lib.optionalString (isPower && is32bit && isBigEndian) "-Xbcj powerpc" + lib.optionalString (isPower && is32bit && isBigEndian) "-Xbcj powerpc"
+ lib.optionalString (isSparc) "-Xbcj sparc"; + lib.optionalString isSparc "-Xbcj sparc";
type = lib.types.nullOr lib.types.str; type = lib.types.nullOr lib.types.str;
description = '' description = ''
Compression settings to use for the squashfs nix store. Compression settings to use for the squashfs nix store.
@ -674,13 +680,13 @@ in
If text mode is required off-handedly (e.g. for serial use) you can use the `T` key, after being prompted, to use text mode for the current boot. If text mode is required off-handedly (e.g. for serial use) you can use the `T` key, after being prompted, to use text mode for the current boot.
''; '';
}; };
}; };
# store them in lib so we can mkImageMediaOverride the # store them in lib so we can mkImageMediaOverride the
# entire file system layout in installation media (only) # entire file system layout in installation media (only)
config.lib.isoFileSystems = { config.lib.isoFileSystems = {
"/" = mkImageMediaOverride "/" =
mkImageMediaOverride
{ {
fsType = "tmpfs"; fsType = "tmpfs";
options = ["mode=0755"]; options = ["mode=0755"];
@ -689,29 +695,37 @@ in
# Note that /dev/root is a symlink to the actual root device # Note that /dev/root is a symlink to the actual root device
# specified on the kernel command line, created in the stage 1 # specified on the kernel command line, created in the stage 1
# init script. # init script.
"/iso" = mkImageMediaOverride "/iso" =
{ device = "/dev/root"; mkImageMediaOverride
{
device = "/dev/root";
neededForBoot = true; neededForBoot = true;
noCheck = true; noCheck = true;
}; };
# In stage 1, mount a tmpfs on top of /nix/store (the squashfs # In stage 1, mount a tmpfs on top of /nix/store (the squashfs
# image) to make this a live CD. # image) to make this a live CD.
"/nix/.ro-store" = mkImageMediaOverride "/nix/.ro-store" =
{ fsType = "squashfs"; mkImageMediaOverride
{
fsType = "squashfs";
device = "/iso/nix-store.squashfs"; device = "/iso/nix-store.squashfs";
options = ["loop"]; options = ["loop"];
neededForBoot = true; neededForBoot = true;
}; };
"/nix/.rw-store" = mkImageMediaOverride "/nix/.rw-store" =
{ fsType = "tmpfs"; mkImageMediaOverride
{
fsType = "tmpfs";
options = ["mode=0755"]; options = ["mode=0755"];
neededForBoot = true; neededForBoot = true;
}; };
"/nix/store" = mkImageMediaOverride "/nix/store" =
{ fsType = "overlay"; mkImageMediaOverride
{
fsType = "overlay";
device = "overlay"; device = "overlay";
options = [ options = [
"lowerdir=/nix/.ro-store" "lowerdir=/nix/.ro-store"
@ -741,8 +755,7 @@ in
length = stringLength config.isoImage.volumeID; length = stringLength config.isoImage.volumeID;
howmany = toString length; howmany = toString length;
toomany = toString (length - 32); toomany = toString (length - 32);
in in "isoImage.volumeID ${config.isoImage.volumeID} is ${howmany} characters. That is ${toomany} characters longer than the limit of 32.";
"isoImage.volumeID ${config.isoImage.volumeID} is ${howmany} characters. That is ${toomany} characters longer than the limit of 32.";
} }
]; ];
@ -750,9 +763,9 @@ in
# here and it causes a cyclic dependency. # here and it causes a cyclic dependency.
boot.loader.grub.enable = false; boot.loader.grub.enable = false;
environment.systemPackages = [ grubPkgs.grub2 grubPkgs.grub2_efi ] environment.systemPackages =
++ optional (config.isoImage.makeBiosBootable) pkgs.syslinux [grubPkgs.grub2 grubPkgs.grub2_efi]
; ++ optional (config.isoImage.makeBiosBootable) pkgs.syslinux;
# In stage 1 of the boot, mount the CD as the root FS by label so # In stage 1 of the boot, mount the CD as the root FS by label so
# that we don't need to know its device. We pass the label of the # that we don't need to know its device. We pass the label of the
@ -762,8 +775,8 @@ in
# UUID of the USB stick. It would be nicer to write # UUID of the USB stick. It would be nicer to write
# `root=/dev/disk/by-label/...' here, but UNetbootin doesn't # `root=/dev/disk/by-label/...' here, but UNetbootin doesn't
# recognise that. # recognise that.
boot.kernelParams = boot.kernelParams = [
[ "root=LABEL=${config.isoImage.volumeID}" "root=LABEL=${config.isoImage.volumeID}"
"boot.shell_on_fail" "boot.shell_on_fail"
]; ];
@ -776,56 +789,72 @@ in
# Closures to be copied to the Nix store on the CD, namely the init # Closures to be copied to the Nix store on the CD, namely the init
# script and the top-level system configuration directory. # script and the top-level system configuration directory.
isoImage.storeContents = isoImage.storeContents =
[ config.system.build.toplevel ] ++ [config.system.build.toplevel]
optional config.isoImage.includeSystemBuildDependencies ++ optional config.isoImage.includeSystemBuildDependencies
config.system.build.toplevel.drvPath; config.system.build.toplevel.drvPath;
# Individual files to be included on the CD, outside of the Nix # Individual files to be included on the CD, outside of the Nix
# store on the CD. # store on the CD.
isoImage.contents = isoImage.contents =
[ [
{ source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile; {
source = config.boot.kernelPackages.kernel + "/" + config.system.boot.loader.kernelFile;
target = "/boot/" + config.system.boot.loader.kernelFile; target = "/boot/" + config.system.boot.loader.kernelFile;
} }
{ source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile; {
source = config.system.build.initialRamdisk + "/" + config.system.boot.loader.initrdFile;
target = "/boot/" + config.system.boot.loader.initrdFile; target = "/boot/" + config.system.boot.loader.initrdFile;
} }
{ source = pkgs.writeText "version" config.system.nixos.label; {
source = pkgs.writeText "version" config.system.nixos.label;
target = "/version.txt"; target = "/version.txt";
} }
] ++ optionals (config.isoImage.makeBiosBootable) [ ]
{ source = config.isoImage.splashImage; ++ optionals (config.isoImage.makeBiosBootable) [
{
source = config.isoImage.splashImage;
target = "/isolinux/background.png"; target = "/isolinux/background.png";
} }
{ source = pkgs.substituteAll { {
source = pkgs.substituteAll {
name = "isolinux.cfg"; name = "isolinux.cfg";
src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg; src = pkgs.writeText "isolinux.cfg-in" isolinuxCfg;
bootRoot = "/boot"; bootRoot = "/boot";
}; };
target = "/isolinux/isolinux.cfg"; target = "/isolinux/isolinux.cfg";
} }
{ source = "${pkgs.syslinux}/share/syslinux"; {
source = "${pkgs.syslinux}/share/syslinux";
target = "/isolinux"; target = "/isolinux";
} }
] ++ optionals config.isoImage.makeEfiBootable [ ]
{ source = efiImg; ++ optionals config.isoImage.makeEfiBootable [
{
source = efiImg;
target = "/boot/efi.img"; target = "/boot/efi.img";
} }
{ source = "${efiDir}/EFI"; {
source = "${efiDir}/EFI";
target = "/EFI"; target = "/EFI";
} }
{ source = (pkgs.writeTextDir "grub/loopback.cfg" "source /EFI/boot/grub.cfg") + "/grub"; {
source = (pkgs.writeTextDir "grub/loopback.cfg" "source /EFI/boot/grub.cfg") + "/grub";
target = "/boot/grub"; target = "/boot/grub";
} }
{ source = config.isoImage.efiSplashImage; {
source = config.isoImage.efiSplashImage;
target = "/EFI/boot/efi-background.png"; target = "/EFI/boot/efi-background.png";
} }
] ++ optionals (config.boot.loader.grub.memtest86.enable && config.isoImage.makeBiosBootable) [ ]
{ source = "${pkgs.memtest86plus}/memtest.bin"; ++ optionals (config.boot.loader.grub.memtest86.enable && config.isoImage.makeBiosBootable) [
{
source = "${pkgs.memtest86plus}/memtest.bin";
target = "/boot/memtest.bin"; target = "/boot/memtest.bin";
} }
] ++ optionals (config.isoImage.grubTheme != null) [ ]
{ source = config.isoImage.grubTheme; ++ optionals (config.isoImage.grubTheme != null) [
{
source = config.isoImage.grubTheme;
target = "/EFI/boot/grub-theme"; target = "/EFI/boot/grub-theme";
} }
]; ];
@ -837,19 +866,23 @@ in
inherit (config.isoImage) isoName compressImage volumeID contents; inherit (config.isoImage) isoName compressImage volumeID contents;
bootable = config.isoImage.makeBiosBootable; bootable = config.isoImage.makeBiosBootable;
bootImage = "/isolinux/isolinux.bin"; bootImage = "/isolinux/isolinux.bin";
syslinux = if config.isoImage.makeBiosBootable then pkgs.syslinux else null; syslinux =
if config.isoImage.makeBiosBootable
then pkgs.syslinux
else null;
squashfsContents = config.isoImage.storeContents; squashfsContents = config.isoImage.storeContents;
squashfsCompression = config.isoImage.squashfsCompression; squashfsCompression = config.isoImage.squashfsCompression;
} // optionalAttrs (config.isoImage.makeUsbBootable && config.isoImage.makeBiosBootable) { }
// optionalAttrs (config.isoImage.makeUsbBootable && config.isoImage.makeBiosBootable) {
usbBootable = true; usbBootable = true;
isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin"; isohybridMbrImage = "${pkgs.syslinux}/share/syslinux/isohdpfx.bin";
} // optionalAttrs config.isoImage.makeEfiBootable { }
// optionalAttrs config.isoImage.makeEfiBootable {
efiBootable = true; efiBootable = true;
efiBootImage = "boot/efi.img"; efiBootImage = "boot/efi.img";
}); });
boot.postBootCommands = boot.postBootCommands = ''
''
# After booting, register the contents of the Nix store on the # After booting, register the contents of the Nix store on the
# CD in the Nix database in the tmpfs. # CD in the Nix database in the tmpfs.
${config.nix.package.out}/bin/nix-store --load-db < /nix/store/nix-path-registration ${config.nix.package.out}/bin/nix-store --load-db < /nix/store/nix-path-registration
@ -863,7 +896,5 @@ in
# Add vfat support to the initrd to enable people to copy the # Add vfat support to the initrd to enable people to copy the
# contents of the CD to a bootable USB stick. # contents of the CD to a bootable USB stick.
boot.initrd.supportedFilesystems = ["vfat"]; boot.initrd.supportedFilesystems = ["vfat"];
}; };
} }

View File

@ -1,5 +1,4 @@
{stdenv}: {stdenv}:
stdenv.mkDerivation { stdenv.mkDerivation {
pname = "calamares-extensions-desk-os"; pname = "calamares-extensions-desk-os";
version = "0.0.1"; version = "0.0.1";