From dadc49133042834dada6eafc98dcb1f7f2c5e43b Mon Sep 17 00:00:00 2001 From: lassulus Date: Thu, 25 Aug 2022 18:36:56 +0200 Subject: add lvm raid --- default.nix | 43 ++++++++++++++++++++------------ example/luks-lvm.nix | 69 +++++++++++++++++++++++++++------------------------- example/lvm-raid.nix | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/lvm-raid.nix | 39 +++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+), 49 deletions(-) create mode 100644 example/lvm-raid.nix create mode 100644 tests/lvm-raid.nix diff --git a/default.nix b/default.nix index 4a9a033..19333fc 100644 --- a/default.nix +++ b/default.nix @@ -52,10 +52,10 @@ let boot.initrd.luks.devices.${x.name}.device = q.device; } // config-f { device = "/dev/mapper/${x.name}"; } x.content; - config.lv = q: x: - config-f { device = "/dev/mapper/${q.vgname}-${q.name}"; } x.content; + config.lvm_lv = q: x: + config-f { device = "/dev/${q.vgname}/${q.name}"; } x.content; - config.lvm = q: x: + config.lvm_vg = q: x: foldl' recursiveUpdate {} (mapAttrsToList (name: config-f { inherit name; vgname = x.name; }) x.lvs); config.noop = q: x: {}; @@ -74,8 +74,8 @@ let ''; create.devices = q: x: let - raid-devices = lib.filterAttrs (_: dev: dev.type == "mdadm" || dev.type == "zpool") x.content; - other-devices = lib.filterAttrs (_: dev: dev.type != "mdadm" && dev.type != "zpool") x.content; + raid-devices = lib.filterAttrs (_: dev: dev.type == "mdadm" || dev.type == "zpool" || dev.type == "lvm_vg") x.content; + other-devices = lib.filterAttrs (_: dev: dev.type != "mdadm" && dev.type != "zpool" && dev.type != "lvm_vg") 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)} @@ -98,15 +98,24 @@ let ${create-f { device = "/dev/mapper/${x.name}"; } x.content} ''; - create.lv = q: x: '' - lvcreate ${if hasInfix "%" x.size then "-l" else "-L"} ${x.size} -n ${q.name} ${q.vgname} - ${create-f { device = "/dev/mapper/${q.vgname}-${q.name}"; } x.content} + create.lvm_pv = q: x: '' + pvcreate ${q.device} + LVMDEVICES_${x.vg}="''${LVMDEVICES_${x.vg}:-}${q.device} " ''; - create.lvm = q: x: '' - pvcreate ${q.device} - vgcreate ${x.name} ${q.device} - ${concatStrings (mapAttrsToList (name: create-f { inherit name; vgname = x.name; }) x.lvs)} + create.lvm_lv = q: x: '' + lvcreate \ + ${if hasInfix "%" x.size then "-l" else "-L"} ${x.size} \ + -n ${q.name} \ + ${lib.optionalString (!isNull x.lvm_type or null) "--type=${x.lvm_type}"} \ + ${lib.optionalString (!isNull x.extraArgs or null) x.extraArgs} \ + ${q.vgname} + ${create-f { device = "/dev/${q.vgname}/${q.name}"; } x.content} + ''; + + create.lvm_vg = q: x: '' + vgcreate ${q.name} $LVMDEVICES_${q.name} + ${concatStrings (mapAttrsToList (name: create-f { inherit name; vgname = q.name; }) x.lvs)} ''; create.noop = q: x: ""; @@ -190,17 +199,19 @@ let '';} ); - mount.lv = q: x: - mount-f { device = "/dev/mapper/${q.vgname}-${q.name}"; } x.content; + mount.lvm_lv = q: x: + mount-f { device = "/dev/${q.vgname}/${q.name}"; } x.content; - mount.lvm = q: x: ( + mount.lvm_vg = q: x: ( recursiveUpdate - (foldl' recursiveUpdate {} (mapAttrsToList (name: mount-f { inherit name; vgname = x.name; }) x.lvs)) + (foldl' recursiveUpdate {} (mapAttrsToList (name: mount-f { inherit name; vgname = q.name; }) x.lvs)) {lvm.${q.device} = '' vgchange -a y '';} ); + mount.lvm_pv = mount.noop; + mount.noop = q: x: {}; mount.mdadm = q: x: diff --git a/example/luks-lvm.nix b/example/luks-lvm.nix index d0b4d26..22c029e 100644 --- a/example/luks-lvm.nix +++ b/example/luks-lvm.nix @@ -36,43 +36,46 @@ "--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"; - }; - }; - }; + type = "lvm_pv"; + vg = "pool"; }; }; } ]; }; + pool = { + type = "lvm_vg"; + lvs = { + root = { + type = "lvm_lv"; + size = "100M"; + mountpoint = "/"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + options = [ + "defaults" + ]; + }; + }; + home = { + type = "lvm_lv"; + size = "10M"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/home"; + }; + }; + raw = { + type = "lvm_lv"; + size = "10M"; + content = { + type = "noop"; + }; + }; + }; + }; }; } diff --git a/example/lvm-raid.nix b/example/lvm-raid.nix new file mode 100644 index 0000000..48930ec --- /dev/null +++ b/example/lvm-raid.nix @@ -0,0 +1,66 @@ +{ + type = "devices"; + content = { + vdb = { + type = "table"; + format = "gpt"; + partitions = [ + { + type = "partition"; + part-type = "primary"; + start = "0%"; + end = "100%"; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + } + ]; + }; + vdc = { + type = "table"; + format = "gpt"; + partitions = [ + { + type = "partition"; + part-type = "primary"; + start = "0%"; + end = "100%"; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + } + ]; + }; + pool = { + type = "lvm_vg"; + lvs = { + root = { + type = "lvm_lv"; + size = "100M"; + mountpoint = "/"; + lvm_type = "mirror"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + options = [ + "defaults" + ]; + }; + }; + home = { + type = "lvm_lv"; + size = "10M"; + lvm_type = "raid0"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/home"; + }; + }; + }; + }; + }; +} diff --git a/tests/lvm-raid.nix b/tests/lvm-raid.nix new file mode 100644 index 0000000..5165645 --- /dev/null +++ b/tests/lvm-raid.nix @@ -0,0 +1,39 @@ +{ makeTest ? import +, pkgs ? (import {}) +}: +let + makeTest' = args: + makeTest args { + inherit pkgs; + inherit (pkgs) system; + }; + disko-config = import ../example/lvm-raid.nix; + tsp-create = pkgs.writeScript "create" ((pkgs.callPackage ../. {}).create disko-config); + tsp-mount = pkgs.writeScript "mount" ((pkgs.callPackage ../. {}).mount disko-config); +in makeTest' { + name = "disko"; + + nodes.machine = + { config, pkgs, modulesPath, ... }: + + { + imports = [ + (modulesPath + "/profiles/installation-device.nix") + (modulesPath + "/profiles/base.nix") + ]; + + # speed-up eval + documentation.enable = false; + + virtualisation.emptyDiskImages = [ 512 512 ]; + boot.kernelModules = [ "dm-raid" "dm-mirror" ]; + }; + + testScript = '' + machine.succeed("echo 'secret' > /tmp/secret.key"); + machine.succeed("${tsp-create}"); + machine.succeed("${tsp-mount}"); + machine.succeed("${tsp-mount}"); # verify that the command is idempotent + machine.succeed("grep -qs '/mnt/home' /proc/mounts"); + ''; +} -- cgit v1.2.3