{ lib , config , ... }: with lib; let cfg = config.hardware.encryptedDisk; volumeGroup = cfg.diskId; # This is important at install-time bootGrubDevice = lib.concatStrings [ "/dev/disk/by-id/" cfg.diskId ]; # These are guaranteed by LVM rootFsDevice = lib.concatStrings [ "/dev/" volumeGroup "/root" ]; swapFsDevice = lib.concatStrings [ "/dev/" volumeGroup "/swap" ]; # TODO: verify the GPT PARTLABEL cap at 36 chars shortenPartlabel = name: (builtins.substring 0 36 name); # Cannot use the disk ID here because might be different at install vs. runtime. # Example: MMC card which is used in the internal reader vs. USB reader bootFsDevice = lib.concatStrings [ "/dev/disk/by-partlabel/" (shortenPartlabel ("2-"+cfg.diskId))]; bootLuksDevice = lib.concatStrings [ "/dev/disk/by-partlabel/" (shortenPartlabel ("3-"+cfg.diskId))]; in { options.hardware.encryptedDisk = { enable = mkEnableOption "Enable encrypted filesystem layout"; diskId = mkOption { type = types.string; }; }; config = lib.mkIf cfg.enable { fileSystems."/boot" = { device = bootFsDevice; fsType = "vfat"; }; fileSystems."/" = { device = rootFsDevice; fsType = "btrfs"; options = [ "subvol=nixos" ]; }; fileSystems."/home" = { device = rootFsDevice; fsType = "btrfs"; options = [ "subvol=home" ]; }; swapDevices = [ { device = swapFsDevice; } ]; boot.loader.grub = { device = bootGrubDevice; enableCryptodisk = true; }; boot.initrd.luks.devices = [ { name = let splitstring = builtins.split "/" bootLuksDevice; lastelem = (builtins.length splitstring)-1; in builtins.elemAt splitstring lastelem; device = bootLuksDevice; preLVM = true; allowDiscards = true; } ]; }; }