From ae8fb251024f6f0f256ad91af88924b0a2bdda0f Mon Sep 17 00:00:00 2001 From: DashieTM Date: Sun, 2 Mar 2025 15:29:47 +0100 Subject: [PATCH] Add disko variant for drive configuration --- flake.nix | 6 +- lib/default.nix | 1 + modules/programs/drives.nix | 298 +++++++++++++++++++++++++++--------- 3 files changed, 228 insertions(+), 77 deletions(-) diff --git a/flake.nix b/flake.nix index 15d1e5e..4ae8f79 100644 --- a/flake.nix +++ b/flake.nix @@ -33,6 +33,7 @@ stylix.url = "github:danth/stylix"; base16.url = "github:SenchoPens/base16.nix"; + disko.url = "github:nix-community/disko/latest"; anyrun.url = "github:Kirottu/anyrun"; oxicalc.url = "github:DashieTM/OxiCalc"; @@ -80,7 +81,8 @@ }; overlays = [ inputs.nur.overlays.default - inputs.chaoticNyx.overlays.default]; + inputs.chaoticNyx.overlays.default + ]; }; pkgs = import inputs.nixpkgs { system = currentSystem; @@ -94,7 +96,7 @@ overlays = [ inputs.nur.overlays.default inputs.chaoticNyx.overlays.default - ]; + ]; }; in rec { dashNixLib = import ./lib { diff --git a/lib/default.nix b/lib/default.nix index 757fdf4..93408b3 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -44,6 +44,7 @@ nixos = [ inputs.home-manager.nixosModules.home-manager inputs.stylix.nixosModules.stylix + inputs.disko.nixosModules.disko ../base ../home ../modules diff --git a/modules/programs/drives.nix b/modules/programs/drives.nix index 35bf396..8331464 100644 --- a/modules/programs/drives.nix +++ b/modules/programs/drives.nix @@ -3,87 +3,151 @@ config, options, ... -}: let - driveModule = lib.types.submodule { - options = { - name = lib.mkOption { - type = lib.types.str; +}: { + options.mods.drives = { + variant = lib.mkOption { + default = "manual"; + example = "disko"; + type = with lib.types; (enum [ + "manual" + "disko" + ]); + description = '' + Disk configuration type, either "manual" for regular NixOS disk configuration, + or "disko" for using disko to automatically format your drives. + ''; + }; + useSwap = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; + description = '' + Use swap in drive. + ''; + }; + homeAndRootFsTypes = lib.mkOption { + default = "ext4"; + example = "btrfs"; + type = with lib.types; (enum [ + "btrfs" + "ext2" + "ext3" + "ext4" + "exfat" + "f2fs" + "fat8" + "fat16" + "fat32" + "ntfs" + "xfs" + "zfs" + ]); + description = '' + Filesystem for the home and root partitions. + ''; + }; + defaultDrives = { + enable = lib.mkOption { + default = true; + example = false; + type = lib.types.bool; description = '' - The path of the drive. - Note that a / is already added at the beginning. + Use default drive config. + + ## Manual variant + This config expects 4 different partitions on a single drive: + - boot partition with "BOOT" label and vfat format (filesystem configurable) + - swap partition with "SWAP" label + - root partition with "ROOT" label and ext4 format (filesystem configurable) + - home partition with "HOME" label and ext4 format (filesystem configurable) + - gpt disk format + NOTE: Any different configuration must be done manually with this turned off. + + ## Disko variant + This config creates 4 different partitions on a single drive: + - boot partition with 1GB size and vfat format + - swap partition with 32GB (size configurable) + - root partition with 30% size and ext4 format (size and filesystem configurable) + - home partition with 70%~ size and ext4 format (size and filesystem configurable) + - gpt disk format + NOTE: Any different configuration must be done manually with this turned off. ''; - default = ""; - example = "drive2"; - }; - drive = lib.mkOption { - type = lib.types.attrsOf lib.types.anything; - description = "The attrs of the drive"; - default = {}; - example = { - device = "/dev/disk/by-label/DRIVE2"; - fsType = "ext4"; - options = [ - "noatime" - "nodiratime" - "discard" - ]; - }; }; }; - }; -in { - options.mods = { - drives = { - useSwap = { - enable = lib.mkOption { - default = true; - example = false; - type = lib.types.bool; - description = '' - Use default drive config - ''; - }; - }; - defaultDrives = { - enable = lib.mkOption { - default = true; - example = false; - type = lib.types.bool; - description = '' - Use default drive config - ''; - }; - }; - extraDrives = lib.mkOption { - default = [ - ]; - example = [ - { - name = "drive2"; - drive = { - device = "/dev/disk/by-label/DRIVE2"; - fsType = "ext4"; - options = [ - "noatime" - "nodiratime" - "discard" - ]; + extraDrives = lib.mkOption { + default = [ + ]; + example = [ + { + name = "drive2"; + drive = { + device = "/dev/disk/by-label/DRIVE2"; + fsType = "ext4"; + options = [ + "noatime" + "nodiratime" + "discard" + ]; + }; + } + ]; + type = with lib.types; listOf (attrsOf anything); + description = '' + Extra drives to add. + Please ensure to add variant compliant attrsets (manual/disko). + (The example is for manual variant, here an example for disko): + ```nix + drive2 = (lib.optionalAttrs config.mods.drives.defaultDrives.enable) { + device = "/dev/nvme1n1" + type = "disk"; + content = { + type = "gpt"; + partitions = { + drive2 = { + start = "0%"; + end = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/drive2"; + mountOptions = [ + "noatime" + "nodiratime" + "discard" + ]; + }; + }; + }; }; - } - ]; - # TODO: how to make this work - # type = with lib.types; listOf (attrsOf driveModule); - type = with lib.types; listOf (attrsOf anything); - description = '' - Extra drives to add. - ''; + }; + ``` + ''; + }; + disko = { + defaultDiskId = lib.mkOption { + default = "TODO"; + example = "/dev/nvme0n1"; + type = lib.types.string; + description = "The name, ID, UUID or similar for the default drive."; + }; + rootAmount = lib.mkOption { + default = 70; + example = 60; + type = lib.types.number; + description = "The percentage of the disk for root. (Home will take up the rest) (Only for disko)"; + }; + swapAmount = lib.mkOption { + default = 32; + example = 64; + type = lib.types.number; + description = "The amount of swap to use. (Only for disko)"; }; }; }; config = ( lib.optionalAttrs (options ? fileSystems) { - fileSystems = + fileSystems = lib.mkIf (config.mods.drives.variant == "manual") ( builtins.listToAttrs ( map ( { @@ -99,7 +163,7 @@ in { // (lib.optionalAttrs config.mods.drives.defaultDrives.enable) { "/" = { device = "/dev/disk/by-label/ROOT"; - fsType = "btrfs"; + fsType = config.mods.drives.homeAndRootFsTypes; options = [ "noatime" "nodiratime" @@ -120,18 +184,102 @@ in { "/home" = { device = "/dev/disk/by-label/HOME"; - fsType = "btrfs"; + fsType = config.mods.drives.homeAndRootFsTypes; options = [ "noatime" "nodiratime" "discard" ]; }; - }; - # TODO make this convert to choice of drives -> thanks to funny types this doesn't work... - swapDevices = lib.mkIf config.mods.drives.useSwap.enable [ + } + ); + + swapDevices = lib.mkIf (config.mods.drives.useSwap && config.mods.drives.variant == "manual") [ {device = "/dev/disk/by-label/SWAP";} ]; + + disko.devices = lib.mkIf (config.mods.drives.variant == "disko") { + disk = + { + main = (lib.optionalAttrs config.mods.drives.defaultDrives.enable) { + device = "${config.mods.drives.disko.defaultDiskId}"; + type = "disk"; + content = { + type = "gpt"; + partitions = { + root = { + start = "${ + if config.mods.drives.useSwap + then builtins.toString config.mods.drives.disko.swapAmount + else builtins.toString 1 + }G"; + end = "${builtins.toString config.mods.drives.disko.rootAmount}%"; + content = { + type = "filesystem"; + format = config.mods.drives.homeAndRootFsTypes; + mountpoint = "/"; + mountOptions = [ + "noatime" + "nodiratime" + "discard" + ]; + }; + }; + plainSwap = { + start = "1G"; + end = "33G"; + content = { + type = "swap"; + discardPolicy = "both"; + resumeDevice = true; + }; + }; + boot = { + start = "0G"; + end = "1G"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ + "rw" + "fmask=0022" + "dmask=0022" + "noatime" + ]; + }; + }; + home = { + start = "${builtins.toString config.mods.drives.disko.rootAmount}%"; + end = "100%"; + content = { + type = "filesystem"; + format = config.mods.drives.homeAndRootFsTypes; + mountpoint = "/home"; + mountOptions = [ + "noatime" + "nodiratime" + "discard" + ]; + }; + }; + }; + }; + }; + } + // builtins.listToAttrs ( + map ( + { + name, + drive, + }: { + name = "/" + name; + value = drive; + } + ) + config.mods.drives.extraDrives + ); + }; } ); }