From ab9b880db2e6ddbcd02656941ba02aff2dd682f0 Mon Sep 17 00:00:00 2001 From: lassulus Date: Sat, 1 Jul 2023 19:02:01 +0200 Subject: [PATCH] lib.types: turn _create, _mount and _config into values --- lib/default.nix | 27 +++++++++++------------ lib/types/btrfs.nix | 31 +++++++++++++++----------- lib/types/disk.nix | 9 ++++---- lib/types/filesystem.nix | 21 +++++++++++------- lib/types/gpt.nix | 31 ++++++++++++++++---------- lib/types/luks.nix | 29 +++++++++++++++---------- lib/types/lvm_pv.nix | 18 +++++++++------ lib/types/lvm_vg.nix | 16 +++++++------- lib/types/mdadm.nix | 12 +++++----- lib/types/mdraid.nix | 16 +++++++++----- lib/types/nodev.nix | 4 ++-- lib/types/swap.nix | 23 ++++++++++++-------- lib/types/table.nix | 47 ++++++++++++++++++++++++---------------- lib/types/zfs.nix | 16 +++++++++----- lib/types/zfs_fs.nix | 14 ++++++------ lib/types/zfs_volume.nix | 16 +++++++------- lib/types/zpool.nix | 10 ++++----- 17 files changed, 194 insertions(+), 146 deletions(-) diff --git a/lib/default.nix b/lib/default.nix index 9f9ae6d..40bbe88 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -178,16 +178,15 @@ let lib.mkOption { internal = true; readOnly = true; - type = lib.types.functionTo lib.types.str; - default = args: - '' - ( # ${config.type} ${concatMapStringsSep " " (n: toString (config.${n} or "")) ["name" "device" "format" "mountpoint"]} - ${diskoLib.defineHookVariables { inherit config options; }} - ${config.preCreateHook} - ${attrs.default args} - ${config.postCreateHook} - ) - ''; + type = lib.types.str; + default = '' + ( # ${config.type} ${concatMapStringsSep " " (n: toString (config.${n} or "")) ["name" "device" "format" "mountpoint"]} + ${diskoLib.defineHookVariables { inherit config options; }} + ${config.preCreateHook} + ${attrs.default} + ${config.postCreateHook} + ) + ''; description = "Creation script"; }; @@ -195,7 +194,7 @@ let lib.mkOption { internal = true; readOnly = true; - type = lib.types.functionTo diskoLib.jsonType; + type = diskoLib.jsonType; default = attrs.default; description = "Mount script"; }; @@ -231,7 +230,7 @@ let trap 'rm -rf "$disko_devices_dir"' EXIT mkdir -p "$disko_devices_dir" - ${concatMapStrings (dev: (attrByPath (dev ++ [ "_create" ]) (_: {}) devices) {}) sortedDeviceList} + ${concatMapStrings (dev: (attrByPath (dev ++ [ "_create" ]) "" devices)) sortedDeviceList} ''; /* Takes a disko device specification and returns a string which mounts the disks @@ -239,13 +238,13 @@ let */ mount = devices: let - fsMounts = diskoLib.deepMergeMap (dev: (dev._mount { }).fs or { }) (flatten (map attrValues (attrValues devices))); + fsMounts = diskoLib.deepMergeMap (dev: dev._mount.fs or { }) (flatten (map attrValues (attrValues devices))); sortedDeviceList = diskoLib.sortDevicesByDependencies ((diskoLib.meta devices).deviceDependencies or { }) devices; in '' set -efux # first create the necessary devices - ${concatMapStrings (dev: ((attrByPath (dev ++ [ "_mount" ]) {} devices) {}).dev or "") sortedDeviceList} + ${concatMapStrings (dev: ((attrByPath (dev ++ [ "_mount" ]) {} devices)).dev or "") sortedDeviceList} # and then mount the filesystems in alphabetical order ${concatStrings (attrValues fsMounts)} diff --git a/lib/types/btrfs.nix b/lib/types/btrfs.nix index 18718f9..4439ff8 100644 --- a/lib/types/btrfs.nix +++ b/lib/types/btrfs.nix @@ -1,4 +1,4 @@ -{ config, options, diskoLib, lib, rootMountPoint, parent, ... }: +{ config, options, diskoLib, lib, rootMountPoint, parent, device, ... }: { options = { type = lib.mkOption { @@ -6,6 +6,11 @@ internal = true; description = "Type"; }; + device = lib.mkOption { + type = lib.types.str; + default = device; + description = "Device to use"; + }; extraArgs = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; @@ -63,17 +68,17 @@ internal = true; readOnly = true; type = lib.types.functionTo diskoLib.jsonType; - default = _dev: { }; + default = dev: { }; description = "Metadata"; }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' - mkfs.btrfs ${dev} ${toString config.extraArgs} + default = '' + mkfs.btrfs ${config.device} ${toString config.extraArgs} ${lib.concatMapStrings (subvol: '' ( MNTPOINT=$(mktemp -d) - mount ${dev} "$MNTPOINT" -o subvol=/ + mount ${config.device} "$MNTPOINT" -o subvol=/ trap 'umount $MNTPOINT; rm -rf $MNTPOINT' EXIT btrfs subvolume create "$MNTPOINT"/${subvol.name} ${toString subvol.extraArgs} ) @@ -82,7 +87,7 @@ }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: + default = let subvolMounts = lib.concatMapAttrs (_: subvol: @@ -94,8 +99,8 @@ in lib.optionalAttrs (mountpoint != null) { ${mountpoint} = '' - if ! findmnt ${dev} "${rootMountPoint}${mountpoint}" > /dev/null 2>&1; then - mount ${dev} "${rootMountPoint}${mountpoint}" \ + if ! findmnt ${config.device} "${rootMountPoint}${mountpoint}" > /dev/null 2>&1; then + mount ${config.device} "${rootMountPoint}${mountpoint}" \ ${lib.concatMapStringsSep " " (opt: "-o ${opt}") (subvol.mountOptions ++ [ "subvol=${subvol.name}" ])} \ -o X-mount.mkdir fi @@ -107,8 +112,8 @@ { fs = subvolMounts // lib.optionalAttrs (config.mountpoint != null) { ${config.mountpoint} = '' - if ! findmnt ${dev} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then - mount ${dev} "${rootMountPoint}${config.mountpoint}" \ + if ! findmnt ${config.device} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then + mount ${config.device} "${rootMountPoint}${config.mountpoint}" \ ${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \ -o X-mount.mkdir fi @@ -119,7 +124,7 @@ _config = lib.mkOption { internal = true; readOnly = true; - default = dev: [ + default = [ (map (subvol: let @@ -130,7 +135,7 @@ in lib.optional (mountpoint != null) { fileSystems.${mountpoint} = { - device = dev; + device = config.device; fsType = "btrfs"; options = subvol.mountOptions ++ [ "subvol=${subvol.name}" ]; }; @@ -139,7 +144,7 @@ (lib.attrValues config.subvolumes)) (lib.optional (config.mountpoint != null) { fileSystems.${config.mountpoint} = { - device = dev; + device = config.device; fsType = "btrfs"; options = config.mountOptions; }; diff --git a/lib/types/disk.nix b/lib/types/disk.nix index 1f30788..120cdc3 100644 --- a/lib/types/disk.nix +++ b/lib/types/disk.nix @@ -16,7 +16,7 @@ type = diskoLib.optionTypes.absolute-pathname; # TODO check if subpath of /dev ? - No! eg: /.swapfile description = "Device path"; }; - content = diskoLib.deviceType { parent = config; }; + content = diskoLib.deviceType { parent = config; device = config.device; }; _meta = lib.mkOption { internal = true; readOnly = true; @@ -27,18 +27,17 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = _: config.content._create { dev = config.device; }; + default = config.content._create; }; _mount = diskoLib.mkMountOption { inherit config options; - default = _: - lib.optionalAttrs (config.content != null) (config.content._mount { dev = config.device; }); + default = lib.optionalAttrs (config.content != null) (config.content._mount); }; _config = lib.mkOption { internal = true; readOnly = true; default = - lib.optional (config.content != null) (config.content._config config.device); + lib.optional (config.content != null) (config.content._config); description = "NixOS configuration"; }; _pkgs = lib.mkOption { diff --git a/lib/types/filesystem.nix b/lib/types/filesystem.nix index 1e15e51..52e0f25 100644 --- a/lib/types/filesystem.nix +++ b/lib/types/filesystem.nix @@ -1,4 +1,4 @@ -{ config, options, lib, diskoLib, rootMountPoint, parent, ... }: +{ config, options, lib, diskoLib, rootMountPoint, parent, device, ... }: { options = { type = lib.mkOption { @@ -6,6 +6,11 @@ internal = true; description = "Type"; }; + device = lib.mkOption { + type = lib.types.str; + default = device; + description = "Device to use"; + }; extraArgs = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; @@ -38,18 +43,18 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' + default = '' mkfs.${config.format} \ ${toString config.extraArgs} \ - ${dev} + ${config.device} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: lib.optionalAttrs (config.mountpoint != null) { + default = lib.optionalAttrs (config.mountpoint != null) { fs.${config.mountpoint} = '' - if ! findmnt ${dev} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then - mount ${dev} "${rootMountPoint}${config.mountpoint}" \ + if ! findmnt ${config.device} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then + mount ${config.device} "${rootMountPoint}${config.mountpoint}" \ -t "${config.format}" \ ${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \ -o X-mount.mkdir @@ -60,9 +65,9 @@ _config = lib.mkOption { internal = true; readOnly = true; - default = dev: lib.optional (config.mountpoint != null) { + default = lib.optional (config.mountpoint != null) { fileSystems.${config.mountpoint} = { - device = dev; + device = config.device; fsType = config.format; options = config.mountOptions; }; diff --git a/lib/types/gpt.nix b/lib/types/gpt.nix index 780aa70..95318c4 100644 --- a/lib/types/gpt.nix +++ b/lib/types/gpt.nix @@ -1,4 +1,4 @@ -{ config, options, lib, diskoLib, parent, ... }@args: +{ config, options, lib, diskoLib, parent, device, ... }@args: { options = { type = lib.mkOption { @@ -6,6 +6,11 @@ internal = true; description = "Partition table"; }; + device = lib.mkOption { + type = lib.types.str; + default = device; + description = "Device to use for the partition table"; + }; partitions = lib.mkOption { type = lib.types.attrsOf (lib.types.submodule ({ name, ... }@partition: { options = { @@ -14,6 +19,11 @@ default = "8300"; description = "Filesystem type to use, run sgdisk -L to see what is available"; }; + device = lib.mkOption { + type = lib.types.str; + default = "/dev/disk/by-partlabel/${partition.config.label}"; + description = "Device to use for the partition"; + }; priority = lib.mkOption { type = lib.types.int; default = if (partition.config.size or "" == "100%") then 9001 else 1000; @@ -51,7 +61,7 @@ or - for relative sizes from the disks end ''; }; - content = diskoLib.partitionType { parent = config; }; + content = diskoLib.partitionType { parent = config; device = partition.config.device; }; }; })); default = [ ]; @@ -75,27 +85,27 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' + default = '' ${lib.concatStrings (lib.imap (index: partition: '' sgdisk \ --new=${toString index}:${partition.start}:${partition.end} \ --change-name=${toString index}:${partition.label} \ --typecode=${toString index}:${partition.type} \ - ${dev} + ${config.device} # ensure /dev/disk/by-path/..-partN exists before continuing udevadm trigger --subsystem-match=block; udevadm settle - ${lib.optionalString (partition.content != null) (partition.content._create { dev = "/dev/disk/by-partlabel/${partition.label}"; })} + ${lib.optionalString (partition.content != null) partition.content._create} '') (lib.sort (x: y: x.priority < y.priority) (lib.attrValues config.partitions)))} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: + default = let partMounts = lib.foldr lib.recursiveUpdate { } (lib.imap (index: partition: - lib.optionalAttrs (partition.content != null) (partition.content._mount { dev = "/dev/disk/by-partlabel/${partition.label}"; }) + lib.optionalAttrs (partition.content != null) partition.content._mount ) (lib.attrValues config.partitions)); in @@ -107,10 +117,9 @@ _config = lib.mkOption { internal = true; readOnly = true; - default = dev: - lib.imap - (index: partition: - lib.optional (partition.content != null) (partition.content._config "/dev/disk/by-partlabel/${partition.label}") + default = map + (partition: + lib.optional (partition.content != null) partition.content._config ) (lib.attrValues config.partitions); description = "NixOS configuration"; diff --git a/lib/types/luks.nix b/lib/types/luks.nix index 55fd994..713afef 100644 --- a/lib/types/luks.nix +++ b/lib/types/luks.nix @@ -1,4 +1,4 @@ -{ config, options, lib, diskoLib, parent, ... }: +{ config, options, lib, diskoLib, parent, device, ... }: { options = { type = lib.mkOption { @@ -6,6 +6,11 @@ internal = true; description = "Type"; }; + device = lib.mkOption { + type = lib.types.str; + description = "Device to encrypt"; + default = device; + }; name = lib.mkOption { type = lib.types.str; description = "Name of the LUKS"; @@ -33,7 +38,7 @@ description = "Extra arguments to pass to `cryptsetup luksOpen` when opening"; example = [ "--allow-discards" ]; }; - content = diskoLib.deviceType { parent = config; }; + content = diskoLib.deviceType { parent = config; device = "/dev/mapper/${config.name}"; }; _parent = lib.mkOption { internal = true; default = parent; @@ -48,22 +53,22 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' - cryptsetup -q luksFormat ${dev} ${diskoLib.maybeStr config.keyFile} ${toString config.extraFormatArgs} - cryptsetup luksOpen ${dev} ${config.name} ${toString config.extraOpenArgs} ${lib.optionalString (config.keyFile != null) "--key-file ${config.keyFile}"} - ${lib.optionalString (config.content != null) (config.content._create {dev = "/dev/mapper/${config.name}";})} + default = '' + cryptsetup -q luksFormat ${config.device} ${diskoLib.maybeStr config.keyFile} ${toString config.extraFormatArgs} + cryptsetup luksOpen ${config.device} ${config.name} ${toString config.extraOpenArgs} ${lib.optionalString (config.keyFile != null) "--key-file ${config.keyFile}"} + ${lib.optionalString (config.content != null) config.content._create} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: + default = let - contentMount = config.content._mount { dev = "/dev/mapper/${config.name}"; }; + contentMount = config.content._mount; in { dev = '' cryptsetup status ${config.name} >/dev/null 2>/dev/null || - cryptsetup luksOpen ${dev} ${config.name} ${lib.optionalString (config.keyFile != null) "--key-file ${config.keyFile}"} + cryptsetup luksOpen ${config.device} ${config.name} ${lib.optionalString (config.keyFile != null) "--key-file ${config.keyFile}"} ${lib.optionalString (config.content != null) contentMount.dev or ""} ''; fs = lib.optionalAttrs (config.content != null) contentMount.fs or { }; @@ -72,10 +77,10 @@ _config = lib.mkOption { internal = true; readOnly = true; - default = dev: [ ] + default = [ ] # If initrdUnlock is true, then add a device entry to the initrd.luks.devices config. - ++ (lib.optional config.initrdUnlock [{ boot.initrd.luks.devices.${config.name}.device = dev; }]) - ++ (lib.optional (config.content != null) (config.content._config "/dev/mapper/${config.name}")); + ++ (lib.optional config.initrdUnlock [{ boot.initrd.luks.devices.${config.name}.device = config.device; }]) + ++ (lib.optional (config.content != null) config.content._config); description = "NixOS configuration"; }; _pkgs = lib.mkOption { diff --git a/lib/types/lvm_pv.nix b/lib/types/lvm_pv.nix index 98c193a..067fff7 100644 --- a/lib/types/lvm_pv.nix +++ b/lib/types/lvm_pv.nix @@ -1,4 +1,4 @@ -{ config, options, lib, diskoLib, parent, ... }: +{ config, options, lib, diskoLib, parent, device, ... }: { options = { type = lib.mkOption { @@ -6,6 +6,11 @@ internal = true; description = "Type"; }; + device = lib.mkOption { + type = lib.types.str; + description = "Device"; + default = device; + }; vg = lib.mkOption { type = lib.types.str; description = "Volume group"; @@ -25,20 +30,19 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' - pvcreate ${dev} - echo "${dev}" >> "$disko_devices_dir"/lvm_${config.vg} + default = '' + pvcreate ${config.device} + echo "${config.device}" >> "$disko_devices_dir"/lvm_${config.vg} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: - { }; + default = { }; }; _config = lib.mkOption { internal = true; readOnly = true; - default = _dev: [ ]; + default = [ ]; description = "NixOS configuration"; }; _pkgs = lib.mkOption { diff --git a/lib/types/lvm_vg.nix b/lib/types/lvm_vg.nix index 53e3d31..55ec33e 100644 --- a/lib/types/lvm_vg.nix +++ b/lib/types/lvm_vg.nix @@ -12,11 +12,11 @@ description = "Type"; }; lvs = lib.mkOption { - type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: { + type = lib.types.attrsOf (lib.types.submodule ({ name, ... }@lv: { options = { name = lib.mkOption { type = lib.types.str; - default = config._module.args.name; + default = name; description = "Name of the logical volume"; }; size = lib.mkOption { @@ -33,7 +33,7 @@ default = [ ]; description = "Extra arguments"; }; - content = diskoLib.partitionType { parent = config; }; + content = diskoLib.partitionType { parent = config; device = "/dev/${config.name}/${lv.config.name}"; }; }; })); default = { }; @@ -53,7 +53,7 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = _: + default = let sortedLvs = lib.sort (a: _: !lib.hasInfix "100%" a.size) (lib.attrValues config.lvs); in @@ -69,17 +69,17 @@ ${lib.optionalString (lv.lvm_type != null) "--type=${lv.lvm_type}"} \ ${toString lv.extraArgs} \ ${config.name} - ${lib.optionalString (lv.content != null) (lv.content._create {dev = "/dev/${config.name}/${lv.name}";})} + ${lib.optionalString (lv.content != null) lv.content._create} '') sortedLvs} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = _: + default = let lvMounts = diskoLib.deepMergeMap (lv: - lib.optionalAttrs (lv.content != null) (lv.content._mount { dev = "/dev/${config.name}/${lv.name}"; }) + lib.optionalAttrs (lv.content != null) lv.content._mount ) (lib.attrValues config.lvs); in @@ -97,7 +97,7 @@ default = map (lv: [ - (lib.optional (lv.content != null) (lv.content._config "/dev/${config.name}/${lv.name}")) + (lib.optional (lv.content != null) lv.content._config) (lib.optional (lv.lvm_type != null) { boot.initrd.kernelModules = [ "dm-${lv.lvm_type}" ]; }) diff --git a/lib/types/mdadm.nix b/lib/types/mdadm.nix index f2edd6d..2392db3 100644 --- a/lib/types/mdadm.nix +++ b/lib/types/mdadm.nix @@ -22,7 +22,7 @@ default = "default"; description = "Metadata"; }; - content = diskoLib.deviceType { parent = config; }; + content = diskoLib.deviceType { parent = config; device = "/dev/md/${config.name}"; }; _meta = lib.mkOption { internal = true; readOnly = true; @@ -33,7 +33,7 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = _: '' + default = '' readarray -t disk_devices < <(cat "$disko_devices_dir"/raid_${config.name}) echo 'y' | mdadm --create /dev/md/${config.name} \ --level=${toString config.level} \ @@ -43,20 +43,20 @@ --homehost=any \ "''${disk_devices[@]}" udevadm trigger --subsystem-match=block; udevadm settle - ${lib.optionalString (config.content != null) (config.content._create {dev = "/dev/md/${config.name}";})} + ${lib.optionalString (config.content != null) config.content._create} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = _: - lib.optionalAttrs (config.content != null) (config.content._mount { dev = "/dev/md/${config.name}"; }); + default = + lib.optionalAttrs (config.content != null) config.content._mount; # TODO we probably need to assemble the mdadm somehow }; _config = lib.mkOption { internal = true; readOnly = true; default = - lib.optional (config.content != null) (config.content._config "/dev/md/${config.name}"); + lib.optional (config.content != null) config.content._config; description = "NixOS configuration"; }; _pkgs = lib.mkOption { diff --git a/lib/types/mdraid.nix b/lib/types/mdraid.nix index 79d097c..5e8b135 100644 --- a/lib/types/mdraid.nix +++ b/lib/types/mdraid.nix @@ -1,4 +1,4 @@ -{ config, options, lib, diskoLib, parent, ... }: +{ config, options, lib, diskoLib, parent, device, ... }: { options = { type = lib.mkOption { @@ -6,6 +6,11 @@ internal = true; description = "Type"; }; + device = lib.mkOption { + type = lib.types.str; + description = "Device"; + default = device; + }; name = lib.mkOption { type = lib.types.str; @@ -26,19 +31,18 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' - echo "${dev}" >> "$disko_devices_dir"/raid_${config.name} + default = '' + echo "${config.device}" >> "$disko_devices_dir"/raid_${config.name} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: - { }; + default = { }; }; _config = lib.mkOption { internal = true; readOnly = true; - default = _dev: [ ]; + default = [ ]; description = "NixOS configuration"; }; _pkgs = lib.mkOption { diff --git a/lib/types/nodev.nix b/lib/types/nodev.nix index 69ea6c2..fd2f51a 100644 --- a/lib/types/nodev.nix +++ b/lib/types/nodev.nix @@ -35,11 +35,11 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = _: ""; + default = ""; }; _mount = diskoLib.mkMountOption { inherit config options; - default = _: lib.optionalAttrs (config.mountpoint != null) { + default = lib.optionalAttrs (config.mountpoint != null) { fs.${config.mountpoint} = '' if ! findmnt ${config.fsType} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then mount -t ${config.fsType} ${config.device} "${rootMountPoint}${config.mountpoint}" \ diff --git a/lib/types/swap.nix b/lib/types/swap.nix index 496be46..688e914 100644 --- a/lib/types/swap.nix +++ b/lib/types/swap.nix @@ -1,4 +1,4 @@ -{ diskoLib, config, options, lib, parent, ... }: +{ diskoLib, config, options, lib, parent, device, ... }: { options = { type = lib.mkOption { @@ -6,6 +6,11 @@ internal = true; description = "Type"; }; + device = lib.mkOption { + type = lib.types.str; + default = device; + description = "Device"; + }; randomEncryption = lib.mkOption { type = lib.types.bool; default = false; @@ -24,16 +29,16 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' - mkswap ${dev} + default = '' + mkswap ${config.device} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: { - fs.${dev} = '' - if ! swapon --show | grep -q '^${dev} '; then - swapon ${dev} + default = { + fs.${config.device} = '' + if ! swapon --show | grep -q '^${config.device} '; then + swapon ${config.device} fi ''; }; @@ -41,9 +46,9 @@ _config = lib.mkOption { internal = true; readOnly = true; - default = dev: [{ + default = [{ swapDevices = [{ - device = dev; + device = config.device; randomEncryption = config.randomEncryption; }]; }]; diff --git a/lib/types/table.nix b/lib/types/table.nix index 9353507..9e5d9c1 100644 --- a/lib/types/table.nix +++ b/lib/types/table.nix @@ -1,4 +1,4 @@ -{ config, options, lib, diskoLib, parent, ... }: +{ config, options, lib, diskoLib, parent, device, ... }: { options = { type = lib.mkOption { @@ -6,13 +6,18 @@ internal = true; description = "Partition table"; }; + device = lib.mkOption { + type = lib.types.str; + default = device; + description = "Device to partition"; + }; format = lib.mkOption { type = lib.types.enum [ "gpt" "msdos" ]; default = "gpt"; description = "The kind of partition table"; }; partitions = lib.mkOption { - type = lib.types.listOf (lib.types.submodule ({ ... }: { + type = lib.types.listOf (lib.types.submodule ({ name, ... }@partition: { options = { part-type = lib.mkOption { type = lib.types.enum [ "primary" "logical" "extended" ]; @@ -48,7 +53,11 @@ default = false; description = "Whether to make the partition bootable"; }; - content = diskoLib.partitionType { parent = config; }; + content = diskoLib.partitionType { parent = config; device = diskoLib.deviceNumbering config.device partition.config._index; }; + _index = lib.mkOption { + internal = true; + default = lib.toInt (lib.head (builtins.match ".*entry ([[:digit:]]+)]" name)); + }; }; })); default = [ ]; @@ -72,36 +81,36 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' - parted -s ${dev} -- mklabel ${config.format} - ${lib.concatStrings (lib.imap (index: partition: '' + default = '' + parted -s ${config.device} -- mklabel ${config.format} + ${lib.concatStrings (map (partition: '' ${lib.optionalString (config.format == "gpt") '' - parted -s ${dev} -- mkpart ${partition.name} ${diskoLib.maybeStr partition.fs-type} ${partition.start} ${partition.end} + parted -s ${config.device} -- mkpart ${partition.name} ${diskoLib.maybeStr partition.fs-type} ${partition.start} ${partition.end} ''} ${lib.optionalString (config.format == "msdos") '' - parted -s ${dev} -- mkpart ${partition.part-type} ${diskoLib.maybeStr partition.fs-type} ${diskoLib.maybeStr partition.fs-type} ${partition.start} ${partition.end} + parted -s ${config.device} -- mkpart ${partition.part-type} ${diskoLib.maybeStr partition.fs-type} ${diskoLib.maybeStr partition.fs-type} ${partition.start} ${partition.end} ''} # ensure /dev/disk/by-path/..-partN exists before continuing udevadm trigger --subsystem-match=block; udevadm settle ${lib.optionalString partition.bootable '' - parted -s ${dev} -- set ${toString index} boot on + parted -s ${config.device} -- set ${toString partition._index} boot on ''} ${lib.concatMapStringsSep "" (flag: '' - parted -s ${dev} -- set ${toString index} ${flag} on + parted -s ${config.device} -- set ${toString partition._index} ${flag} on '') partition.flags} # ensure further operations can detect new partitions udevadm trigger --subsystem-match=block; udevadm settle - ${lib.optionalString (partition.content != null) (partition.content._create { dev = diskoLib.deviceNumbering dev index; })} + ${lib.optionalString (partition.content != null) partition.content._create} '') config.partitions)} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: + default = let - partMounts = lib.foldr lib.recursiveUpdate { } (lib.imap - (index: partition: - lib.optionalAttrs (partition.content != null) (partition.content._mount { dev = diskoLib.deviceNumbering dev index; }) + partMounts = lib.foldr lib.recursiveUpdate { } (map + (partition: + lib.optionalAttrs (partition.content != null) partition.content._mount ) config.partitions); in @@ -113,10 +122,10 @@ _config = lib.mkOption { internal = true; readOnly = true; - default = dev: - lib.imap - (index: partition: - lib.optional (partition.content != null) (partition.content._config (diskoLib.deviceNumbering dev index)) + default = + map + (partition: + lib.optional (partition.content != null) partition.content._config ) config.partitions; description = "NixOS configuration"; diff --git a/lib/types/zfs.nix b/lib/types/zfs.nix index 7e7589a..bf7ea18 100644 --- a/lib/types/zfs.nix +++ b/lib/types/zfs.nix @@ -1,4 +1,4 @@ -{ config, options, lib, diskoLib, parent, ... }: +{ config, options, lib, diskoLib, parent, device, ... }: { options = { type = lib.mkOption { @@ -6,6 +6,11 @@ internal = true; description = "Type"; }; + device = lib.mkOption { + type = lib.types.str; + default = device; + description = "Device"; + }; pool = lib.mkOption { type = lib.types.str; description = "Name of the ZFS pool"; @@ -25,19 +30,18 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { dev }: '' - echo "${dev}" >> "$disko_devices_dir"/zfs_${config.pool} + default = '' + echo "${config.device}" >> "$disko_devices_dir"/zfs_${config.pool} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { dev }: - { }; + default = { }; }; _config = lib.mkOption { internal = true; readOnly = true; - default = _dev: [ ]; + default = [ ]; description = "NixOS configuration"; }; _pkgs = lib.mkOption { diff --git a/lib/types/zfs_fs.nix b/lib/types/zfs_fs.nix index c3e7ce5..7d84a85 100644 --- a/lib/types/zfs_fs.nix +++ b/lib/types/zfs_fs.nix @@ -46,18 +46,18 @@ # important to prevent accidental shadowing of mount points # since (create order != mount order) # -p creates parents automatically - default = { zpool }: '' - zfs create -up ${zpool}/${config.name} \ + default = '' + zfs create -up ${config._parent.name}/${config.name} \ ${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-o ${n}=${v}") config.options)} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { zpool }: + default = lib.optionalAttrs (config.options.mountpoint or "" != "none") { fs.${config.mountpoint} = '' - if ! findmnt ${zpool}/${config.name} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then - mount ${zpool}/${config.name} "${rootMountPoint}${config.mountpoint}" \ + if ! findmnt ${config._parent.name}/${config.name} "${rootMountPoint}${config.mountpoint}" > /dev/null 2>&1; then + mount ${config._parent.name}/${config.name} "${rootMountPoint}${config.mountpoint}" \ -o X-mount.mkdir \ ${lib.concatMapStringsSep " " (opt: "-o ${opt}") config.mountOptions} \ ${lib.optionalString ((config.options.mountpoint or "") != "legacy") "-o zfsutil"} \ @@ -69,10 +69,10 @@ _config = lib.mkOption { internal = true; readOnly = true; - default = zpool: + default = lib.optional (config.options.mountpoint or "" != "none") { fileSystems.${config.mountpoint} = { - device = "${zpool}/${config.name}"; + device = "${config._parent.name}/${config.name}"; fsType = "zfs"; options = config.mountOptions ++ lib.optional ((config.options.mountpoint or "") != "legacy") "zfsutil"; }; diff --git a/lib/types/zfs_volume.nix b/lib/types/zfs_volume.nix index bd231f9..e2c508e 100644 --- a/lib/types/zfs_volume.nix +++ b/lib/types/zfs_volume.nix @@ -30,7 +30,7 @@ description = "Size of the dataset"; }; - content = diskoLib.partitionType { parent = config; }; + content = diskoLib.partitionType { parent = config; device = "/dev/zvol/${config._parent.name}/${config.name}"; }; _parent = lib.mkOption { internal = true; @@ -46,23 +46,23 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = { zpool }: '' - zfs create ${zpool}/${config.name} \ + default = '' + zfs create ${config._parent.name}/${config.name} \ ${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-o ${n}=${v}") config.options)} -V ${config.size} udevadm trigger --subsystem-match=block; udevadm settle - ${lib.optionalString (config.content != null) (config.content._create {dev = "/dev/zvol/${zpool}/${config.name}";})} + ${lib.optionalString (config.content != null) config.content._create} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = { zpool }: - lib.optionalAttrs (config.content != null) (config.content._mount { dev = "/dev/zvol/${zpool}/${config.name}"; }); + default = + lib.optionalAttrs (config.content != null) config.content._mount; }; _config = lib.mkOption { internal = true; readOnly = true; - default = zpool: - lib.optional (config.content != null) (config.content._config "/dev/zvol/${zpool}/${config.name}"); + default = + lib.optional (config.content != null) config.content._config; description = "NixOS configuration"; }; _pkgs = lib.mkOption { diff --git a/lib/types/zpool.nix b/lib/types/zpool.nix index e53fea7..41c624a 100644 --- a/lib/types/zpool.nix +++ b/lib/types/zpool.nix @@ -65,21 +65,21 @@ }; _create = diskoLib.mkCreateOption { inherit config options; - default = _: '' + default = '' readarray -t zfs_devices < <(cat "$disko_devices_dir"/zfs_${config.name}) zpool create -f ${config.name} \ -R ${config.mountRoot} ${config.mode} \ ${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-o ${n}=${v}") config.options)} \ ${lib.concatStringsSep " " (lib.mapAttrsToList (n: v: "-O ${n}=${v}") config.rootFsOptions)} \ "''${zfs_devices[@]}" - ${lib.concatMapStrings (dataset: dataset._create {zpool = config.name;}) (lib.attrValues config.datasets)} + ${lib.concatMapStrings (dataset: dataset._create) (lib.attrValues config.datasets)} ''; }; _mount = diskoLib.mkMountOption { inherit config options; - default = _: + default = let - datasetMounts = diskoLib.deepMergeMap (dataset: dataset._mount { zpool = config.name; }) (lib.attrValues config.datasets); + datasetMounts = diskoLib.deepMergeMap (dataset: dataset._mount) (lib.attrValues config.datasets); in { dev = '' @@ -104,7 +104,7 @@ internal = true; readOnly = true; default = [ - (map (dataset: dataset._config config.name) (lib.attrValues config.datasets)) + (map (dataset: dataset._config) (lib.attrValues config.datasets)) (lib.optional (config.mountpoint != null) { fileSystems.${config.mountpoint} = { device = config.name;