summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlassulus <lassulus@lassul.us>2022-08-24 16:46:36 +0200
committerlassulus <lassulus@lassul.us>2022-08-24 20:15:18 +0200
commit88cb7a47196220431f45df6d9f616a63015deb4b (patch)
treeb796091caf6e392a3046aed292f45028facda7ff
parent9bca66ca7d2f8c9ac39d1f4a067ae45e681b87f9 (diff)
add mdadm support
-rw-r--r--example/raid.nix60
-rw-r--r--lib/default.nix47
-rw-r--r--tests/test.nix83
3 files changed, 99 insertions, 91 deletions
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");
'';
}