nix/lib/disko/default.nix

499 lines
14 KiB
Nix
Raw Normal View History

2025-02-14 13:31:18 -06:00
{ nixpkgs-unstable, ... }:
let
2025-02-14 13:04:04 -06:00
# TODO: This file needs some serious cleaning up.
lib = nixpkgs-unstable.lib;
inherit (lib.attrsets) mapAttrs' filterAttrs;
2025-02-14 13:31:18 -06:00
ESP =
inputs@{
size ? "4G",
label ? "ESP",
name ? "ESP",
}:
2024-12-28 13:41:53 -06:00
{
priority = 1;
start = "1M";
label = label;
name = name;
end = size;
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [
"umask=0077"
];
};
}
// inputs;
2025-02-14 13:31:18 -06:00
in
rec {
standardWithHibernateSwap =
{
esp ? {
label = "ESP";
size = "4G";
name = "ESP";
},
rootfsName ? "/rootfs",
homeName ? "/home",
disk,
swapSize,
...
}:
{
/*
this is my standard partitioning scheme for my machines which probably want hibernation capabilities
a UEFI-compatible boot partition
it includes an LUKS-encrypted btrfs volume
a swap partition big enough to dump all the machine's RAM into
*/
2024-07-17 20:22:16 -05:00
2025-02-14 13:31:18 -06:00
disko.devices = {
disk = {
primary = {
type = "disk";
device = disk;
content = {
type = "gpt";
partitions = {
ESP = ESP esp;
swap = {
size = swapSize;
content = {
type = "swap";
discardPolicy = "both";
resumeDevice = true; # resume from hiberation from this device
};
2024-07-17 20:22:16 -05:00
};
2025-02-14 13:31:18 -06:00
luks = {
size = "100%";
2024-07-17 20:22:16 -05:00
content = {
2025-02-14 13:31:18 -06:00
type = "luks";
name = "crypted";
# if you want to use the key for interactive login be sure there is no trailing newline
# for example use `echo -n "password" > /tmp/secret.key`
keyFile = "/tmp/secret.key"; # Interactive
# settings.keyFile = "/tmp/password.key";
# additionalKeyFiles = ["/tmp/additionalSecret.key"];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
${rootfsName} = {
mountpoint = "/";
mountOptions = [ "compress=zstd" ];
};
${homeName} = {
mountpoint = "/home";
mountOptions = [ "compress=zstd" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
};
};
2024-07-17 20:22:16 -05:00
};
};
};
};
};
};
};
};
2024-12-28 13:41:53 -06:00
foxtrot = standardWithHibernateSwap {
disk = "nvme0n1";
swapSize = "32G";
2025-01-18 00:38:41 -06:00
rootfsName = "/nixos-rootfs";
homeName = "/nixos-home";
2024-12-28 13:41:53 -06:00
esp = {
2024-12-28 13:57:03 -06:00
label = "disk-primary-ESP";
name = "disk-primary-ESP";
2024-12-28 13:41:53 -06:00
};
};
2025-02-20 12:24:40 -06:00
standardEncrypted =
{
disk,
espSize ? "4G",
...
}:
standard {
inherit disk;
esp = {
label = "ESP";
size = espSize;
name = "ESP";
};
};
2025-02-14 13:31:18 -06:00
standard =
{
esp ? {
label = "ESP";
size = "4G";
name = "ESP";
},
disk,
...
}:
{
# this is my standard partitioning scheme for my machines: an LUKS-encrypted
# btrfs volume
disko.devices = {
disk = {
primary = {
type = "disk";
device = disk;
content = {
type = "gpt";
partitions = {
ESP = ESP esp;
luks = {
size = "100%";
2023-10-02 14:40:35 -05:00
content = {
2025-02-14 13:31:18 -06:00
type = "luks";
name = "crypted";
# if you want to use the key for interactive login be sure there is no trailing newline
# for example use `echo -n "password" > /tmp/secret.key`
keyFile = "/tmp/secret.key"; # Interactive
# settings.keyFile = "/tmp/password.key";
# additionalKeyFiles = ["/tmp/additionalSecret.key"];
content = {
type = "btrfs";
extraArgs = [ "-f" ];
subvolumes = {
"/root" = {
mountpoint = "/";
mountOptions = [ "compress=zstd" ];
};
"/home" = {
mountpoint = "/home";
mountOptions = [ "compress=zstd" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
2023-10-02 14:40:35 -05:00
};
};
};
};
};
};
};
};
};
};
2024-09-04 10:31:06 -05:00
2025-01-05 01:33:54 -06:00
thablet = standard {
disk = "nvme0n1";
esp = {
label = "EFI";
size = "4G";
name = "EFI";
};
};
2025-02-14 13:31:18 -06:00
unencrypted =
{ disk, ... }:
{
disko.devices = {
disk = {
primary = {
type = "disk";
device = disk;
content = {
type = "gpt";
partitions = {
ESP = ESP { size = "5G"; };
root = {
size = "100%";
content = {
type = "btrfs";
extraArgs = [ "-f" ];
mountpoint = "/partition-root";
subvolumes = {
"/rootfs" = {
mountpoint = "/";
mountOptions = [ "compress=zstd" ];
};
"/home" = {
mountpoint = "/home";
mountOptions = [ "compress=zstd" ];
};
"/nix" = {
mountpoint = "/nix";
mountOptions = [
"compress=zstd"
"noatime"
];
};
2023-09-05 15:33:20 -05:00
};
};
};
};
};
};
};
};
2024-09-04 10:31:06 -05:00
};
2024-09-06 06:56:28 -05:00
2025-02-14 13:31:18 -06:00
beefcake =
let
zpools = {
zroot = {
/*
TODO: at the time of writing, disko does not support draid6
so I'm building/managing the array manually for the time being
the root pool is just a single disk right now
*/
name = "zroot";
config = {
type = "zpool";
# mode = "draid6";
rootFsOptions = {
compression = "zstd";
"com.sun:auto-snapshot" = "false";
2024-09-04 10:31:06 -05:00
};
2025-02-14 13:31:18 -06:00
mountpoint = "/";
postCreateHook = "zfs list -t snapshot -H -o name | grep -E '^zroot@blank$' || zfs snapshot zroot@blank";
datasets = {
zfs_fs = {
type = "zfs_fs";
mountpoint = "/zfs_fs";
options."com.sun:auto-snapshot" = "true";
2024-09-04 10:31:06 -05:00
};
2025-02-14 13:31:18 -06:00
zfs_unmounted_fs = {
type = "zfs_fs";
options.mountpoint = "none";
};
zfs_legacy_fs = {
type = "zfs_fs";
options.mountpoint = "legacy";
mountpoint = "/zfs_legacy_fs";
};
zfs_testvolume = {
type = "zfs_volume";
size = "10M";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/ext4onzfs";
};
};
encrypted = {
type = "zfs_fs";
options = {
mountpoint = "none";
encryption = "aes-256-gcm";
keyformat = "passphrase";
keylocation = "file:///tmp/secret.key";
};
# use this to read the key during boot
/*
postCreateHook = ''
zfs set keylocation="prompt" "zroot/$name";
'';
*/
};
"encrypted/test" = {
type = "zfs_fs";
mountpoint = "/zfs_crypted";
2024-09-04 10:31:06 -05:00
};
};
};
};
2025-02-14 13:31:18 -06:00
zstorage = {
/*
PARITY_COUNT=3 NUM_DRIVES=8 HOT_SPARES=2 sudo -E zpool create -f -O mountpoint=none -O compression=on -O xattr=sa -O acltype=posixacl -o ashift=12 -O atime=off -O recordsize=64K zstorage draid{$PARITY_COUNT}:{$NUM_DRIVES}c:{$HOT_SPARES}s /dev/disk/by-id/scsi-35000039548cb637c /dev/disk/by-id/scsi-35000039548cb7c8c /dev/disk/by-id/scsi-35000039548cb85c8 /dev/disk/by-id/scsi-35000039548d9b504 /dev/disk/by-id/scsi-35000039548da2b08 /dev/disk/by-id/scsi-35000039548dad2fc /dev/disk/by-id/scsi-350000399384be921 /dev/disk/by-id/scsi-35000039548db096c
sudo zfs create -o mountpoint=legacy zstorage/nix
sudo zfs create -o canmount=on -o mountpoint=/storage zstorage/storage
*/
name = "zstorage";
config = { };
};
2024-09-04 10:31:06 -05:00
};
2025-02-14 13:31:18 -06:00
diskClass = {
storage = {
type = "zfs";
pool = zpools.zroot.name;
};
boot = {
content = {
type = "gpt";
partitions = {
ESP = {
size = "1G";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
2024-09-04 10:31:06 -05:00
};
2025-02-14 13:31:18 -06:00
zfs = {
size = "100%";
content = {
type = "zfs";
pool = zpools.zroot.name;
};
2024-09-04 10:31:06 -05:00
};
};
};
};
};
2025-02-14 13:31:18 -06:00
bootDisks = {
"/dev/sdi" = {
name = "i";
enable = true;
};
"/dev/sdj" = {
name = "j";
enable = true;
}; # TODO: join current boot drive to new boot pool
2024-09-04 10:31:06 -05:00
};
2025-02-14 13:31:18 -06:00
storageDisks = {
"/dev/sda" = {
enable = true;
name = "a";
};
"/dev/sdb" = {
enable = true;
name = "b";
};
"/dev/sdc" = {
enable = true;
name = "c";
};
"/dev/sdd" = {
enable = true;
name = "d";
};
2024-09-04 10:31:06 -05:00
2025-02-14 13:31:18 -06:00
# TODO: start small
"/dev/sde" = {
enable = false;
name = "e";
};
"/dev/sdf" = {
enable = false;
name = "f";
};
"/dev/sdg" = {
enable = false;
name = "g";
};
"/dev/sdh" = {
enable = false;
name = "h";
};
2024-09-04 10:31:06 -05:00
2025-02-14 13:31:18 -06:00
# gap for two boot drives
2024-09-04 10:31:06 -05:00
2025-02-14 13:31:18 -06:00
"/dev/sdk" = {
enable = false;
name = "k";
};
"/dev/sdl" = {
enable = false;
name = "l";
};
"/dev/sdm" = {
enable = false;
name = "m";
};
"/dev/sdn" = {
# TODO: this is my holding cell for random stuff right now
enable = false;
name = "n";
};
2024-09-04 10:31:06 -05:00
};
2025-02-14 13:31:18 -06:00
diskoBoot = mapAttrs' (
device:
{ name, ... }:
{
name = "boot-${name}";
value = {
inherit device;
type = "disk";
content = diskClass.boot.content;
};
}
) (filterAttrs (_: { enable, ... }: enable) bootDisks);
2024-09-04 10:31:06 -05:00
2025-02-14 13:31:18 -06:00
diskoStorage = mapAttrs' (
device:
{ name, ... }:
{
name = "storage-${name}";
value = {
inherit device;
type = "disk";
content = diskClass.storage.content;
};
}
) (filterAttrs (_: { enable, ... }: enable) storageDisks);
in
{
disko.devices = {
disk = diskoBoot // diskoStorage;
zpool = {
zroot = zpools.zroot.config;
};
2024-09-04 10:31:06 -05:00
};
2023-09-05 15:33:20 -05:00
};
2025-02-14 13:04:04 -06:00
2025-02-14 13:31:18 -06:00
legacy =
{ disks, ... }:
{
disko.devices = {
disk = {
primary = {
device = builtins.elemAt disks 0;
type = "disk";
content = {
type = "table";
format = "gpt";
partitions = [
{
label = "EFI";
name = "ESP";
size = "512M";
bootable = true;
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
};
}
{
name = "root";
start = "500M";
end = "100%";
part-type = "primary";
bootable = true;
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
};
}
];
};
2023-10-06 10:42:19 -05:00
};
};
};
};
2023-09-05 15:33:20 -05:00
}