diff options
author | lassulus <lassulus@lassul.us> | 2022-08-24 22:24:33 +0200 |
---|---|---|
committer | lassulus <lassulus@lassul.us> | 2022-08-24 22:24:33 +0200 |
commit | 6b0b20da18cdffd09f04faee7128c557bcb9f054 (patch) | |
tree | b3da02282d31f5832d9dcf2ae8e282c87d772036 | |
parent | 1be70de384fd8bbba0a7d6ed1229af92159ce06f (diff) |
/lib -> /
-rw-r--r-- | default.nix | 197 | ||||
-rw-r--r-- | lib/default.nix | 194 |
2 files changed, 193 insertions, 198 deletions
diff --git a/default.nix b/default.nix index 6858c40..d20b67e 100644 --- a/default.nix +++ b/default.nix @@ -1,5 +1,194 @@ -{ lib ? (import <nixpkgs> {}).lib }: { - inherit (import ./lib { - inherit lib; - }) config create mount; +{ lib ? import <nixpkgs/lib> }: +with lib; +with builtins; + +let + + helper.find-device = device: let + environment = helper.device-id device; + in + # DEVICE points already to /dev/disk, so we don't handle it via /dev/disk/by-path + if hasPrefix "/dev/disk" device then + "${environment}='${device}'" + else '' + ${environment}=$(for x in $(find /dev/disk/{by-path,by-id}/); do + dev=$x + if [ "$(readlink -f $x)" = "$(readlink -f '${device}')" ]; then + target=$dev + break + fi + done + if test -z ''${target+x}; then + echo 'unable to find path of disk: ${device}, bailing out' >&2 + exit 1 + else + echo $target + fi) + ''; + + helper.device-id = device: "DEVICE${builtins.substring 0 5 (builtins.hashString "sha1" device)}"; + + config-f = q: x: config.${x.type} q x; + + config.filesystem = q: x: { + fileSystems.${x.mountpoint} = { + device = q.device; + fsType = x.format; + ${if x ? options then "options" else null} = x.options; + }; + }; + + config.devices = q: x: + foldl' recursiveUpdate {} (mapAttrsToList (name: config-f { device = "/dev/${name}"; }) x.content); + + config.luks = q: x: { + 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 = q: x: + foldl' recursiveUpdate {} (mapAttrsToList (name: config-f { inherit name; vgname = x.name; }) x.lvs); + + config.noop = q: x: {}; + + config.partition = q: x: + config-f { device = q.device + toString q.index; } x.content; + + config.table = q: x: + foldl' recursiveUpdate {} (imap (index: config-f (q // { inherit index; })) x.partitions); + + + create-f = q: x: create.${x.type} q x; + + create.filesystem = q: x: '' + mkfs.${x.format} ${q.device} + ''; + + 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: '' + cryptsetup -q luksFormat ${q.device} ${if builtins.hasAttr "keyfile" x then x.keyfile else ""} ${toString (x.extraArgs or [])} + cryptsetup luksOpen ${q.device} ${x.name} ${if builtins.hasAttr "keyfile" x then "--key-file " + x.keyfile else ""} + ${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 = q: x: '' + pvcreate ${q.device} + vgcreate ${x.name} ${q.device} + ${concatStrings (mapAttrsToList (name: create-f { inherit name; vgname = x.name; }) x.lvs)} + ''; + + create.noop = q: x: ""; + + create.partition = q: x: let + env = helper.device-id q.device; + in '' + parted -s "''${${env}}" mkpart ${x.part-type} ${x.fs-type or ""} ${x.start} ${x.end} + # ensure /dev/disk/by-path/..-partN exists before continuing + udevadm trigger --subsystem-match=block; udevadm settle + ${optionalString (x.bootable or false) '' + parted -s "''${${env}}" set ${toString q.index} boot on + ''} + ${concatMapStringsSep "" (flag: '' + parted -s "''${${env}}" set ${toString q.index} ${flag} on + '') (x.flags or [])} + ${create-f { device = "\"\${${env}}\"-part" + toString q.index; } x.content} + ''; + + create.table = q: x: '' + ${helper.find-device q.device} + parted -s "''${${helper.device-id q.device}}" mklabel ${x.format} + ${concatStrings (imap (index: create-f (q // { inherit index; })) x.partitions)} + ''; + + + mount-f = q: x: mount.${x.type} q x; + + mount.filesystem = q: x: { + fs.${x.mountpoint} = '' + if ! findmnt ${q.device} "/mnt${x.mountpoint}" > /dev/null 2>&1; then + mount ${q.device} "/mnt${x.mountpoint}" -o X-mount.mkdir + fi + ''; + }; + + mount.devices = q: x: let + z = foldl' recursiveUpdate {} (mapAttrsToList (name: mount-f { device = "/dev/${name}"; }) x.content); + # attrValues returns values sorted by name. This is important, because it + # ensures that "/" is processed before "/foo" etc. + in '' + ${optionalString (hasAttr "table" z) (concatStringsSep "\n" (attrValues z.table))} + ${optionalString (hasAttr "luks" z) (concatStringsSep "\n" (attrValues z.luks))} + ${optionalString (hasAttr "lvm" z) (concatStringsSep "\n" (attrValues z.lvm))} + ${optionalString (hasAttr "fs" z) (concatStringsSep "\n" (attrValues z.fs))} + ''; + + mount.luks = q: x: ( + recursiveUpdate + (mount-f { device = "/dev/mapper/${x.name}"; } x.content) + {luks.${q.device} = '' + cryptsetup luksOpen ${q.device} ${x.name} ${if builtins.hasAttr "keyfile" x then "--key-file " + x.keyfile else ""} + '';} + ); + + mount.lv = q: x: + mount-f { device = "/dev/mapper/${q.vgname}-${q.name}"; } x.content; + + mount.lvm = q: x: ( + recursiveUpdate + (foldl' recursiveUpdate {} (mapAttrsToList (name: mount-f { inherit name; vgname = x.name; }) x.lvs)) + {lvm.${q.device} = '' + vgchange -a y + '';} + ); + + 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; + + mount.table = q: x: ( + recursiveUpdate + (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/lib/default.nix b/lib/default.nix deleted file mode 100644 index 9d43553..0000000 --- a/lib/default.nix +++ /dev/null @@ -1,194 +0,0 @@ -{ lib }: -with lib; -with builtins; - -let - - helper.find-device = device: let - environment = helper.device-id device; - in - # DEVICE points already to /dev/disk, so we don't handle it via /dev/disk/by-path - if hasPrefix "/dev/disk" device then - "${environment}='${device}'" - else '' - ${environment}=$(for x in $(find /dev/disk/{by-path,by-id}/); do - dev=$x - if [ "$(readlink -f $x)" = "$(readlink -f '${device}')" ]; then - target=$dev - break - fi - done - if test -z ''${target+x}; then - echo 'unable to find path of disk: ${device}, bailing out' >&2 - exit 1 - else - echo $target - fi) - ''; - - helper.device-id = device: "DEVICE${builtins.substring 0 5 (builtins.hashString "sha1" device)}"; - - config-f = q: x: config.${x.type} q x; - - config.filesystem = q: x: { - fileSystems.${x.mountpoint} = { - device = q.device; - fsType = x.format; - ${if x ? options then "options" else null} = x.options; - }; - }; - - config.devices = q: x: - foldl' recursiveUpdate {} (mapAttrsToList (name: config-f { device = "/dev/${name}"; }) x.content); - - config.luks = q: x: { - 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 = q: x: - foldl' recursiveUpdate {} (mapAttrsToList (name: config-f { inherit name; vgname = x.name; }) x.lvs); - - config.noop = q: x: {}; - - config.partition = q: x: - config-f { device = q.device + toString q.index; } x.content; - - config.table = q: x: - foldl' recursiveUpdate {} (imap (index: config-f (q // { inherit index; })) x.partitions); - - - create-f = q: x: create.${x.type} q x; - - create.filesystem = q: x: '' - mkfs.${x.format} ${q.device} - ''; - - 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: '' - cryptsetup -q luksFormat ${q.device} ${if builtins.hasAttr "keyfile" x then x.keyfile else ""} ${toString (x.extraArgs or [])} - cryptsetup luksOpen ${q.device} ${x.name} ${if builtins.hasAttr "keyfile" x then "--key-file " + x.keyfile else ""} - ${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 = q: x: '' - pvcreate ${q.device} - vgcreate ${x.name} ${q.device} - ${concatStrings (mapAttrsToList (name: create-f { inherit name; vgname = x.name; }) x.lvs)} - ''; - - create.noop = q: x: ""; - - create.partition = q: x: let - env = helper.device-id q.device; - in '' - parted -s "''${${env}}" mkpart ${x.part-type} ${x.fs-type or ""} ${x.start} ${x.end} - # ensure /dev/disk/by-path/..-partN exists before continuing - udevadm trigger --subsystem-match=block; udevadm settle - ${optionalString (x.bootable or false) '' - parted -s "''${${env}}" set ${toString q.index} boot on - ''} - ${concatMapStringsSep "" (flag: '' - parted -s "''${${env}}" set ${toString q.index} ${flag} on - '') (x.flags or [])} - ${create-f { device = "\"\${${env}}\"-part" + toString q.index; } x.content} - ''; - - create.table = q: x: '' - ${helper.find-device q.device} - parted -s "''${${helper.device-id q.device}}" mklabel ${x.format} - ${concatStrings (imap (index: create-f (q // { inherit index; })) x.partitions)} - ''; - - - mount-f = q: x: mount.${x.type} q x; - - mount.filesystem = q: x: { - fs.${x.mountpoint} = '' - if ! findmnt ${q.device} "/mnt${x.mountpoint}" > /dev/null 2>&1; then - mount ${q.device} "/mnt${x.mountpoint}" -o X-mount.mkdir - fi - ''; - }; - - mount.devices = q: x: let - z = foldl' recursiveUpdate {} (mapAttrsToList (name: mount-f { device = "/dev/${name}"; }) x.content); - # attrValues returns values sorted by name. This is important, because it - # ensures that "/" is processed before "/foo" etc. - in '' - ${optionalString (hasAttr "table" z) (concatStringsSep "\n" (attrValues z.table))} - ${optionalString (hasAttr "luks" z) (concatStringsSep "\n" (attrValues z.luks))} - ${optionalString (hasAttr "lvm" z) (concatStringsSep "\n" (attrValues z.lvm))} - ${optionalString (hasAttr "fs" z) (concatStringsSep "\n" (attrValues z.fs))} - ''; - - mount.luks = q: x: ( - recursiveUpdate - (mount-f { device = "/dev/mapper/${x.name}"; } x.content) - {luks.${q.device} = '' - cryptsetup luksOpen ${q.device} ${x.name} ${if builtins.hasAttr "keyfile" x then "--key-file " + x.keyfile else ""} - '';} - ); - - mount.lv = q: x: - mount-f { device = "/dev/mapper/${q.vgname}-${q.name}"; } x.content; - - mount.lvm = q: x: ( - recursiveUpdate - (foldl' recursiveUpdate {} (mapAttrsToList (name: mount-f { inherit name; vgname = x.name; }) x.lvs)) - {lvm.${q.device} = '' - vgchange -a y - '';} - ); - - 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; - - mount.table = q: x: ( - recursiveUpdate - (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} - ''; - -} |