{ config, lib, ... }: with lib; let cfg = config.numbus.hardware.disks.boot; bootCount = builtins.length cfg.list; singleDiskConfig = { disko.devices.disk.main = { type = "disk"; device = head cfg.list; content = { type = cfg.partitionTableScheme; partitions = { ESP = { size = cfg.partition.boot.size; type = cfg.partition.boot.esp; content = { type = "filesystem"; format = cfg.partition.boot.filesystem; mountpoint = "/boot"; mountOptions = [ "umask=0077" ]; }; }; swap = { size = cfg.partition.swap.size; content = { type = "swap"; randomEncryption = cfg.partition.swap.encrypt; }; }; luks = { size = cfg.partition.root.size; content = { type = "luks"; name = "boot"; settings.keyFile = "/run/secrets/disks/boot"; content = { type = "filesystem"; format = cfg.partition.root.filesystem; mountpoint = "/"; }; }; }; }; }; }; }; raid1DiskConfig = { disko.devices.disk = lib.listToAttrs (lib.imap0 (i: device: { name = "boot-${toString i}"; value = { type = "disk"; inherit device; content = { type = cfg.partitionTableScheme; partitions = { ESP = { size = cfg.partition.boot.size; type = cfg.partition.boot.esp; content = { type = "mdraid"; name = "boot"; }; }; swap = { size = cfg.partition.swap.size; content = { type = "mdraid"; name = "swap"; }; }; mdadm = { size = cfg.partition.root.size; content = { type = "mdraid"; name = "raid1"; }; }; }; }; }; }) cfg.list); disko.devices.mdadm = { boot = { type = "mdadm"; level = 1; metadata = "1.0"; content = { type = "filesystem"; format = cfg.partition.boot.filesystem; mountpoint = "/boot"; mountOptions = [ "umask=0077" ]; }; }; swap = { type = "mdadm"; level = 1; content = { type = "swap"; randomEncryption = cfg.partition.swap.encrypt; }; }; raid1 = { type = "mdadm"; level = 1; content = { type = "luks"; name = "boot"; settings.keyFile = "/run/secrets/disks/boot"; content = { type = "filesystem"; format = cfg.partition.root.filesystem; mountpoint = "/"; }; }; }; }; }; in { options.numbus.hardware.disks = { boot = { list = mkOption { type = types.listOf types.str; example = [ "/dev/disk/by-id/nvme_SAMSUNG_MZVPYEHCO_159Ejz224G0000" "/dev/disk/by-id/ata-San_Disk_159Ejz224G" ]; description = "A set of by-id path of disk(s) that will be used as boot disk(s). At least one disk must be set."; }; partitionTableScheme = mkOption { type = types.enum [ "gpt" "mbr" ]; default = "gpt"; example = "gpt"; description = "The scheme of the partition table. Use \"gpt\" for modern devices and \"mbr\" for legacy ones."; }; partition = { root = { filesystem = mkOption { type = types.enum [ "ext4" "btrfs" "xfs" ]; default = "ext4"; example = "ext4"; description = "The filesystem to use for the root partition of the boot disk(s)."; }; size = mkOption { type = types.str; default = "100%"; example = "100%"; description = "The size of the root partition. Use G for GBs and M for MBs."; }; }; boot = { filesystem = mkOption { type = types.enum [ "vfat" ]; default = "vfat"; example = "vfat"; description = "The filesystem to use for the boot partition of the boot disk(s)."; }; esp = mkOption { type = types.enum [ "EF00" "EF02" ]; default = "EF00"; example = "EF00"; description = "The ESP type to use for the boot partition. Use EF02 for UEFI and EF00 for BIOS."; }; size = mkOption { type = types.str; default = "1G"; example = "1G"; description = "The size of the boot partition."; }; }; swap = { enable = mkOption { type = types.bool; default = true; example = true; description = "Wether to create a swap partition. Useful for servers that don't have a lot of RAM."; }; encrypt = mkOption { type = types.bool; default = true; example = true; description = "Wether to encrypt randomly the swap partition. Disable if you need hibernation"; }; size = mkOption { type = types.str; default = "16G"; example = "16G"; description = "Size of the swap partition. Use G for GBs and M for MBs."; }; }; }; }; }; config = mkMerge [ { sops.secrets."disks/boot" = { sopsFile = "/etc/nixos/secrets/disks/boot.yaml"; gid = "0"; uid = "0"; mode = "0400"; }; } (mkIf (bootCount == 1) singleDiskConfig) (mkIf (bootCount == 2) raid1DiskConfig) ]; }