wip vno1-oh2
This commit is contained in:
6
modules/base/README.md
Normal file
6
modules/base/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
## From https://github.com/ne9z/dotfiles-flake, branch openzfs-guide
|
||||
|
||||
857dea48debb4d45021b4005784919e96e63cc4a
|
||||
|
||||
boot/
|
||||
fileSystems/
|
||||
171
modules/base/boot/default.nix
Normal file
171
modules/base/boot/default.nix
Normal file
@@ -0,0 +1,171 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.zfs-root.boot;
|
||||
inherit (lib) mkIf types mkDefault mkOption mkMerge strings;
|
||||
inherit (builtins) head toString map tail;
|
||||
in {
|
||||
options.zfs-root.boot = {
|
||||
enable = mkOption {
|
||||
description = "Enable root on ZFS support";
|
||||
type = types.bool;
|
||||
default = false; # TODO: change by @motiejus
|
||||
};
|
||||
devNodes = mkOption {
|
||||
description = "Specify where to discover ZFS pools";
|
||||
type = types.str;
|
||||
apply = x:
|
||||
assert (strings.hasSuffix "/" x
|
||||
|| abort "devNodes '${x}' must have trailing slash!"); x;
|
||||
default = "/dev/disk/by-id/";
|
||||
};
|
||||
bootDevices = mkOption {
|
||||
description = "Specify boot devices";
|
||||
type = types.nonEmptyListOf types.str;
|
||||
};
|
||||
availableKernelModules = mkOption {
|
||||
type = types.nonEmptyListOf types.str;
|
||||
default = ["uas" "nvme" "ahci"];
|
||||
};
|
||||
kernelParams = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
};
|
||||
immutable = mkOption {
|
||||
description = "Enable root on ZFS immutable root support";
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
removableEfi = mkOption {
|
||||
description = "install bootloader to fallback location";
|
||||
type = types.bool;
|
||||
default = true;
|
||||
};
|
||||
partitionScheme = mkOption {
|
||||
default = {
|
||||
biosBoot = "-part5";
|
||||
efiBoot = "-part1";
|
||||
swap = "-part4";
|
||||
bootPool = "-part2";
|
||||
rootPool = "-part3";
|
||||
};
|
||||
description = "Describe on disk partitions";
|
||||
type = types.attrsOf types.str;
|
||||
};
|
||||
sshUnlock = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
};
|
||||
authorizedKeys = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf (cfg.enable) (mkMerge [
|
||||
{
|
||||
zfs-root.fileSystems.datasets = {
|
||||
"rpool/nixos/home" = mkDefault "/home";
|
||||
"rpool/nixos/var/lib" = mkDefault "/var/lib";
|
||||
"rpool/nixos/var/log" = mkDefault "/var/log";
|
||||
"rpool/nixos/nix" = mkDefault "/nix";
|
||||
"bpool/nixos/root" = "/boot";
|
||||
};
|
||||
}
|
||||
(mkIf (!cfg.immutable) {
|
||||
zfs-root.fileSystems.datasets = {"rpool/nixos/root" = "/";};
|
||||
})
|
||||
(mkIf cfg.immutable {
|
||||
zfs-root.fileSystems = {
|
||||
datasets = {
|
||||
"rpool/nixos/empty" = "/";
|
||||
"rpool/nixos/root" = "/oldroot";
|
||||
};
|
||||
bindmounts = {
|
||||
"/oldroot/nix" = "/nix";
|
||||
"/oldroot/etc/nixos" = "/etc/nixos";
|
||||
};
|
||||
};
|
||||
boot.initrd.postDeviceCommands = ''
|
||||
if ! grep -q zfs_no_rollback /proc/cmdline; then
|
||||
zpool import -N rpool
|
||||
zfs rollback -r rpool/nixos/empty@start
|
||||
zpool export -a
|
||||
fi
|
||||
'';
|
||||
})
|
||||
{
|
||||
zfs-root.fileSystems = {
|
||||
efiSystemPartitions =
|
||||
map (diskName: diskName + cfg.partitionScheme.efiBoot)
|
||||
cfg.bootDevices;
|
||||
swapPartitions =
|
||||
map (diskName: diskName + cfg.partitionScheme.swap) cfg.bootDevices;
|
||||
};
|
||||
boot = {
|
||||
kernelPackages =
|
||||
mkDefault config.boot.zfs.package.latestCompatibleLinuxPackages;
|
||||
initrd.availableKernelModules = cfg.availableKernelModules;
|
||||
kernelParams = cfg.kernelParams;
|
||||
supportedFilesystems = ["zfs"];
|
||||
zfs = {
|
||||
devNodes = cfg.devNodes;
|
||||
forceImportRoot = mkDefault false;
|
||||
};
|
||||
loader = {
|
||||
efi = {
|
||||
canTouchEfiVariables =
|
||||
if cfg.removableEfi
|
||||
then false
|
||||
else true;
|
||||
efiSysMountPoint =
|
||||
"/boot/efis/"
|
||||
+ (head cfg.bootDevices)
|
||||
+ cfg.partitionScheme.efiBoot;
|
||||
};
|
||||
generationsDir.copyKernels = true;
|
||||
grub = {
|
||||
enable = true;
|
||||
devices = map (diskName: cfg.devNodes + diskName) cfg.bootDevices;
|
||||
efiInstallAsRemovable = cfg.removableEfi;
|
||||
copyKernels = true;
|
||||
efiSupport = true;
|
||||
zfsSupport = true;
|
||||
extraInstallCommands = toString (map (diskName: ''
|
||||
set -x
|
||||
${pkgs.coreutils-full}/bin/cp -r ${config.boot.loader.efi.efiSysMountPoint}/EFI /boot/efis/${diskName}${cfg.partitionScheme.efiBoot}
|
||||
set +x
|
||||
'') (tail cfg.bootDevices));
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
(mkIf cfg.sshUnlock.enable {
|
||||
boot.initrd = {
|
||||
network = {
|
||||
enable = true;
|
||||
ssh = {
|
||||
enable = true;
|
||||
hostKeys = [
|
||||
"/var/lib/ssh_unlock_zfs_ed25519_key"
|
||||
"/var/lib/ssh_unlock_zfs_rsa_key"
|
||||
];
|
||||
authorizedKeys = cfg.sshUnlock.authorizedKeys;
|
||||
};
|
||||
# FIXME vendored change by motiejus
|
||||
#postCommands = ''
|
||||
# tee -a /root/.profile >/dev/null <<EOF
|
||||
# if zfs load-key rpool/nixos; then
|
||||
# pkill zfs
|
||||
# fi
|
||||
# exit
|
||||
# EOF'';
|
||||
};
|
||||
};
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -5,7 +5,9 @@
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
./boot
|
||||
./initrd
|
||||
./fileSystems
|
||||
./snapshot
|
||||
./sshd
|
||||
./unitstatus
|
||||
|
||||
72
modules/base/fileSystems/default.nix
Normal file
72
modules/base/fileSystems/default.nix
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.zfs-root.fileSystems;
|
||||
inherit (lib) mkIf types mkDefault mkOption mkMerge mapAttrsToList;
|
||||
in {
|
||||
options.zfs-root.fileSystems = {
|
||||
datasets = mkOption {
|
||||
description = "Set mountpoint for datasets";
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
};
|
||||
bindmounts = mkOption {
|
||||
description = "Set mountpoint for bindmounts";
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
};
|
||||
efiSystemPartitions = mkOption {
|
||||
description = "Set mountpoint for efi system partitions";
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
};
|
||||
swapPartitions = mkOption {
|
||||
description = "Set swap partitions";
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
};
|
||||
};
|
||||
config.fileSystems = mkMerge (mapAttrsToList (dataset: mountpoint: {
|
||||
"${mountpoint}" = {
|
||||
device = "${dataset}";
|
||||
fsType = "zfs";
|
||||
options = ["X-mount.mkdir" "noatime"];
|
||||
neededForBoot = true;
|
||||
};
|
||||
})
|
||||
cfg.datasets
|
||||
++ mapAttrsToList (bindsrc: mountpoint: {
|
||||
"${mountpoint}" = {
|
||||
device = "${bindsrc}";
|
||||
fsType = "none";
|
||||
options = ["bind" "X-mount.mkdir" "noatime"];
|
||||
};
|
||||
})
|
||||
cfg.bindmounts
|
||||
++ map (esp: {
|
||||
"/boot/efis/${esp}" = {
|
||||
device = "${config.zfs-root.boot.devNodes}${esp}";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"x-systemd.idle-timeout=1min"
|
||||
"x-systemd.automount"
|
||||
"noauto"
|
||||
"nofail"
|
||||
"noatime"
|
||||
"X-mount.mkdir"
|
||||
];
|
||||
};
|
||||
})
|
||||
cfg.efiSystemPartitions);
|
||||
config.swapDevices = mkDefault (map (swap: {
|
||||
device = "${config.zfs-root.boot.devNodes}${swap}";
|
||||
discardPolicy = mkDefault "both";
|
||||
randomEncryption = {
|
||||
enable = true;
|
||||
allowDiscards = mkDefault true;
|
||||
};
|
||||
})
|
||||
cfg.swapPartitions);
|
||||
}
|
||||
Reference in New Issue
Block a user