diff --git a/README.md b/README.md index 07810461..00c93a5d 100644 --- a/README.md +++ b/README.md @@ -248,5 +248,9 @@ For the deployment options take a look at [deployment](https://gitea.c3d2.de/c3d ## ZFS setup -Please refer to [disko](./disko) +Set the `disko` options for the machine and run: + +``` +$(nix build --print-out-paths --no-link -L '.#nixosConfigurations.HOSTNAME.config.system.build.disko') +``` diff --git a/disko/README.md b/disko/README.md deleted file mode 100644 index debfefb5..00000000 --- a/disko/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Disko - -Usage: - -```bash -./format-disk.sh --name nixbert --disk /dev/sda -``` - -See ``./format-disk.sh --help`` for more options like disable luks, ceph or zfs. - -For example: - -```bash -./format-disk.sh --name nixbert --disk /dev/sda --no-ceph --no-luks --no-zfs -``` diff --git a/disko/disko-config.nix b/disko/disko-config.nix deleted file mode 100644 index d333473c..00000000 --- a/disko/disko-config.nix +++ /dev/null @@ -1,162 +0,0 @@ -{ lib -, name ? "chaos" -, useConfig ? false -, config ? "" -, disk ? "/dev/sda1" -, enableCeph ? true -, enableLuks ? true -, enableZfs ? true -, ... -}: - -assert lib.assertMsg (enableCeph || enableZfs) "Must enable ceph or zfs!"; -assert lib.assertMsg (enableCeph -> enableLuks) "Ceph requires Luks!"; - -{ - 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"; - dnodesize = "auto"; - 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 deleted file mode 100755 index e9d3fb6d..00000000 --- a/disko/format-disk.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash -useConfig=false config='""' 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] --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 - ;; - "--name") - name=$2 - shift - ;; - "--config") - useConfig=true - if [[ $2 =~ ^-- ]]; then - config=$2 - shift - else - config=../hosts/$name/default.nix - fi - shift - ;; - "--disk") - disk=$2 - shift - ;; - "--no-ceph") ceph=false;; - "--no-luks") luks=false;; - "--no-zfs") zfs=false ;; - *) - echo "Argument $1 is not understood." - exit 2 - ;; - esac - shift -done - -if [[ -z ${name:-} && (-n ${config:-} || -n ${disk:-}) ]]; then - echo $name $config $disk - # 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 useConfig "$useConfig" --arg config "$config" \ - --arg enableCeph "$ceph" --arg enableLuks "$luks" --arg enableZfs "$zfs" diff --git a/flake.nix b/flake.nix index 67deff55..d5937742 100644 --- a/flake.nix +++ b/flake.nix @@ -79,6 +79,10 @@ zentralwerk.follows = "zentralwerk"; }; }; + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixos"; + }; fenix = { url = "github:nix-community/fenix/monthly"; inputs.nixpkgs.follows = "nixos"; @@ -202,7 +206,7 @@ }; }; - outputs = inputs@{ self, alert2muc, c3d2-user-module, deployment, fenix, heliwatch, microvm, naersk, nixos, nixos-hardware, nixos-modules, buzzrelay, caveman, oparl-scraper, scrapers, secrets, skyflake, sshlogd, sops-nix, spacemsg, ticker, tigger, yammat, zentralwerk, ... }: + outputs = inputs@{ self, alert2muc, c3d2-user-module, deployment, disko, fenix, heliwatch, microvm, naersk, nixos, nixos-hardware, nixos-modules, buzzrelay, caveman, oparl-scraper, scrapers, secrets, skyflake, sshlogd, sops-nix, spacemsg, ticker, tigger, yammat, zentralwerk, ... }: let inherit (nixos) lib; @@ -239,6 +243,7 @@ self.nixosModules.c3d2 c3d2-user-module.nixosModule + disko.nixosModules.disko nixos-modules.nixosModule ./config ./modules/pi-sensors.nix diff --git a/hosts/glotzbert/default.nix b/hosts/glotzbert/default.nix index 5642d417..83ff648d 100644 --- a/hosts/glotzbert/default.nix +++ b/hosts/glotzbert/default.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ config, pkgs, ... }: { imports = [ ./hardware-configuration.nix ]; @@ -9,6 +9,13 @@ autoUpdate = true; }; + disko = { + enableCeph = false; + enableLuks = false; + name = config.networking.hostName; + rootDisk = "/dev/sda"; + }; + nix.settings = { cores = 4; max-jobs = 4; diff --git a/modules/disko.nix b/modules/disko.nix index e621fdde..0513f124 100644 --- a/modules/disko.nix +++ b/modules/disko.nix @@ -1,7 +1,8 @@ -{ lib, ... }: - -# none functional until https://github.com/nix-community/disko/issues/219 is resolved +{ config, lib, ... }: +let + cfg = config.disko; +in { options.disko = { name = lib.mkOption { @@ -11,7 +12,8 @@ }; rootDisk = lib.mkOption { - type = lib.types.str; + type = with lib.types; nullOr str; + default = null; example = "/dev/sda"; description = "Path of the root disk."; }; @@ -34,4 +36,151 @@ description = "Wether to include a zfs on the root disk."; }; }; + + config = { + assertions = [ + { + assertion = cfg.enableCeph || cfg.enableZfs; + message = "Must enable ceph or zfs!"; + } + { + assertion = cfg.enableCeph -> cfg.enableLuks; + message = "Ceph requires Luks!"; + } + ]; + + disko.devices = + let + rootSize = 200; + zfs = { + size = if (!cfg.enableCeph) then "100%FREE" else "${toString rootSize}GiB"; + content = { + pool = cfg.name; + type = "zfs"; + }; + }; + in + lib.mkIf (cfg.rootDisk != "") { + disk.${cfg.rootDisk} = { + device = cfg.rootDisk; + type = "disk"; + content = { + type = "table"; + format = "gpt"; + partitions = lib.optional cfg.enableZfs + { + name = "ESP"; + start = "1MiB"; + end = "512MiB"; + bootable = true; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + } ++ [ + { + name = "root"; + start = if cfg.enableZfs then "512MiB" else "1MiB"; + end = "100%"; + part-type = "primary"; + content = lib.optionalAttrs cfg.enableLuks + { + type = "luks"; + name = "crypt-${cfg.name}"; + # TODO: add password, otherwise prompt opens + keyFile = "/$PWD/keyFile"; + content = { + type = "lvm_pv"; + vg = "lvm-${cfg.name}"; + }; + } // lib.optionalAttrs (!cfg.enableLuks) zfs.content; + } + ]; + }; + }; + } // lib.optionalAttrs cfg.enableLuks { + lvm_vg."lvm-${cfg.name}" = { + type = "lvm_vg"; + lvs = lib.optionalAttrs cfg.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 cfg.enableZfs { inherit zfs; }; + }; + } // { + zpool."${cfg.name}" = { + type = "zpool"; + mountpoint = null; + mountRoot = "/mnt"; + rootFsOptions.acltype = "posixacl"; + options = { + ashift = "12"; + autotrim = "on"; + }; + datasets = + let + dataset = mountpoint: { + options = { + canmount = "on"; + compression = "zstd"; + dnodesize = "auto"; + 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"; + }; + }; + }; + }; + }; }