Commit 2e87d3da authored by Oto Petřík's avatar Oto Petřík Committed by Martin Weinelt
Browse files

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;

(cherry picked from commit 4729d5d7)
parent 8b8d92ec
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -1462,6 +1462,26 @@ services.github-runner.serviceOverrides.SupplementaryGroups = [
          if you intend to add packages to <literal>/bin</literal>.
        </para>
      </listitem>
      <listitem>
        <para>
          The <literal>proxmox.qemuConf.bios</literal> option was added,
          it corresponds to <literal>Hardware-&gt;BIOS</literal> field
          in Proxmox web interface. Use
          <literal>&quot;ovmf&quot;</literal> value to build UEFI image,
          default value remains <literal>&quot;bios&quot;</literal>. New
          option <literal>proxmox.partitionTableType</literal> defaults
          to either <literal>&quot;legacy&quot;</literal> or
          <literal>&quot;efi&quot;</literal>, depending on the
          <literal>bios</literal> value. Setting
          <literal>partitionTableType</literal> to
          <literal>&quot;hybrid&quot;</literal> results in an image,
          which supports both methods
          (<literal>&quot;bios&quot;</literal> and
          <literal>&quot;ovmf&quot;</literal>), thereby remaining
          bootable after change to Proxmox
          <literal>Hardware-&gt;BIOS</literal> field.
        </para>
      </listitem>
      <listitem>
        <para>
          memtest86+ was updated from 5.00-coreboot-002 to 6.00-beta2.
+2 −0
Original line number Diff line number Diff line
@@ -475,6 +475,8 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
- `dockerTools.buildImage` deprecates the misunderstood `contents` parameter, in favor of `copyToRoot`.
  Use `copyToRoot = buildEnv { ... };` or similar if you intend to add packages to `/bin`.

- The `proxmox.qemuConf.bios` option was added, it corresponds to `Hardware->BIOS` field in Proxmox web interface. Use `"ovmf"` value to build UEFI image, default value remains `"bios"`. New option `proxmox.partitionTableType` defaults to either `"legacy"` or `"efi"`, depending on the `bios` value. Setting `partitionTableType` to `"hybrid"` results in an image, which supports both methods (`"bios"` and `"ovmf"`), thereby remaining bootable after change to Proxmox `Hardware->BIOS` field.

- memtest86+ was updated from 5.00-coreboot-002 to 6.00-beta2. It is now the upstream version from https://www.memtest.org/, as coreboot's fork is no longer available.

- Option descriptions, examples, and defaults writting in DocBook are now deprecated. Using CommonMark is preferred and will become the default in a future release.
+58 −1
Original line number Diff line number Diff line
@@ -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;
  };