diff --git a/machines/modules/disko/default.nix b/machines/modules/disko/default.nix new file mode 100644 index 00000000..d11b6f4e --- /dev/null +++ b/machines/modules/disko/default.nix @@ -0,0 +1,264 @@ +{config, lib, ...}: +let + cfg = config.malobeo.disks; +in +{ + options.malobeo.disks = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Enable disko disk creation"; + }; + hostId = lib.mkOption { + type = lib.types.str; + default = ""; + description = "Host ID for zfs disks, generate with 'head -c4 /dev/urandom | od -A none -t x4'"; + }; + devNodes = lib.mkOption { + type = lib.types.str; + default = "/dev/disk/by-id/"; + description = '' + where disks should be mounted from + https://openzfs.github.io/openzfs-docs/Project%20and%20Community/FAQ.html#selecting-dev-names-when-creating-a-pool-linux + use "/dev/disk/by-path/" for vm's + ''; + }; + root = { + disk0 = lib.mkOption { + type = lib.types.str; + default = ""; + description = "name ab /dev für root dateisystem"; + }; + disk1 = lib.mkOption { + type = lib.types.str; + default = ""; + description = "name ab /dev für eventuellen root mirror"; + }; + swap = lib.mkOption { + type = lib.types.str; + default = "8G"; + description = "size of swap partition (only disk0)"; + }; + reservation = lib.mkOption { + type = lib.types.str; + default = "20GiB"; + description = "zfs reservation"; + }; + mirror = lib.mkOption { + type = lib.types.bool; + default = false; + description = "mirror zfs root pool"; + }; + }; + storage = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Enable storage pool"; + }; + disks = lib.mkOption { + type = lib.types.listOf lib.types.str; + default = [ ]; + description = "name ab /dev/ für storage pool"; + example = "ata-ST16000NE000-2RW103_ZL2P0YSZ"; + }; + reservation = lib.mkOption { + type = lib.types.str; + default = "20GiB"; + description = "zfs reservation"; + }; + mirror = lib.mkOption { + type = lib.types.bool; + default = false; + description = "mirror zfs storage pool"; + }; + }; + }; + + config = lib.mkif cfg.enable { + networking.hostId = cfg.zfs.hostId; + disko.devices = { + disk = lib.mkMerge [ + { + ssd0 = lib.mkIf (cfg.root.disk0 != "") { + type = "disk"; + device = "/dev/${cfg.root.disk0}"; + content = { + type = "gpt"; + partitions = { + ESP = { + size = "1024M"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "umask=0077" ]; + }; + }; + encryptedSwap = { + size = cfg.root.swap; + content = { + type = "swap"; + randomEncryption = true; + }; + }; + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; + }; + ssd1 = lib.mkIf (cfg.root.disk1 != "") { + type = "disk"; + device = "/dev/${cfg.root.disk1}"; + content = { + type = "gpt"; + partitions = { + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; + }; + } + (lib.mkIf cfg.storage.enable ( + lib.mkMerge ( + map (diskname: { + "${diskname}" = { + type = "disk"; + device = "/dev/${diskname}"; + content = { + type = "gpt"; + partitions = { + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "storage"; + }; + }; + }; + }; + }; + }) cfg.storage.disks + ) + )) + ]; + + zpool = { + zroot = { + type = "zpool"; + mode = lib.mkIf cfg.root.mirror "mirror"; + # Workaround: cannot import 'zroot': I/O error in disko tests + options.cachefile = "none"; + rootFsOptions = { + mountpoint = "none"; + xattr = "sa"; # für microvm virtiofs mount + acltype = "posixacl"; # für microvm virtiofs mount + compression = "zstd"; + "com.sun:auto-snapshot" = "false"; + }; + + datasets = { + encrypted = { + type = "zfs_fs"; + options = { + mountpoint = "none"; + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + keylocation = "file:///tmp/root.key"; + }; + # use this to read the key during boot + postCreateHook = '' + zfs set keylocation="prompt" zroot/encrypted; + ''; + }; + "encrypted/root" = { + type = "zfs_fs"; + mountpoint = "/"; + }; + "encrypted/var" = { + type = "zfs_fs"; + mountpoint = "/var"; + }; + "encrypted/etc" = { + type = "zfs_fs"; + mountpoint = "/etc"; + }; + "encrypted/home" = { + type = "zfs_fs"; + mountpoint = "/home"; + }; + "encrypted/nix" = { + type = "zfs_fs"; + mountpoint = "/nix"; + }; + reserved = { + # for cow delete if pool is full + options = { + canmount = "off"; + mountpoint = "none"; + reservation = "${cfg.root.reservation}"; + }; + type = "zfs_fs"; + }; + }; + }; + + storage = lib.mkIf cfg.storage.enable { + type = "zpool"; + mode = lib.mkIf (cfg.storage.mirror) "mirror"; + rootFsOptions = { + mountpoint = "none"; + xattr = "sa"; # für microvm virtiofs mount + acltype = "posixacl"; # für microvm virtiofs mount + }; + datasets = { + encrypted = { + type = "zfs_fs"; + options = { + mountpoint = "none"; + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + keylocation = "file:///tmp/storage.key"; + }; + # use this to read the key during boot + postCreateHook = '' + zfs set keylocation="prompt" storage/encrypted; + ''; + }; + "encrypted/data" = { + type = "zfs_fs"; + mountpoint = "/data"; + }; + reserved = { + # for cow delete if pool is full + options = { + canmount = "off"; + mountpoint = "none"; + reservation = "${cfg.storage.reservation}"; + }; + type = "zfs_fs"; + }; + }; + }; + }; + }; + + fileSystems."/".neededForBoot = true; + fileSystems."/etc".neededForBoot = true; + fileSystems."/boot".neededForBoot = true; + fileSystems."/var".neededForBoot = true; + fileSystems."/home".neededForBoot = true; + fileSystems."/nix".neededForBoot = true; + }; +} diff --git a/machines/modules/disko/fanny.nix b/machines/modules/disko/fanny.nix deleted file mode 100644 index 0ac2a1c9..00000000 --- a/machines/modules/disko/fanny.nix +++ /dev/null @@ -1,157 +0,0 @@ -{ - disko.devices = { - disk = { - ssd = { - type = "disk"; - device = "/dev/sda"; - content = { - type = "gpt"; - partitions = { - ESP = { - size = "1024M"; - type = "EF00"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - mountOptions = [ "umask=0077" ]; - }; - }; - encryptedSwap = { - size = "8G"; #set to 100M for testing - content = { - type = "swap"; - randomEncryption = true; - }; - }; - zfs = { - size = "100%"; - content = { - type = "zfs"; - pool = "zroot"; - }; - }; - }; - }; - }; - - hdd0 = { - type = "disk"; - device = "/dev/sdb"; - content = { - type = "gpt"; - partitions = { - zfs = { - size = "100%"; - content = { - type = "zfs"; - pool = "storage"; - }; - }; - }; - }; - }; - - hdd1 = { - type = "disk"; - device = "/dev/sdc"; - content = { - type = "gpt"; - partitions = { - zfs = { - size = "100%"; - content = { - type = "zfs"; - pool = "storage"; - }; - }; - }; - }; - }; - }; - - zpool = { - zroot = { - type = "zpool"; - mode = ""; - # Workaround: cannot import 'zroot': I/O error in disko tests - options.cachefile = "none"; - rootFsOptions = { - mountpoint = "none"; - compression = "zstd"; - "com.sun:auto-snapshot" = "false"; - }; - - datasets = { - encrypted = { - type = "zfs_fs"; - options = { - mountpoint = "none"; - encryption = "aes-256-gcm"; - keyformat = "passphrase"; - keylocation = "file:///tmp/root.key"; - }; - # use this to read the key during boot - postCreateHook = '' - zfs set keylocation="prompt" zroot/encrypted; - ''; - }; - "encrypted/root" = { - type = "zfs_fs"; - mountpoint = "/"; - }; - "encrypted/var" = { - type = "zfs_fs"; - mountpoint = "/var"; - }; - "encrypted/etc" = { - type = "zfs_fs"; - mountpoint = "/etc"; - }; - "encrypted/home" = { - type = "zfs_fs"; - mountpoint = "/home"; - }; - "encrypted/nix" = { - type = "zfs_fs"; - mountpoint = "/nix"; - }; - }; - }; - - storage = { - type = "zpool"; - mode = "mirror"; - rootFsOptions = { mountpoint = "none"; }; - - datasets = { - encrypted = { - type = "zfs_fs"; - options = { - mountpoint = "none"; - encryption = "aes-256-gcm"; - keyformat = "passphrase"; - keylocation = "file:///tmp/storage.key"; - }; - - # use this to read the key during boot - postCreateHook = '' - zfs set keylocation="prompt" storage/encrypted; - ''; - }; - "encrypted/data" = { - type = "zfs_fs"; - mountpoint = "/data"; - }; - }; - }; - }; - }; - - fileSystems."/".neededForBoot = true; - fileSystems."/boot".neededForBoot = true; - fileSystems."/var".neededForBoot = true; - fileSystems."/etc".neededForBoot = true; - fileSystems."/home".neededForBoot = true; - fileSystems."/nix".neededForBoot = true; -} diff --git a/outputs.nix b/outputs.nix index 634d548b..10085926 100644 --- a/outputs.nix +++ b/outputs.nix @@ -117,6 +117,7 @@ in (utils.lib.eachSystem (builtins.filter filter_system utils.lib.defaultSystems microvm.imports = [ ./machines/modules/malobeo/microvm_host.nix ]; vpn.imports = [ ./machines/modules/malobeo/wireguard.nix ]; initssh.imports = [ ./machines/modules/malobeo/initssh.nix ]; + disko.imports = [ ./machines/modules/disko ]; }; hydraJobs = nixpkgs.lib.mapAttrs (_: nixpkgs.lib.hydraJob) (