lib.types: turn _create, _mount and _config into values

This commit is contained in:
lassulus 2023-07-01 19:02:01 +02:00 committed by mergify[bot]
parent 8002e7cb89
commit ab9b880db2
17 changed files with 194 additions and 146 deletions

View file

@ -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)}

View file

@ -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;
};

View file

@ -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 {

View file

@ -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;
};

View file

@ -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";

View file

@ -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 {

View file

@ -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 {

View file

@ -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}" ];
})

View file

@ -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 {

View file

@ -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 {

View file

@ -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}" \

View file

@ -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;
}];
}];

View file

@ -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";

View file

@ -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 {

View file

@ -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";
};

View file

@ -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 {

View file

@ -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;