From 88cb7a47196220431f45df6d9f616a63015deb4b Mon Sep 17 00:00:00 2001 From: lassulus Date: Wed, 24 Aug 2022 16:46:36 +0200 Subject: add mdadm support --- example/raid.nix | 60 ++++++++++++++++++++++++++++++++++++++++ lib/default.nix | 47 ++++++++++++++++++++++++-------- tests/test.nix | 83 ++------------------------------------------------------ 3 files changed, 99 insertions(+), 91 deletions(-) create mode 100644 example/raid.nix diff --git a/example/raid.nix b/example/raid.nix new file mode 100644 index 0000000..490ea01 --- /dev/null +++ b/example/raid.nix @@ -0,0 +1,60 @@ +# usage: nix-instantiate --eval --json --strict example/config.nix | jq . +{ + type = "devices"; + content = { + vdb = { + type = "table"; + format = "gpt"; + partitions = [ + { + type = "partition"; + part-type = "primary"; + start = "1MiB"; + end = "100%"; + content = { + type = "mdraid"; + name = "raid1"; + }; + } + ]; + }; + vdc = { + type = "table"; + format = "gpt"; + partitions = [ + { + type = "partition"; + part-type = "primary"; + start = "1MiB"; + end = "100%"; + content = { + type = "mdraid"; + name = "raid1"; + }; + } + ]; + }; + raid1 = { + type = "mdadm"; + level = 1; + content = { + type = "table"; + format = "gpt"; + partitions = [ + { + type = "partition"; + part-type = "primary"; + start = "1MiB"; + end = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/raid"; + }; + } + ]; + + }; + }; + }; +} diff --git a/lib/default.nix b/lib/default.nix index f2908f5..7a49642 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -2,12 +2,7 @@ with lib; with builtins; -let { - - body.config = config-f {}; - body.create = create-f {}; - body.mount = mount-f {}; - +let helper.find-device = device: let environment = helper.device-id device; @@ -16,14 +11,14 @@ let { if hasPrefix "/dev/disk" device then "${environment}='${device}'" else '' - ${environment}=$(for x in /dev/disk/by-path/*; do + ${environment}=$(for x in $(find /dev/disk/{by-path,by-id}/); do dev=$x - if [ "$(readlink -f $x)" = '${device}' ]; then + if [ "$(readlink -f $x)" = "$(readlink -f '${device}')" ]; then target=$dev break fi done - if test -z $target; then + if test -z ''${target+x}; then echo 'unable to find path of disk: ${device}, bailing out' >&2 exit 1 else @@ -71,8 +66,23 @@ let { mkfs.${x.format} ${q.device} ''; - create.devices = q: x: '' - ${concatStrings (mapAttrsToList (name: create-f { device = "/dev/${name}"; }) x.content)} + create.devices = q: x: let + raid-devices = lib.filterAttrs (_: dev: dev.type == "mdadm") x.content; + other-devices = lib.filterAttrs (_: dev: dev.type != "mdadm") x.content; + in '' + ${concatStrings (mapAttrsToList (name: create-f { device = "/dev/${name}"; }) other-devices)} + ${concatStrings (mapAttrsToList (name: create-f { device = "/dev/${name}"; name = name; }) raid-devices)} + ''; + + create.mdraid = q: x: '' + RAIDDEVICES_N_${x.name}=$((''${RAIDDEVICES_N_${x.name}:-0}+1)) + RAIDDEVICES_${x.name}="''${RAIDDEVICES_${x.name}:-}${q.device} " + ''; + + create.mdadm = q: x: '' + echo 'y' | mdadm --create /dev/md/${q.name} --level=${toString x.level or 1} --raid-devices=''${RAIDDEVICES_N_${q.name}} ''${RAIDDEVICES_${q.name}} + udevadm trigger --subsystem-match=block; udevadm settle + ${create-f { device = "/dev/md/${q.name}"; } x.content} ''; create.luks = q: x: '' @@ -158,6 +168,10 @@ let { mount.noop = q: x: {}; + # TODO maybe we need to do something here? + mount.mdadm = mount.noop; + mount.mdraid = mount.noop; + mount.partition = q: x: mount-f { device = "\"\${${q.device}}\"-part" + toString q.index; } x.content; @@ -166,4 +180,15 @@ let { (foldl' recursiveUpdate {} (imap (index: mount-f (q // { inherit index; device = helper.device-id q.device; })) x.partitions)) {table.${q.device} = helper.find-device q.device;} ); +in { + config = config-f {}; + create = cfg: '' + set -efux + ${create-f {} cfg} + ''; + mount = cfg: '' + set -efux + ${mount-f {} cfg} + ''; + } diff --git a/tests/test.nix b/tests/test.nix index 82976ba..1384590 100644 --- a/tests/test.nix +++ b/tests/test.nix @@ -7,84 +7,7 @@ let inherit pkgs; inherit (pkgs) system; }; - disko-config = { - type = "devices"; - content = { - vdb = { - type = "table"; - format = "gpt"; - partitions = [ - { - type = "partition"; - part-type = "ESP"; - start = "1MiB"; - end = "100MiB"; - fs-type = "FAT32"; - bootable = true; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - options = [ - "defaults" - ]; - }; - } - { - type = "partition"; - part-type = "primary"; - start = "100MiB"; - end = "100%"; - content = { - type = "luks"; - algo = "aes-xts..."; - name = "crypted"; - keyfile = "/tmp/secret.key"; - extraArgs = [ - "--hash sha512" - "--iter-time 5000" - ]; - content = { - type = "lvm"; - name = "pool"; - lvs = { - root = { - type = "lv"; - size = "100M"; - mountpoint = "/"; - content = { - type = "filesystem"; - format = "ext4"; - mountpoint = "/"; - options = [ - "defaults" - ]; - }; - }; - home = { - type = "lv"; - size = "10M"; - content = { - type = "filesystem"; - format = "ext4"; - mountpoint = "/home"; - }; - }; - raw = { - type = "lv"; - size = "10M"; - content = { - type = "noop"; - }; - }; - }; - }; - }; - } - ]; - }; - }; - }; + disko-config = import ../example/raid.nix; tsp-create = pkgs.writeScript "create" ((pkgs.callPackage ../. {}).create disko-config); tsp-mount = pkgs.writeScript "mount" ((pkgs.callPackage ../. {}).mount disko-config); in makeTest' { @@ -102,7 +25,7 @@ in makeTest' { # speed-up eval documentation.enable = false; - virtualisation.emptyDiskImages = [ 512 ]; + virtualisation.emptyDiskImages = [ 512 512 ]; }; testScript = '' @@ -110,6 +33,6 @@ in makeTest' { machine.succeed("${tsp-create}"); machine.succeed("${tsp-mount}"); machine.succeed("${tsp-mount}"); # verify that the command is idempotent - machine.succeed("test -b /dev/mapper/pool-raw"); + machine.succeed("test -b /dev/md/raid1"); ''; } -- cgit v1.2.3