mirror of
https://github.com/NiklasGollenstede/nixos-installer.git
synced 2025-07-19 23:36:12 +02:00
4.3 KiB
4.3 KiB
/*
Extra Boot-Partition Files
This module allows copying additional files to the boot partition when installing/updating the bootloader.
Implementation
#*/# end of MarkDown, beginning of NixOS module:
dirname: inputs: args@{ config, options, pkgs, lib, ... }: let lib = inputs.self.lib.__internal__; in let
inherit (inputs.config.rename) setup;
cfg = config.boot.loader.extra-files;
targetMount = let path = lib.findFirst (path: config.fileSystems?${path}) "/" (lib.fun.parentPaths cfg.targetDir); in config.fileSystems.${path};
supportedFSes = [ "vfat" "ntfs" "ext2" "ext3" "ext4" "btrfs" "xfs" "ufs" ]; fsSupported = fs: builtins.elem fs supportedFSes;
in {
options = { boot.loader.extra-files = {
enable = lib.mkEnableOption ''
copying of additional files to the boot partition during the system's installation and activation.
Note that this modifies the global, non-versioned bootloader state based on the last generation(s) installed / switched to, and that it only ensures the files existence, possibly overwriting previous files, but does not delete files (left by previous generations or configurations)
'';
files = lib.mkOption { description = ''
...
''; example = lib.literalExpression ''
{ "config.txt".text = lib.mkAfter "disable_splash=1";
"start4.elf".source = "${pkgs.raspberrypifw}/share/raspberrypi/boot/start4.elf";
}
''; default = { }; type = lib.types.attrsOf (lib.types.nullOr (lib.types.submodule ({ name, config, ... }: { options = {
source = lib.mkOption { description = "Source path of the file."; type = lib.types.path; };
text = lib.mkOption { description = "Text lines of the file."; default = null; type = lib.types.nullOr lib.types.lines; };
format = lib.mkOption { description = "Formatter to use to transform `.data` into `.text` lines (if `!= null`)."; default = null; type = lib.types.nullOr (lib.types.functionTo lib.types.str); };
data = lib.mkOption { description = "Data to serialize to become the files `.text`. A `.format`ter must be set for the file for this to become applicable, and the data assigned must conform to the particular formatters input requirements."; type = (pkgs.formats.json { }).type; };
}; config = {
text = lib.mkIf (config.format != null) (config.format config.data);
}; }))); apply = lib.filterAttrs (k: v: v != null); };
tree = lib.mkOption { internal = true; readOnly = true; type = lib.types.package; };
targetDir = lib.mkOption { description = ''
The where the files will be installed (copied) to. This has to be mounted when `nixos-rebuild boot/switch` gets called.
''; type = lib.types.strMatching ''^/.*[^/]$''; default = "/boot"; };
}; } // {
system.build.installBootLoader = lib.mkOption { apply = old: if !cfg.enable then old else pkgs.writeShellScript "${old.name or "install-bootloader"}-extra-files" ''
${old} "$@" || exit
shopt -s dotglob # for the rest of the script, have globs (*) also match hidden files
function copy () { # 1: src, 2: dst
cd "$1" ; for name in * ; do
if [[ -d "$1"/"$name" ]] ; then
rm "$2"/"$name" 2>/dev/null || true
mkdir -p "$2"/"$name" ; copy "$1"/"$name" "$2"/"$name"
else
if ! ${pkgs.diffutils}/bin/cmp --quiet "$1"/"$name" "$2"/"$name" ; then
cp -a "$1"/"$name" "$2"/"$name"
fi
fi
done
}
copy ${cfg.tree} ${lib.escapeShellArg cfg.targetDir}
''; };
};
config = {
# This copies referenced files to reduce the installation's closure size.
boot.loader.extra-files.tree = lib.fun.writeTextFiles pkgs "boot-files" { checkPhase = ''
${lib.concatStringsSep "\n" (lib.mapAttrsToList (path: file: ''
path=${lib.escapeShellArg path} ; mkdir -p "$( dirname "$path" )"
cp -aT ${lib.escapeShellArg file.source} "$path"
'') (lib.filterAttrs (__: _:_.text == null) cfg.files))}
''; } (lib.fun.catAttrSets "text" (lib.filterAttrs (__: _:_.text != null) cfg.files));
};
}