From e84aaf361d5987943fd340c5ff1c3da5efdc2809 Mon Sep 17 00:00:00 2001 From: Felix Stupp Date: Mon, 26 Aug 2024 00:46:06 +0000 Subject: [PATCH] nixosMod: add vmDisko module --- nix/nixos-modules/default.nix | 1 + nix/nixos-modules/vmDisko/default.nix | 115 ++++++++++++++++++++++++++ nix/nixos-modules/vmDisko/ext4-1.nix | 29 +++++++ 3 files changed, 145 insertions(+) create mode 100644 nix/nixos-modules/vmDisko/default.nix create mode 100644 nix/nixos-modules/vmDisko/ext4-1.nix diff --git a/nix/nixos-modules/default.nix b/nix/nixos-modules/default.nix index 9b6b111..5fd3035 100644 --- a/nix/nixos-modules/default.nix +++ b/nix/nixos-modules/default.nix @@ -26,6 +26,7 @@ in ./extends ./frontend ./improvedDefaults + ./vmDisko # files ./allCommon.nix ./autoUnfree.nix diff --git a/nix/nixos-modules/vmDisko/default.nix b/nix/nixos-modules/vmDisko/default.nix new file mode 100644 index 0000000..7c6c550 --- /dev/null +++ b/nix/nixos-modules/vmDisko/default.nix @@ -0,0 +1,115 @@ +{ + config, + lib, + options, + ... +}: +let + self = options.x-banananetwork.vmDisko; + cfg = config.x-banananetwork.vmDisko; +in +{ + + # TODO upstream that to disko + + options.x-banananetwork.vmDisko = { + + enable = lib.mkEnableOption '' + VM disk configuration with disko. + Will be automatically enabled when option{x-banananetwork.vmDisko.generation} is manually set. + ''; + + mainDiskName = lib.mkOption { + description = '' + Name of the main disk. + + Similar to {option}`system.stateVersion`, + **do not change this** unless you know what you are doing. + ''; + type = lib.types.str; + }; + + generation = lib.mkOption { + description = '' + Disk generation to use. + + Similar to {option}`system.stateVersion`, + **do not change this** unless you know what you are doing. + + See option {option}`x-banananetwork.vmDisko.generations` + for a list of all generations available. + ''; + type = with lib.types; nullOr str; + default = null; + example = self.recommendedGeneration.default; + }; + + recommendedGeneration = lib.mkOption { + description = '' + Disk generation recommended to use for new systems. + ''; + default = "ext4-1"; + readOnly = true; + }; + + generationsDir = lib.mkOption { + description = '' + Directories where to search for generations. + + A generation must at least use one disk with the attr name `main` + (through its label name can be different) + because VMs are expected to have at least one disk as their primary available. + ''; + type = lib.types.path; + default = ./.; + example = ./.; + }; + + generationPath = lib.mkOption { + description = "Path to selected generation template."; + readOnly = true; + type = lib.types.path; + default = + let + path = cfg.generationsDir + "/${cfg.generation}"; + in + if builtins.pathExists path then path else path + ".nix"; + defaultText = lib.literalExpression '' + with config.x-banananetwork.vmDisko; + generationsDir + ("/''${generation}" or "/''${generation}.nix") + ''; + }; + + }; + + config = lib.mkMerge [ + (lib.mkIf (cfg.generation != null) { x-banananetwork.vmDisko.enable = true; }) + (lib.mkIf cfg.enable { + + assertions = [ + { + assertion = cfg.enable -> cfg.generation != null; + message = "x-banananetwork.vmDisko.generation must be set. Currently \"${cfg.recommendedGeneration}\" is recommended."; + } + { + assertion = cfg.generation != null -> builtins.pathExists cfg.generationPath; + message = "generation \"${cfg.generation}\" was not found in ${cfg.generationPath}"; + } + ]; + + disko.devices = lib.mkMerge [ + (import cfg.generationPath) + { + # avoid mixing VM disks + # hint: mkOverride required because + # - cfg.generations from above is already type-checked, hence priorities are discharged + # - assigment from above has default priority of 100 + #disk.main.name = lib.mkOverride 99 cfg.mainDiskName; + disk.main.name = cfg.mainDiskName; + } + ]; + + }) + ]; + +} diff --git a/nix/nixos-modules/vmDisko/ext4-1.nix b/nix/nixos-modules/vmDisko/ext4-1.nix new file mode 100644 index 0000000..ce22033 --- /dev/null +++ b/nix/nixos-modules/vmDisko/ext4-1.nix @@ -0,0 +1,29 @@ +{ + disk = { + main = { + type = "disk"; + content = { + type = "gpt"; + partitions = { + ESP = { + type = "EF00"; + size = "500M"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + size = "100%"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + }; + }; + }; + }; + }; + }; +}