This commit is contained in:
Raphaël Billet
2025-12-04 10:46:18 +01:00
parent 3a5b786b36
commit 0c07311b0d
4 changed files with 113 additions and 55 deletions
+61 -24
View File
@@ -1,21 +1,28 @@
{ modulesPath, config, lib, pkgs, inputs, ... }:
let
# Find all mount points that start with "/mnt/data-"
dataDiskMounts = lib.attrsets.attrNames (
lib.attrsets.filterAttrs (name: value: lib.strings.hasPrefix "/mnt/data-" name) config.fileSystems
);
# # Find all mount points that start with "/mnt/data-"
# dataDiskMounts = lib.attrsets.attrNames (
# lib.attrsets.filterAttrs (name: value: lib.strings.hasPrefix "/mnt/data-" name) config.fileSystems
# );
#
# # Find all mount points that start with "/mnt/parity-"
# parityDiskMounts = lib.attrsets.attrNames (
# lib.attrsets.filterAttrs (name: value: lib.strings.hasPrefix "/mnt/parity-" name) config.fileSystems
# );
#
# # Create an attribute set for snapraid data disks, e.g. { d1 = "/mnt/data-1"; d2 = "/mnt/data-2"; }
# snapraidDataDisks = lib.lists.foldl'
# (acc: path: acc // { "d${toString (acc.i + 1)}" = path; i = acc.i + 1; })
# { i = 0; }
# dataDiskMounts;
#in
# Find all mount points that start with "/mnt/parity-"
parityDiskMounts = lib.attrsets.attrNames (
lib.attrsets.filterAttrs (name: value: lib.strings.hasPrefix "/mnt/parity-" name) config.fileSystems
);
# Create an attribute set for snapraid data disks, e.g. { d1 = "/mnt/data-1"; d2 = "/mnt/data-2"; }
snapraidDataDisks = lib.lists.foldl'
(acc: path: acc // { "d${toString (acc.i + 1)}" = path; i = acc.i + 1; })
{ i = 0; }
dataDiskMounts;
# Helper to get mount points for data and parity disks from disko config
getMounts = prefix: lib.attrsets.attrNames (lib.attrsets.filterAttrs (n: v: v.mountPoint != null && lib.strings.hasPrefix v.mountPoint prefix) config.disko.devices.fs);
dataDiskMounts = getMounts "/mnt/data-";
parityDiskMounts = getMounts "/mnt/parity-";
snapraidDataDisks = lib.listToAttrs (lib.imap0 (i: path: { name = "d${toString (i + 1)}"; value = path; }) dataDiskMounts);
in
{
@@ -24,6 +31,7 @@ in
(modulesPath + "/profiles/qemu-guest.nix")
inputs.sops-nix.nixosModules.sops
./disk-config.nix
./ensure-pcr.nix
];
# Hardware settings
@@ -44,21 +52,19 @@ in
sops.secrets."docker/hass" = { owner = "numbus-admin"; path = "/etc/docker-compose/hass/.env"; };
sops.secrets."docker/pihole" = { owner = "numbus-admin"; path = "/etc/docker-compose/pihole/.env"; };
sops.secrets."docker/immich" = { owner = "numbus-admin"; path = "/etc/docker-compose/immich/.env"; };
sops.secrets."disks/data_disk_1" = { owner = "root"; };
sops.secrets."disks/data_disk_2" = { owner = "root"; };
sops.secrets."disks/data_disk_3" = { owner = "root"; };
sops.secrets."disks/data_disk_4" = { owner = "root"; };
sops.secrets."disks/data_disk_5" = { owner = "root"; };
sops.secrets."disks/data_disk_6" = { owner = "root"; };
sops.secrets."disks/parity_disk_1" = { owner = "root"; };
sops.secrets."disks/parity_disk_2" = { owner = "root"; };
sops.secrets."disks/parity_disk_3" = { owner = "root"; };
# Bootloader options
boot.initrd.systemd.enable = true;
boot.initrd.systemd.tpm2.enable = true;
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
# TPM2 PCR check
systemIdentity.enable = true;
# On first boot, get the value with: systemd-analyze pcrs 15 --json=short | jq -r ".[0].sha256"
# and place it here.
systemIdentity.pcr15 = null; # "6214de8c3d861c4b451acc8c4e24294c95d55bcec516bbf15c077ca3bffb6547";
# Timezone
time.timeZone = "Europe/Paris";
@@ -198,12 +204,43 @@ in
];
};
# # Hard drives decryption
# environment.etc."crypttab".text = ''
# crypted-data-1 /dev/disk/by-uuid/THE-UUID-OF-DATA-DISK-1 /run/secrets/disks/data-disk-1
# crypted-data-2 /dev/disk/by-uuid/THE-UUID-OF-DATA-DISK-2 /run/secrets/disks/data-disk-2
# crypted-data-3 /dev/disk/by-uuid/THE-UUID-OF-DATA-DISK-3 /run/secrets/disks/data-disk-3
# crypted-data-4 /dev/disk/by-uuid/THE-UUID-OF-DATA-DISK-4 /run/secrets/disks/data-disk-4
# crypted-data-5 /dev/disk/by-uuid/THE-UUID-OF-DATA-DISK-5 /run/secrets/disks/data-disk-5
# crypted-data-6 /dev/disk/by-uuid/THE-UUID-OF-DATA-DISK-6 /run/secrets/disks/data-disk-6
# crypted-parity-1 /dev/disk/by-uuid/THE-UUID-OF-PARITY-DISK-1 /run/secrets/disks/parity-disk-1
# crypted-parity-2 /dev/disk/by-uuid/THE-UUID-OF-PARITY-DISK-2 /run/secrets/disks/parity-disk-2
# crypted-parity-3 /dev/disk/by-uuid/THE-UUID-OF-PARITY-DISK-3 /run/secrets/disks/parity-disk-3
# '';
# Declarative LUKS decryption for data and parity disks
boot.luks.devices =
let
# This function generates the attribute set for a LUKS device
mkLuksDevice = type: index:
lib.nameValuePair "crypted-${type}-${toString index}" {
device = "/dev/disk/by-partlabel/${type}-disk-${toString index}";
keyFile = "/run/secrets/disks/${type}-disk-${toString index}";
# This option tells systemd to measure the LUKS header into PCR 15
};
in
# Merge attributes for data and parity disks
lib.attrsets.listToAttrs (
(lib.lists.imap1 (i: _: mkLuksDevice "data" i) dataDiskMounts) ++
(lib.lists.imap1 (i: _: mkLuksDevice "parity" i) parityDiskMounts)
);
# SnapRAID for data redundancy
services.snapraid = {
enable = true;
contentFiles = map (disk: "${disk}/snapraid.content") dataDiskMounts;
parityFiles = map (disk: "${disk}/snapraid.parity") parityDiskMounts;
dataDisks = builtins.removeAttrs snapraidDataDisks [ "i" ]; # This correctly creates the required attribute set.
# dataDisks = builtins.removeAttrs snapraidDataDisks [ "i" ]; # This correctly creates the required attribute set.
dataDisks = snapraidDataDisks;
# Using default sync and scrub schedules:
# Sync runs daily at 01:00.
# Scrub runs weekly on Monday at 02:00.