{ config, lib, pkgs, ... }: with lib; let cfg = config.numbus.hardware.disks.content; contentCount = builtins.length cfg.list; parityCount = builtins.length config.numbus.hardware.disks.parity.list; contentDisks = lib.imap0 (i: device: { name = "content-${toString i}"; value = { type = "disk"; inherit device; content = { type = cfg.partitionTableScheme; partitions.luks = { size = cfg.partition.size; content = { type = "luks"; name = "content-${toString i}"; settings.keyFile = "/run/secrets/disks/content-${toString i}"; initrdUnlock = false; content = { type = "filesystem"; format = cfg.partition.filesystem; mountpoint = "/mnt/content-${toString i}"; mountOptions = [ "noauto" "nofail" ]; }; }; }; }; }; }) cfg.list; in { options.numbus.hardware.disks = { content = { list = mkOption { type = types.listOf types.str; example = [ "/dev/disk/by-id/ata_Hitachi_MZVPYEHCO_159Ejz224G0000" "/dev/disk/by-id/ata-WD_159Ejz224G" ]; default = []; description = "A set of by-id path of disk(s) that will be used as content disk(s)."; }; 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 = { filesystem = mkOption { type = types.enum [ "ext4" "btrfs" "xfs" ]; default = "xfs"; example = "xfs"; description = "The filesystem to use for the main partition of the content disk(s)."; }; size = mkOption { type = types.str; default = "100%"; example = "100%"; description = "The size of the main partition. Use G for GBs and M for MBs."; }; }; }; }; config = mkIf (contentCount > 0 && (parityCount != 1 && contentCount != 1)) { disko.devices.disk = builtins.listToAttrs contentDisks; sops.secrets = listToAttrs (map (i: nameValuePair "disks/content-${toString i}" { sopsFile = "/etc/nixos/secrets/disks/content.yaml"; gid = "0"; uid = "0"; mode = "0400"; } ) (range 0 (contentCount - 1))); systemd.services.mount-content-disks = { description = "Mount content disks."; before = [ "mnt-data.mount" ]; requiredBy = [ "mnt-data.mount" ]; requires = [ "sops-install-secrets.service" ]; path = [ pkgs.cryptsetup pkgs.util-linux ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; script = let mountContentDisk = i: '' if [ ! -e /dev/mapper/content-${toString i} ]; then cryptsetup luksOpen --key-file /run/secrets/disks/content-${toString i} /dev/disk/by-partlabel/disk-content-${toString i}-luks content-${toString i} fi mkdir -p /mnt/content-${toString i} if ! mountpoint -q /mnt/content-${toString i}; then mount -t ${cfg.partition.filesystem} /dev/mapper/content-${toString i} /mnt/content-${toString i} fi ''; in '' ${concatMapStrings mountContentDisk (range 0 (contentCount - 1))} ''; }; }; }