From dd645848d82da06dd7cc766ff25518577d0a3861 Mon Sep 17 00:00:00 2001 From: Eva Emmerich Date: Thu, 24 Jul 2025 12:22:38 -0500 Subject: [PATCH] docs: add btrfs raid on luks devices non-root example useful for creating and managing a non-root, encrypted data raid on a headless server the major difference between this and https://github.com/nix-community/disko/blob/master/example/luks-btrfs-raid.nix is that this configuration is not expected to be decrypted at boot time because of that, we set options ``` initrdUnlock = false; # dont try to unlock this in the initrd "noauto" # ensure that systemd doesnt try to mount this at boot "nofail" # ensure that systemd failing to mount this doesn't send us to emergency mode ``` additionally, each disk is a raw luks device with no partition table tested using a server board with 4x nvme drives --- example/luks-btrfs-raid-non-root.nix | 118 +++++++++++++++++++++++++++ tests/luks-btrfs-raid-non-root.nix | 16 ++++ 2 files changed, 134 insertions(+) create mode 100644 example/luks-btrfs-raid-non-root.nix create mode 100644 tests/luks-btrfs-raid-non-root.nix diff --git a/example/luks-btrfs-raid-non-root.nix b/example/luks-btrfs-raid-non-root.nix new file mode 100644 index 00000000..d152533b --- /dev/null +++ b/example/luks-btrfs-raid-non-root.nix @@ -0,0 +1,118 @@ +# creates 4x luks containers on 4x nvme drives +# then creates a single btrfs RAID 10 volume across them +# this is not intended to be used as a root/boot device, rather as encrypted data storage +# each device has its own luks key +# instead use `disko-mount` to mount them +# disko-mount can be added to your system by adding the following to your configuration.nix +# environment.systemPackages = [ config.system.build.mount ]; + +{ + disko.devices = { + disk = { + # Devices will be mounted and formatted in alphabetical order, and btrfs can only mount raids + # when all devices are present. So we define an "empty" luks device on the first 3 disks, + # and the actual btrfs raid on the last disk, and the name of these entries matters! + disk0 = { + type = "disk"; + device = "/dev/nvme0n1"; + content = { + type = "luks"; + name = "disk0"; # device-mapper name when decrypted + initrdUnlock = false; # dont try to unlock this in the initrd + settings = { + allowDiscards = true; + }; + }; + }; + disk1 = { + type = "disk"; + device = "/dev/nvme1n1"; + content = { + type = "luks"; + name = "disk1"; # device-mapper name when decrypted + initrdUnlock = false; # dont try to unlock this in the initrd + settings = { + allowDiscards = true; + }; + }; + }; + disk2 = { + type = "disk"; + device = "/dev/nvme2n1"; + content = { + type = "luks"; + name = "disk2"; # device-mapper name when decrypted + initrdUnlock = false; # dont try to unlock this in the initrd + settings = { + allowDiscards = true; + }; + }; + }; + disk3 = { + type = "disk"; + device = "/dev/nvme3n1"; + content = { + type = "luks"; + name = "disk3"; # device-mapper name when decrypted + initrdUnlock = false; # dont try to unlock this in the initrd + settings = { + allowDiscards = true; + }; + content = { + type = "btrfs"; + extraArgs = [ + "-d raid10" + "/dev/mapper/disk0" # Use decrypted mapped device, same name as defined in disk0 + "/dev/mapper/disk1" # Use decrypted mapped device, same name as defined in disk1 + "/dev/mapper/disk2" # Use decrypted mapped device, same name as defined in disk2 + # disk3 is passed in by by default + ]; + subvolumes = { + "data" = { + + mountpoint = "/data"; + mountOptions = [ + "defaults" # use the sane btrfs mount defaults + "noauto" # ensure that systemd doesnt try to mount this at boot + "nofail" # ensure that systemd failing to mount this doesn't send us to emergency mode + "noatime" + "ssd" + ]; + }; + }; + }; + }; + }; + # included a simple root fs to make the test framework happy + # swap this with any solution for your rootfs, or drop it completely + # its not the focus of this example + adisk = { + device = "/dev/mmcblk0"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + ESP = { + type = "EF00"; + size = "500M"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; + }; +} diff --git a/tests/luks-btrfs-raid-non-root.nix b/tests/luks-btrfs-raid-non-root.nix new file mode 100644 index 00000000..3a2c4c8d --- /dev/null +++ b/tests/luks-btrfs-raid-non-root.nix @@ -0,0 +1,16 @@ +{ + pkgs ? import { }, + diskoLib ? pkgs.callPackage ../lib { }, +}: +diskoLib.testLib.makeDiskoTest { + inherit pkgs; + name = "luks-btrfs-raid-non-root"; + disko-config = ../example/luks-btrfs-raid-non-root.nix; + extraTestScript = '' + machine.succeed("cryptsetup isLuks /dev/vda4"); + machine.succeed("cryptsetup isLuks /dev/vda3"); + machine.succeed("cryptsetup isLuks /dev/vda2"); + machine.succeed("cryptsetup isLuks /dev/vdb1"); + machine.succeed("btrfs subvolume list /data"); + ''; +}