mirror of
https://github.com/NiklasGollenstede/nixos-installer.git
synced 2025-06-20 09:47:52 +02:00
update to 24.11, small changes
This commit is contained in:
parent
a937ebf3fc
commit
ea4d8161bb
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@ -35,8 +35,10 @@
|
||||
"bridgedifs", // virtual box
|
||||
"btrfs", // filesystem
|
||||
"builtins", // nix
|
||||
"bwrap", // program
|
||||
"cachefile", // zfs
|
||||
"canmount", // zfs
|
||||
"chardev", // qemu
|
||||
"checksumming", // word
|
||||
"compress_chksum", // f2fs
|
||||
"concat", // abbr
|
||||
@ -108,6 +110,8 @@
|
||||
"lsusb", // program / function
|
||||
"luks", // linux
|
||||
"macaddr", // cli arg
|
||||
"memdev", // qemu
|
||||
"memfd", // qemu
|
||||
"metadata_csum", // ext4 option
|
||||
"mktemp", // program / function
|
||||
"mmap", // abbr "memory map"
|
||||
@ -136,6 +140,7 @@
|
||||
"notrunc", // dd option
|
||||
"nounset", // bash
|
||||
"ntfs", // filesystem
|
||||
"numa", // abbr (non-uniform memory architecture)
|
||||
"oneshot", // systemd
|
||||
"openssh", // package
|
||||
"optimise", // B/E
|
||||
@ -185,6 +190,7 @@
|
||||
"startvm", // virtual box
|
||||
"stdenv", // nix
|
||||
"storageattach", // virtual box
|
||||
"submounts", // plural
|
||||
"swsuspend", // parameter
|
||||
"sysinit", // systemd
|
||||
"syslinux", // package
|
||||
@ -213,9 +219,11 @@
|
||||
"vboxusers", // virtual box
|
||||
"vdev", "vdevs", // zfs
|
||||
"vfat", // linux
|
||||
"vhost", // qemu
|
||||
"virt", // abbr (virtualization)
|
||||
"virtfs", // qemu / filesystem
|
||||
"virtio", // cli arg
|
||||
"virtiofs", "virtiofsd", // linux
|
||||
"virtualbox", // program
|
||||
"virtualisation", // british english
|
||||
"vmdk", // vbox
|
||||
|
@ -38,7 +38,7 @@ in { preface = { # (any »preface« options have to be defined here)
|
||||
# Example of adding and/or overwriting setup/maintenance functions:
|
||||
#installer.scripts.install-overwrite.path = ../lib/install.sh.md;
|
||||
|
||||
boot.initrd.systemd.enable = true;
|
||||
boot.initrd.systemd.enable = true; # default now
|
||||
|
||||
|
||||
}) (lib.mkIf (name == "explicit-fs") { ## Minimal explicit FS setup
|
||||
|
20
flake.lock
generated
20
flake.lock
generated
@ -3,11 +3,11 @@
|
||||
"config": {
|
||||
"locked": {
|
||||
"dir": "example/defaultConfig",
|
||||
"lastModified": 1721833083,
|
||||
"narHash": "sha256-4b0AkgAv/SLb9JHxwY9j+sF9Xpo/AQvJr5RishgToj8=",
|
||||
"lastModified": 1729801154,
|
||||
"narHash": "sha256-4zx8zYm+ddExG1+D6Om1V43Y4SsOULUlyEfxAyAZhsM=",
|
||||
"owner": "NiklasGollenstede",
|
||||
"repo": "nixos-installer",
|
||||
"rev": "95aa2619872f50ceb7f8f198e9d4c2bf2f9ddce1",
|
||||
"rev": "a937ebf3fcf9953a8b9e47b379639c0aeb08f311",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -24,11 +24,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1724670824,
|
||||
"narHash": "sha256-nVq1funYyVken7nsZT6SWA6dSkobnFEyZM27SuwShGM=",
|
||||
"lastModified": 1728847189,
|
||||
"narHash": "sha256-UZzhxwURaYl7CP8NnoWsfunT+vZD8Odym7uQ09KZhR0=",
|
||||
"owner": "NiklasGollenstede",
|
||||
"repo": "nix-functions",
|
||||
"rev": "f3d4f9d64a5019cf8496068f6515fdd0076ed1dd",
|
||||
"rev": "5dac6b54b60985e3da124e79afc28525b1d693c4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -39,16 +39,16 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1724316499,
|
||||
"narHash": "sha256-Qb9MhKBUTCfWg/wqqaxt89Xfi6qTD3XpTzQ9eXi3JmE=",
|
||||
"lastModified": 1733808091,
|
||||
"narHash": "sha256-KWwINTQelKOoQgrXftxoqxmKFZb9pLVfnRvK270nkVk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "797f7dc49e0bc7fab4b57c021cdf68f595e47841",
|
||||
"rev": "a0f3e10d94359665dba45b71b4227b0aeb851f8e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-24.05",
|
||||
"ref": "nixos-24.11",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"Fully automated NixOS CLI installer"
|
||||
); inputs = {
|
||||
|
||||
nixpkgs = { url = "github:NixOS/nixpkgs/nixos-24.05"; };
|
||||
nixpkgs = { url = "github:NixOS/nixpkgs/nixos-24.11"; };
|
||||
functions = { url = "github:NiklasGollenstede/nix-functions"; inputs.nixpkgs.follows = "nixpkgs"; };
|
||||
config.url = "github:NiklasGollenstede/nixos-installer?dir=example/defaultConfig"; # "path:./example/defaultConfig"; # (The latter only works on each host after using this flake directly (not as dependency or another flake). The former effectively points to the last commit, i.e. it takes two commits to apply changes to the default config.)
|
||||
|
||||
|
@ -12,7 +12,7 @@ dirname: inputs@{ self, nixpkgs, functions, ...}: let
|
||||
) else module;
|
||||
|
||||
getPreface = inputs: moduleArgs: mainModule: name: let
|
||||
args = { config = null; pkgs = null; lib = null; name = null; nodes = null; extraModules = null; } // { inherit inputs; } // moduleArgs // { name = name; };
|
||||
args = { config = null; pkgs = null; lib = null; utils = null; name = null; nodes = null; extraModules = null; } // { inherit inputs; } // moduleArgs // { name = name; };
|
||||
config = getModuleConfig mainModule inputs args;
|
||||
in config.${preface'} or { };
|
||||
|
||||
@ -52,7 +52,7 @@ in rec {
|
||||
# There is, unfortunately, no way to directly pass modules into all containers. Each container will need to be defined with »config.containers."${name}".config.imports = extraModules«.
|
||||
# (One could do that automatically by defining »options.security.containers = lib.mkOption { type = lib.types.submodule (cfg: { options.config = lib.mkOption { apply = _:_.extendModules { modules = extraModules; }; }); }«.)
|
||||
|
||||
nixpkgs = { overlays = overlays; } // (lib.optionalAttrs (buildPlatform != null) { inherit buildPlatform; });
|
||||
nixpkgs = { overlays = lib.mkBefore overlays; } // (lib.optionalAttrs (buildPlatform != null) { inherit buildPlatform; });
|
||||
|
||||
_module.args = { inherit inputs; } // moduleArgs; # (pass the args here, so that they also apply to any other evaluation using »extraModules«)
|
||||
|
||||
|
@ -163,7 +163,10 @@ function run-qemu { # ...: qemuArgs
|
||||
if [[ ${args[dry-run]:-} ]] ; then
|
||||
echo "${qemu[@]}"
|
||||
else
|
||||
( set -x ; "${qemu[@]}" ) || return
|
||||
echo + "${qemu[@]}" ; for _ in $( seq $( @{native.ncurses}/bin/tput lines ) ) ; do echo ; done
|
||||
#sleep 5
|
||||
#sleep 9999999
|
||||
"${qemu[@]}" || return
|
||||
fi
|
||||
|
||||
# https://askubuntu.com/questions/54814/how-can-i-ctrl-alt-f-to-get-to-a-tty-in-a-qemu-session
|
||||
|
@ -4,6 +4,9 @@
|
||||
|
||||
This module allows copying additional files to the boot partition when installing/updating the bootloader.
|
||||
|
||||
There is `boot.loader.systemd-boot/grub.extraFiles`, but at least the implementations are awful (systemd's first deletes all old files, then copies them all again; grub's simply overwrites its files every time, ignoring old files).
|
||||
|
||||
To delete previous files, one could: have a list of old files, read that as keys of a named array, add the to-be-installed files to the list of (potential) old files, install the new files and meanwhile remove each one installed from the array, delete all files left in the array (if they exist), write (only) the installed files to the list of (next time) old files.
|
||||
|
||||
## Implementation
|
||||
|
||||
@ -39,6 +42,7 @@ in {
|
||||
|
||||
tree = lib.mkOption { internal = true; readOnly = true; type = lib.types.package; };
|
||||
|
||||
# Each bootloader seems to keep an option like this separately ...
|
||||
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"; };
|
||||
|
@ -31,12 +31,13 @@ dirname: inputs: { config, pkgs, lib, utils, ... }: let lib = inputs.self.lib.__
|
||||
inherit (inputs.config.rename) setup installer;
|
||||
cfg = config.${setup}.keystore;
|
||||
hash = builtins.substring 0 8 (builtins.hashString "sha256" config.networking.hostName);
|
||||
keystore = "/run/keystore-${hash}";
|
||||
keystoreKeys = lib.attrValues (lib.filterAttrs (n: v: lib.fun.startsWith "luks/keystore-${hash}/" n) cfg.keys);
|
||||
keystore = "/run/${cfg.name}";
|
||||
keystoreKeys = lib.attrValues (lib.filterAttrs (n: v: lib.fun.startsWith "luks/${cfg.name}/" n) cfg.keys);
|
||||
in let module = {
|
||||
|
||||
options = { ${setup}.keystore = {
|
||||
enable = lib.mkEnableOption "the use of a keystore partition to unlock various things during early boot";
|
||||
name = lib.mkOption { type = lib.types.str; readOnly = true; default = "keystore-${hash}"; };
|
||||
enableLuksGeneration = (lib.mkEnableOption "the generation of a LUKS mapper configuration for each »luks/*/0« entry in ».keys«") // { default = true; example = false; };
|
||||
keys = lib.mkOption { description = "Keys declared to be generated during installation and then exist in the keystore for unlocking disks and such. See »${dirname}/keystore.nix.md« for much more information."; type = lib.types.attrsOf (lib.types.either (lib.types.nullOr lib.types.str) (lib.types.attrsOf lib.types.str)); default = { }; apply = keys: (
|
||||
lib.fun.mapMergeUnique (usage: methods: if methods == null then { } else if builtins.isString methods then { "${usage}" = methods; } else lib.fun.mapMerge (slot: method: if method == null then { } else { "${usage}/${slot}" = method; }) methods) keys
|
||||
@ -52,10 +53,10 @@ in let module = {
|
||||
config = let
|
||||
in lib.mkIf (cfg.enable) (lib.mkMerge [ ({
|
||||
|
||||
${setup}.keystore.keys."luks/keystore-${hash}/0" = lib.mkOptionDefault "hostname"; # (This is the only key that the setup scripts unconditionally require to be declared.)
|
||||
${setup}.keystore.keys."luks/${cfg.name}/0" = lib.mkOptionDefault "hostname"; # (This is the only key that the setup scripts unconditionally require to be declared.)
|
||||
assertions = [ {
|
||||
assertion = cfg.keys?"luks/keystore-${hash}/0";
|
||||
message = ''At least one key (»0«) for »luks/keystore-${hash}« must be specified!'';
|
||||
assertion = cfg.keys?"luks/${cfg.name}/0";
|
||||
message = ''At least one key (»0«) for »luks/${cfg.name}« must be specified!'';
|
||||
} ];
|
||||
|
||||
}) ({ ## Declare LUKS devices for all LUKS keys:
|
||||
@ -66,13 +67,13 @@ in let module = {
|
||||
label = builtins.substring 5 ((builtins.stringLength key) - 7) key;
|
||||
in { ${label} = {
|
||||
device = lib.mkDefault "/dev/disk/by-partlabel/${label}";
|
||||
keyFile = lib.mkIf (label != "keystore-${hash}") (lib.mkDefault "/run/keystore-${hash}/luks/${label}/0.key");
|
||||
keyFile = lib.mkIf (label != cfg.name) (lib.mkDefault "/run/${cfg.name}/luks/${label}/0.key");
|
||||
allowDiscards = lib.mkDefault true; # If attackers can observe trimmed blocks, then they can probably do much worse ...
|
||||
}; }) (lib.fun.filterMatching ''^luks/.*/0$'' (lib.attrNames cfg.keys)));
|
||||
|
||||
boot.initrd.systemd.services = lib.mkIf (config.boot.initrd.systemd.enable) (lib.fun.mapMerge (key: let
|
||||
label = builtins.substring 5 ((builtins.stringLength key) - 7) key;
|
||||
in if label == "keystore-${hash}" || (!config.boot.initrd.luks.devices?${label}) then { } else { "systemd-cryptsetup@${utils.escapeSystemdPath label}" = rec {
|
||||
in if label == cfg.name || (!config.boot.initrd.luks.devices?${label}) then { } else { "systemd-cryptsetup@${utils.escapeSystemdPath label}" = rec {
|
||||
overrideStrategy = "asDropin"; # (could this be set via a x-systemd.after= crypttab option?)
|
||||
after = [ "systemd-cryptsetup@keystore\\x2d${hash}.service" ]; wants = after; # (this may be implicit if systemd knew about the /run/keystore-... mount point)
|
||||
}; }) (lib.fun.filterMatching ''^luks/.*/0$'' (lib.attrNames cfg.keys)));
|
||||
@ -80,11 +81,11 @@ in let module = {
|
||||
|
||||
}) ({ ## Create and populate keystore during installation:
|
||||
|
||||
fileSystems.${keystore} = { fsType = "vfat"; device = "/dev/mapper/keystore-${hash}"; options = [ "ro" "nosuid" "nodev" "noexec" "noatime" "umask=0277" "noauto" ]; formatArgs = [ ]; };
|
||||
fileSystems.${keystore} = { fsType = "vfat"; device = "/dev/mapper/${cfg.name}"; options = [ "ro" "nosuid" "nodev" "noexec" "noatime" "umask=0277" "noauto" ]; formatArgs = [ ]; };
|
||||
|
||||
${setup}.disks.partitions."keystore-${hash}" = { type = lib.mkDefault "8309"; order = lib.mkDefault 1375; disk = lib.mkDefault "primary"; size = lib.mkDefault "32M"; };
|
||||
${setup}.disks.partitions.${cfg.name} = { type = lib.mkDefault "8309"; order = lib.mkDefault 1375; disk = lib.mkDefault "primary"; size = lib.mkDefault "32M"; };
|
||||
${installer}.commands.postFormat = ''( : 'Copy the live keystore to its primary persistent location:'
|
||||
tmp=$(mktemp -d) && ${pkgs.util-linux}/bin/mount "/dev/mapper/keystore-${hash}" $tmp && trap "${pkgs.util-linux}/bin/umount $tmp && rmdir $tmp" EXIT &&
|
||||
tmp=$(mktemp -d) && ${pkgs.util-linux}/bin/mount "/dev/mapper/${cfg.name}" $tmp && trap "${pkgs.util-linux}/bin/umount $tmp && rmdir $tmp" EXIT &&
|
||||
${pkgs.rsync}/bin/rsync -a ${keystore}/ $tmp/
|
||||
)'';
|
||||
|
||||
@ -93,7 +94,7 @@ in let module = {
|
||||
}) (lib.mkIf (!(config.virtualisation.useDefaultFilesystems or false)) (let # (don't bother with any of this if »boot.initrd.luks.devices« is forced to »{ }« in »nixos/modules/virtualisation/qemu-vm.nix«)
|
||||
in lib.mkMerge [ ({
|
||||
|
||||
boot.initrd.luks.devices."keystore-${hash}".keyFile = lib.mkMerge [
|
||||
boot.initrd.luks.devices.${cfg.name}.keyFile = lib.mkMerge [
|
||||
(lib.mkIf (cfg.unlockMethods.trivialHostname) "${pkgs.writeText "hostname" config.networking.hostName}")
|
||||
(lib.mkIf (cfg.unlockMethods.usbPartition) "/dev/disk/by-partlabel/bootkey-${hash}")
|
||||
];
|
||||
@ -103,28 +104,21 @@ in let module = {
|
||||
|
||||
}) (lib.mkIf (!config.boot.initrd.systemd.enable) { # Legacy initrd
|
||||
|
||||
boot.initrd.luks.devices."keystore-${hash}" = {
|
||||
boot.initrd.luks.devices.${cfg.name} = {
|
||||
preLVM = true; # ensure the keystore is opened early (»preLVM« also seems to be pre zpool import, and it is the only option that affects the opening order)
|
||||
preOpenCommands = lib.mkIf (cfg.unlockMethods.pinThroughYubikey) verbose.doOpenWithYubikey; # TODO: required?
|
||||
fallbackToPassword = true; # (might as well)
|
||||
postOpenCommands = ''
|
||||
echo "Mounting ${keystore}"
|
||||
mkdir -p ${keystore}
|
||||
mount -o nodev,umask=0277,ro /dev/mapper/keystore-${hash} ${keystore}
|
||||
mount -o nodev,umask=0277,ro /dev/mapper/${cfg.name} ${keystore}
|
||||
'';
|
||||
};
|
||||
|
||||
boot.initrd.postMountCommands = ''
|
||||
${if (lib.any (lib.fun.matches "^home/.*$") (lib.attrNames cfg.keys)) then ''
|
||||
echo "Transferring home key composites"
|
||||
# needs to be available later to unlock the home on demand
|
||||
mkdir -p /run/keys/home-composite/ ; chmod 551 /run/keys/home-composite/ ; cp -a ${keystore}/home/*.key /run/keys/home-composite/
|
||||
for name in "$(ls /run/keys/home-composite/)" ; do chown "''${name:0:(-4)}": /run/keys/home-composite/"$name" ; done
|
||||
'' else ""}
|
||||
|
||||
echo "Closing ${keystore}"
|
||||
umount ${keystore} ; rmdir ${keystore}
|
||||
cryptsetup close /dev/mapper/keystore-${hash}
|
||||
cryptsetup close /dev/mapper/${cfg.name}
|
||||
'';
|
||||
|
||||
boot.initrd.luks.yubikeySupport = lib.mkIf (cfg.unlockMethods.pinThroughYubikey) true;
|
||||
@ -136,17 +130,17 @@ in let module = {
|
||||
}) (lib.mkIf (config.boot.initrd.systemd.enable) (let # Systemd initrd
|
||||
|
||||
unlockWithYubikey = pkgs.writeShellScript "unlock-keystore" (let
|
||||
dev = config.boot.initrd.luks.devices."keystore-${hash}";
|
||||
dev = config.boot.initrd.luks.devices.${cfg.name};
|
||||
in ''
|
||||
${verbose.tryYubikey}
|
||||
${lib.optionalString (dev.keyFile != null) ''
|
||||
if systemd-cryptsetup attach 'keystore-${hash}' '/dev/disk/by-partlabel/keystore-${hash}' ${lib.escapeShellArg dev.keyFile} '${lib.optionalString dev.allowDiscards "discard,"}headless' ; then exit ; fi
|
||||
printf '%s\n\n' 'Unlocking keystore-${hash} with '${lib.escapeShellArg dev.keyFile}' failed.' >/dev/console
|
||||
if systemd-cryptsetup attach '${cfg.name}' '/dev/disk/by-partlabel/${cfg.name}' ${lib.escapeShellArg dev.keyFile} '${lib.optionalString dev.allowDiscards "discard,"}headless' ; then exit ; fi
|
||||
printf '%s\n\n' 'Unlocking ${cfg.name} with '${lib.escapeShellArg dev.keyFile}' failed.' >/dev/console
|
||||
''}
|
||||
for attempt in "" 2 3 ; do (
|
||||
passphrase=$( systemd-ask-password 'Please enter passphrase for disk keystore-${hash}'"''${attempt:+ (attempt $attempt/3)}" ) || exit
|
||||
passphrase=$( systemd-ask-password 'Please enter passphrase for disk ${cfg.name}'"''${attempt:+ (attempt $attempt/3)}" ) || exit
|
||||
passphrase="$( tryYubikey "$passphrase" 2>/dev/console )" || exit
|
||||
systemd-cryptsetup attach 'keystore-${hash}' '/dev/disk/by-partlabel/keystore-${hash}' <( printf %s "$passphrase" ) '${lib.optionalString dev.allowDiscards "discard,"}headless' || exit
|
||||
systemd-cryptsetup attach '${cfg.name}' '/dev/disk/by-partlabel/${cfg.name}' <( printf %s "$passphrase" ) '${lib.optionalString dev.allowDiscards "discard,"}headless' || exit
|
||||
) && break ; done || exit
|
||||
'');
|
||||
in {
|
||||
@ -157,23 +151,16 @@ in let module = {
|
||||
postStart = ''
|
||||
echo "Mounting ${keystore}"
|
||||
mkdir -p ${keystore}
|
||||
mount -o nodev,umask=0277,ro /dev/mapper/keystore-${hash} ${keystore}
|
||||
mount -o nodev,umask=0277,ro /dev/mapper/${cfg.name} ${keystore}
|
||||
'';
|
||||
};
|
||||
# lib.mkIf (lib.any (lib.fun.matches "^home/.*$") (lib.attrNames cfg.keys))
|
||||
initrd-nixos-activation.postStart = ''
|
||||
mkdir -pm 551 /sysroot/run/keys/home-composite/
|
||||
if [[ -e ${keystore}/home/ ]] ; then
|
||||
cp -a ${keystore}/home/*.key /sysroot/run/keys/home-composite/
|
||||
fi
|
||||
'';
|
||||
initrd-cleanup.preStart = ''
|
||||
umount ${keystore} || true
|
||||
rmdir ${keystore} || true
|
||||
systemd-cryptsetup detach keystore-${hash}
|
||||
systemd-cryptsetup detach ${cfg.name}
|
||||
'';
|
||||
};
|
||||
boot.initrd.luks.devices."keystore-${hash}".keyFileTimeout = 10;
|
||||
boot.initrd.luks.devices.${cfg.name}.keyFileTimeout = 10;
|
||||
boot.initrd.systemd.storePaths = lib.mkIf (cfg.unlockMethods.pinThroughYubikey) [ unlockWithYubikey ];
|
||||
boot.initrd.systemd.initrdBin = lib.mkIf (cfg.unlockMethods.pinThroughYubikey) [ pkgs.yubikey-personalization ];
|
||||
|
||||
@ -241,7 +228,7 @@ in let module = {
|
||||
doOpenWithYubikey = (let
|
||||
inherit (lib) optionalString;
|
||||
inherit (config.boot.initrd) luks;
|
||||
inherit (config.boot.initrd.luks.devices."keystore-${hash}") name device header keyFile keyFileSize keyFileOffset allowDiscards yubikey gpgCard fido2 fallbackToPassword;
|
||||
inherit (config.boot.initrd.luks.devices.${cfg.name}) name device header keyFile keyFileSize keyFileOffset allowDiscards yubikey gpgCard fido2 fallbackToPassword;
|
||||
cs-open = "cryptsetup luksOpen ${device} ${name} ${optionalString allowDiscards "--allow-discards"} ${optionalString (header != null) "--header=${header}"}";
|
||||
in ''
|
||||
${tryYubikey}
|
||||
|
@ -271,7 +271,7 @@ in {
|
||||
pool = builtins.head (builtins.split "/" cfg.temp.zfs.dataset);
|
||||
in {
|
||||
|
||||
boot.initrd.postDeviceCommands = lib.mkIf (!config.boot.initrd.systemd.enable) (lib.mkAfter ''
|
||||
boot.initrd.postResumeCommands = lib.mkIf (!config.boot.initrd.systemd.enable) (lib.mkAfter ''
|
||||
echo '${description}'
|
||||
( ${command} )
|
||||
'');
|
||||
|
@ -108,7 +108,7 @@ in let module = {
|
||||
in {
|
||||
${setup}.zfs.extraInitrdPools = keystorePools;
|
||||
|
||||
boot.initrd.postDeviceCommands = lib.mkIf (!config.boot.initrd.systemd.enable) (lib.mkAfter ''
|
||||
boot.initrd.postResumeCommands = lib.mkIf (!config.boot.initrd.systemd.enable) (lib.mkAfter ''
|
||||
${lib.concatStringsSep "\n" (map verbose.initrd-import-zpool cfg.extraInitrdPools)}
|
||||
${verbose.initrd-load-keys}
|
||||
'');
|
||||
@ -127,41 +127,12 @@ in let module = {
|
||||
}) (lib.mkIf (config.boot.resumeDevice == "") { ## Disallow hibernation without fixed »resumeDevice«:
|
||||
|
||||
boot.kernelParams = [ "nohibernate" "hibernate=no" ];
|
||||
assertions = [ { # Ensure that none is overriding the above:
|
||||
assertions = [ { # Ensure that no one is overriding the above:
|
||||
assertion = builtins.elem "nohibernate" config.boot.kernelParams;
|
||||
message = ''Hibernation with ZFS (and NixOS' initrd) without fixed »resumeDevice« can/will lead to pool corruption. Disallow it by setting »boot.kernelParams = [ "nohibernate" ]«'';
|
||||
} ];
|
||||
|
||||
|
||||
}) (lib.mkIf (false && (config.boot.resumeDevice != "")) { ## Make resuming after hibernation safe with ZFS:
|
||||
# or not: https://github.com/NixOS/nixpkgs/commit/c70f0473153c63ad1cf6fbea19f290db6b15291f
|
||||
|
||||
boot.kernelParams = [ "resume=${config.boot.resumeDevice}" ];
|
||||
assertions = [ { # Just making sure ...
|
||||
assertion = builtins.elem "resume=${config.boot.resumeDevice}" config.boot.kernelParams;
|
||||
message = "When using ZFS and not disabling hibernation, make sure to set the »resume=« kernel parameter!";
|
||||
} ];
|
||||
|
||||
boot.initrd.postDeviceCommands = let
|
||||
inherit (config.system.build) extraUtils;
|
||||
in (lib.mkBefore ''
|
||||
# After hibernation, the pools MUST NOT be imported before resuming, as doing so can corrupt them.
|
||||
# NixOS' mess of an initrd script does resuming after mounting FSs (which seems very unnecessarily late, resuming from a "file" doesn't need the FS to be mounted, does it?).
|
||||
# This should generally run after all (also mapped) devices are created, but before any ZFS action, so do the hibernation resume here.
|
||||
# But also only support a fixed »resumeDevice«. No guessing:
|
||||
|
||||
resumeInfo="$(udevadm info -q property "${config.boot.resumeDevice}" )"
|
||||
if [ "$(echo "$resumeInfo" | sed -n 's/^ID_FS_TYPE=//p')" = "swsuspend" ]; then
|
||||
resumeMajor="$(echo "$resumeInfo" | sed -n 's/^MAJOR=//p')"
|
||||
resumeMinor="$(echo "$resumeInfo" | sed -n 's/^MINOR=//p')"
|
||||
echo -n "Attempting to resume from hibernation (device $resumeMajor:$resumeMinor as ${config.boot.resumeDevice}) ..."
|
||||
echo "$resumeMajor:$resumeMinor" > /sys/power/resume 2> /dev/null || echo "failed to wake from hibernation, continuing normal boot!"
|
||||
fi
|
||||
'');
|
||||
#setsid ${extraUtils}/bin/ash -c "exec ${extraUtils}/bin/ash < /dev/$console >/dev/$console 2>/dev/$console"
|
||||
boot.zfs = if (options.boot.zfs?allowHibernation) then { allowHibernation = true; } else { };
|
||||
|
||||
|
||||
}) (let ## Implement »cfg.pools.*.autoApplyDuringBoot« and »cfg.pools.*.autoApplyOnActivation«:
|
||||
|
||||
inherit (config.system.build) extraUtils;
|
||||
@ -212,7 +183,7 @@ in let module = {
|
||||
}); };
|
||||
in {
|
||||
|
||||
boot.initrd.postDeviceCommands = lib.mkIf (!config.boot.initrd.systemd.enable) (lib.mkIf (anyPool "autoApplyDuringBoot") (lib.mkOrder 2000 ''
|
||||
boot.initrd.postResumeCommands = lib.mkIf (!config.boot.initrd.systemd.enable) (lib.mkIf (anyPool "autoApplyDuringBoot") (lib.mkOrder 2000 ''
|
||||
${ensure-datasets-for "autoApplyDuringBoot" extraUtils extraUtils}
|
||||
''));
|
||||
boot.initrd.systemd.services = lib.mkIf (config.boot.initrd.systemd.enable) (lib.fun.mapMerge (pool: ensure-datasets-service pool true) (lib.attrValues cfg.pools));
|
||||
|
Loading…
x
Reference in New Issue
Block a user