diff --git a/disko/disko-config.nix b/disko/disko-config.nix index 0cc95280..801bc740 100644 --- a/disko/disko-config.nix +++ b/disko/disko-config.nix @@ -1,5 +1,7 @@ { lib , name ? "chaos" +, useConfig ? false +, config ? "" , disk ? "/dev/sda1" , enableCeph ? true , enableLuks ? true @@ -11,136 +13,149 @@ assert lib.assertMsg (enableCeph || enableZfs) "Must enable ceph or zfs!"; assert lib.assertMsg (enableCeph -> enableLuks) "Ceph requires Luks!"; { - disko.devices = - let - rootSize = 200; - zfs = { - size = if (!enableCeph) then "100%FREE" else "${toString rootSize}GiB"; - content = { - pool = name; - type = "zfs"; - }; - }; - in - { - disk.${disk} = { - device = disk; - type = "disk"; - content = { - type = "table"; - format = "gpt"; - partitions = lib.optional enableZfs - { - name = "ESP"; - start = "1MiB"; - end = "512MiB"; - bootable = true; - content = { - type = "filesystem"; - format = "fat32"; - mountpoint = "/boot"; - }; - } ++ [ - { - name = "root"; - start = if enableZfs then "512MiB" else "1MiB"; - end = "100%"; - part-type = "primary"; - content = lib.optionalAttrs enableLuks - { - type = "luks"; - name = "crypt-${name}"; - # TODO: add password, otherwise prompt opens - keyFile = "/$PWD/keyFile"; - content = { - type = "lvm_pv"; - vg = "lvm-${name}"; - }; - } // lib.optionalAttrs (!enableLuks) zfs.content; - } - ]; - }; - }; - } // lib.optionalAttrs enableLuks { - lvm_vg."lvm-${name}" = { - type = "lvm_vg"; - lvs = lib.optionalAttrs enableCeph - { - # the header is 3650 byte long and substract an additional 446 byte for aligment - # error messages: - # Volume group "lvm-chaos" has insufficient free space (51195 extents): 51200 required. - # Size is not a multiple of 512. Try using 40057405440 or 40057405952. - ceph.size = - let - # convert GiB to bytes - rootSizeMiB = rootSize * 1024 * 1024 * 1024; - # convert back to MiB and allign to 4 MiB in the process - roundToMiB = "/1024/1024/4*4"; - # substract 512 MiB for /boot and 20 MiB for luks+header+other - bootOther = "-512-20"; - in - "$((($(lsblk /dev/sda --noheadings --nodeps --output SIZE --bytes)-${toString rootSizeMiB})${roundToMiB}${bootOther}))MiB"; - } // lib.optionalAttrs enableZfs { inherit zfs; }; - }; - } // { - zpool."${name}" = { - type = "zpool"; - mountpoint = "none"; - mountRoot = "/mnt"; - rootFsOptions.acltype = "posixacl"; - options = { - ashift = "12"; - autotrim = "on"; - }; - datasets = - let - dataset = mountpoint: { - options = { - canmount = "on"; - compression = "zstd"; - normalization = "formD"; - xattr = "sa"; - inherit mountpoint; - }; - type = "zfs_fs"; - }; - in - { - "data" = dataset "/"; - "data/etc" = dataset "/etc"; - "data/home" = dataset "/home"; - "data/var" = dataset "/var"; - # used by services.postgresqlBackup and later by restic - "data/var/backup" = dataset "/var/backup"; - "data/var/lib" = dataset "/var/lib"; - "data/var/log" = dataset "/var/log"; - "nixos" = { - options = { - canmount = "off"; - mountpoint = "none"; - }; - type = "zfs_fs"; - }; - "nixos/nix" = dataset "/nix"; - "nixos/nix/store" = { - options = { - atime = "off"; - canmount = "on"; - mountpoint = "/nix/store"; - }; - type = "zfs_fs"; - }; - "nixos/nix/var" = dataset "/nix/var"; - "reserved" = { - # zfs uses copy on write and requires some free space to delete files when the disk is completely filled - options = { - canmount = "off"; - mountpoint = "none"; - reservation = "5GiB"; - }; - type = "zfs_fs"; - }; + imports = [ + ../modules/disko.nix + ] ++ lib.optional useConfig config; + + disko = { + # TODO: deprecate? + name.default = name; + rootDisk.default = disk; + enableCeph.default = enableCeph; + enableLuks.default = enableLuks; + enableZfs.default = enableZfs; + + devices = + let + rootSize = 200; + zfs = { + size = if (!enableCeph) then "100%FREE" else "${toString rootSize}GiB"; + content = { + pool = name; + type = "zfs"; }; + }; + in + { + disk.${disk} = { + device = disk; + type = "disk"; + content = { + type = "table"; + format = "gpt"; + partitions = lib.optional enableZfs + { + name = "ESP"; + start = "1MiB"; + end = "512MiB"; + bootable = true; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + } ++ [ + { + name = "root"; + start = if enableZfs then "512MiB" else "1MiB"; + end = "100%"; + part-type = "primary"; + content = lib.optionalAttrs enableLuks + { + type = "luks"; + name = "crypt-${name}"; + # TODO: add password, otherwise prompt opens + keyFile = "/$PWD/keyFile"; + content = { + type = "lvm_pv"; + vg = "lvm-${name}"; + }; + } // lib.optionalAttrs (!enableLuks) zfs.content; + } + ]; + }; + }; + } // lib.optionalAttrs enableLuks { + lvm_vg."lvm-${name}" = { + type = "lvm_vg"; + lvs = lib.optionalAttrs enableCeph + { + # the header is 3650 byte long and substract an additional 446 byte for aligment + # error messages: + # Volume group "lvm-chaos" has insufficient free space (51195 extents): 51200 required. + # Size is not a multiple of 512. Try using 40057405440 or 40057405952. + ceph.size = + let + # convert GiB to bytes + rootSizeMiB = rootSize * 1024 * 1024 * 1024; + # convert back to MiB and allign to 4 MiB in the process + roundToMiB = "/1024/1024/4*4"; + # substract 512 MiB for /boot and 20 MiB for luks+header+other + bootOther = "-512-20"; + in + "$((($(lsblk /dev/sda --noheadings --nodeps --output SIZE --bytes)-${toString rootSizeMiB})${roundToMiB}${bootOther}))MiB"; + } // lib.optionalAttrs enableZfs { inherit zfs; }; + }; + } // { + zpool."${name}" = { + type = "zpool"; + mountpoint = null; + mountRoot = "/mnt"; + rootFsOptions.acltype = "posixacl"; + options = { + ashift = "12"; + autotrim = "on"; + }; + datasets = + let + dataset = mountpoint: { + options = { + canmount = "on"; + compression = "zstd"; + normalization = "formD"; + xattr = "sa"; + inherit mountpoint; + }; + type = "zfs_fs"; + }; + in + { + "data" = dataset "/"; + "data/etc" = dataset "/etc"; + "data/home" = dataset "/home"; + "data/var" = dataset "/var"; + # used by services.postgresqlBackup and later by restic + "data/var/backup" = dataset "/var/backup"; + "data/var/lib" = dataset "/var/lib"; + "data/var/log" = dataset "/var/log"; + "nixos" = { + options = { + canmount = "off"; + mountpoint = "none"; + }; + type = "zfs_fs"; + }; + "nixos/nix" = dataset "/nix"; + "nixos/nix/store" = { + options = { + atime = "off"; + canmount = "on"; + mountpoint = "/nix/store"; + }; + type = "zfs_fs"; + }; + "nixos/nix/var" = dataset "/nix/var"; + "reserved" = { + # zfs uses copy on write and requires some free space to delete files when the disk is completely filled + options = { + canmount = "off"; + mountpoint = "none"; + reservation = "5GiB"; + }; + type = "zfs_fs"; + }; + }; + }; }; - }; + }; } diff --git a/disko/format-disk.sh b/disko/format-disk.sh index 6d1a2482..a5e952fa 100755 --- a/disko/format-disk.sh +++ b/disko/format-disk.sh @@ -1,22 +1,35 @@ #!/usr/bin/env bash +useConfig=false config="" ceph=true luks=true zfs=true -ceph=true luks=true zfs=true +cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null || exit 1 while [[ $# -gt 0 ]]; do case "$1" in "-h" | "--help") echo "Usage:" - echo "$0 [-h|--help] --disk /dev/sdx --name chaos [--no-ceph] [--no-luks] [--no-zfs]" + echo "$0 [-h|--help] --name chaos [--config [hosts/\$name/default.nix]] [--disk /dev/sdx] [--no-ceph] [--no-luks] [--no-zfs]" + echo + echo "If only --config is supplied, the script tries to guess the nix file to import from --name." + echo "Note: --config is none working" exit 0 ;; - "--disk") - disk=$2 - shift - ;; "--name") name=$2 shift ;; + "--config") + useConfig=true + if [[ $2 =~ ^-- ]]; then + config=$2 + shift + else + config=../hosts/$name/default.nix + fi + shift + ;; + "--disk") + disk=$2 + ;; "--no-ceph") ceph=false;; "--no-luks") luks=false;; "--no-zfs") zfs=false ;; @@ -28,12 +41,13 @@ while [[ $# -gt 0 ]]; do shift done -if [[ -z ${disk:-} || -z ${name:-} ]]; then - echo "--disk and --name must be supplied!" +if [[ -z ${name:-} || (-n ${config:-} && -n ${disk:-}) ]]; then + # echo "--name and either config or disk must be supplied!" + echo "--name and disk must be supplied!" exit 1 fi # TODO: wait for https://github.com/nix-community/disko/pull/211 to be merged sudo nix run github:SuperSandro2000/disko/zpool-R -- --mode zap_create_mount ./disko-config.nix --debug \ - --arg disk '"'"$disk"'"' --arg name '"'"$name"'"' \ + --arg disk '"'"$disk"'"' --arg name '"'"$name"'"' --arg useConfig "$useConfig" --arg config "$config" \ --arg enableCeph "$ceph" --arg enableLuks "$luks" --arg enableZfs "$zfs" diff --git a/modules/disko.nix b/modules/disko.nix new file mode 100644 index 00000000..e621fdde --- /dev/null +++ b/modules/disko.nix @@ -0,0 +1,37 @@ +{ lib, ... }: + +# none functional until https://github.com/nix-community/disko/issues/219 is resolved + +{ + options.disko = { + name = lib.mkOption { + type = lib.types.str; + example = "chaos"; + description = "Machine name used in eg zpool name."; + }; + + rootDisk = lib.mkOption { + type = lib.types.str; + example = "/dev/sda"; + description = "Path of the root disk."; + }; + + enableCeph = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Wether to include a ceph on the root disk."; + }; + + enableLuks = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Wether to encrypt the root disk."; + }; + + enableZfs = lib.mkOption { + type = lib.types.bool; + default = true; + description = "Wether to include a zfs on the root disk."; + }; + }; +}