about summary refs log tree commit diff
path: root/nixos/modules/virtualisation
diff options
context:
space:
mode:
authorOto Petřík <oto.petrik@gmail.com>2022-07-24 15:36:43 +0200
committerOto Petřík <oto.petrik@gmail.com>2022-11-09 03:19:42 +0100
commit4729d5d7f62a989c1518cac96a3a971da00a7d12 (patch)
tree501ca8d4148c5a8beb0d57b1aaa2196663a327ab /nixos/modules/virtualisation
parent8f0c7e38cbd47df68fa560a0c9ea5f42fb5f82e9 (diff)
nixos/proxmox-image: allow building UEFI images
Allow building other than Legacy-BIOS-only Proxmox images.
Default is unchanged.

To build UEFI proxmox image use:
  proxmox.qemuConf.bios = "ovmf";
(default is "seabios")

To build image bootable using both "seabios" and "ovmf" use:
  partitionTableType = "hybrid";
BIOS can be switched in Proxmox between "seabios" and "ovmf" and VM still boots.
(GRUB2-only, systemd-boot does not boot under "seabios")

To build systemd-boot UEFI image:
  proxmox.qemuConf.bios = "ovmf";
  boot.loader.systemd-boot.enable = true;
Diffstat (limited to 'nixos/modules/virtualisation')
-rw-r--r--nixos/modules/virtualisation/proxmox-image.nix59
1 files changed, 58 insertions, 1 deletions
diff --git a/nixos/modules/virtualisation/proxmox-image.nix b/nixos/modules/virtualisation/proxmox-image.nix
index 4fca8ce9e7eb6..42c52c12edf09 100644
--- a/nixos/modules/virtualisation/proxmox-image.nix
+++ b/nixos/modules/virtualisation/proxmox-image.nix
@@ -53,6 +53,13 @@ with lib;
           Guest memory in MB
         '';
       };
+      bios = mkOption {
+        type = types.enum [ "seabios" "ovmf" ];
+        default = "seabios";
+        description = ''
+          Select BIOS implementation (seabios = Legacy BIOS, ovmf = UEFI).
+        '';
+      };
 
       # optional configs
       name = mkOption {
@@ -99,6 +106,17 @@ with lib;
         Additional options appended to qemu-server.conf
       '';
     };
+    partitionTableType = mkOption {
+      type = types.enum [ "efi" "hybrid" "legacy" "legacy+gpt" ];
+      description = ''
+        Partition table type to use. See make-disk-image.nix partitionTableType for details.
+        Defaults to 'legacy' for 'proxmox.qemuConf.bios="seabios"' (default), other bios values defaults to 'efi'.
+        Use 'hybrid' to build grub-based hybrid bios+efi images.
+      '';
+      default = if config.proxmox.qemuConf.bios == "seabios" then "legacy" else "efi";
+      defaultText = lib.literalExpression ''if config.proxmox.qemuConf.bios == "seabios" then "legacy" else "efi"'';
+      example = "hybrid";
+    };
     filenameSuffix = mkOption {
       type = types.str;
       default = config.proxmox.qemuConf.name;
@@ -122,9 +140,33 @@ with lib;
       ${lib.concatStrings (lib.mapAttrsToList cfgLine properties)}
       #qmdump#map:virtio0:drive-virtio0:local-lvm:raw:
     '';
+    inherit (cfg) partitionTableType;
+    supportEfi = partitionTableType == "efi" || partitionTableType == "hybrid";
+    supportBios = partitionTableType == "legacy" || partitionTableType == "hybrid" || partitionTableType == "legacy+gpt";
+    hasBootPartition = partitionTableType == "efi" || partitionTableType == "hybrid";
+    hasNoFsPartition = partitionTableType == "hybrid" || partitionTableType == "legacy+gpt";
   in {
+    assertions = [
+      {
+        assertion = config.boot.loader.systemd-boot.enable -> config.proxmox.qemuConf.bios == "ovmf";
+        message = "systemd-boot requires 'ovmf' bios";
+      }
+      {
+        assertion = partitionTableType == "efi" -> config.proxmox.qemuConf.bios == "ovmf";
+        message = "'efi' disk partitioning requires 'ovmf' bios";
+      }
+      {
+        assertion = partitionTableType == "legacy" -> config.proxmox.qemuConf.bios == "seabios";
+        message = "'legacy' disk partitioning requires 'seabios' bios";
+      }
+      {
+        assertion = partitionTableType == "legacy+gpt" -> config.proxmox.qemuConf.bios == "seabios";
+        message = "'legacy+gpt' disk partitioning requires 'seabios' bios";
+      }
+    ];
     system.build.VMA = import ../../lib/make-disk-image.nix {
       name = "proxmox-${cfg.filenameSuffix}";
+      inherit partitionTableType;
       postVM = let
         # Build qemu with PVE's patch that adds support for the VMA format
         vma = (pkgs.qemu_kvm.override {
@@ -181,7 +223,18 @@ with lib;
     boot = {
       growPartition = true;
       kernelParams = [ "console=ttyS0" ];
-      loader.grub.device = lib.mkDefault "/dev/vda";
+      loader.grub = {
+        device = lib.mkDefault (if (hasNoFsPartition || supportBios) then
+          # Even if there is a separate no-fs partition ("/dev/disk/by-partlabel/no-fs" i.e. "/dev/vda2"),
+          # which will be used the bootloader, do not set it as loader.grub.device.
+          # GRUB installation fails, unless the whole disk is selected.
+          "/dev/vda"
+        else
+          "nodev");
+        efiSupport = lib.mkDefault supportEfi;
+        efiInstallAsRemovable = lib.mkDefault supportEfi;
+      };
+
       loader.timeout = 0;
       initrd.availableKernelModules = [ "uas" "virtio_blk" "virtio_pci" ];
     };
@@ -191,6 +244,10 @@ with lib;
       autoResize = true;
       fsType = "ext4";
     };
+    fileSystems."/boot" = lib.mkIf hasBootPartition {
+      device = "/dev/disk/by-label/ESP";
+      fsType = "vfat";
+    };
 
     services.qemuGuest.enable = lib.mkDefault true;
   };