UEFI Shell boot options missing. QEMU/KVM/ArchLinux/Virt Manager

The UEFI option in virt manager drops me to the UEFI shell.

When entering exit, it becomes clear why as the GRUB option is missing…


And so are a few other options. Out of 8 listed below, I only see 4.

efibootmgr during packer build

    bastille-installer.qemu.archlinux: BootCurrent: 0001
    bastille-installer.qemu.archlinux: Timeout: 0 seconds
    bastille-installer.qemu.archlinux: BootOrder: 0007,0000,0001,0002,0003,0004,0005,0006
    bastille-installer.qemu.archlinux: Boot0000* UiApp	FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(462caa21-7614-4503-836e-8ab6f4662331)
    bastille-installer.qemu.archlinux: Boot0001* UEFI QEMU DVD-ROM QM00001 	PciRoot(0x0)/Pci(0x1f,0x2)/Sata(0,65535,0){auto_created_boot_option}
    bastille-installer.qemu.archlinux: Boot0002* UEFI QEMU DVD-ROM QM00005 	PciRoot(0x0)/Pci(0x1f,0x2)/Sata(2,65535,0){auto_created_boot_option}
    bastille-installer.qemu.archlinux: Boot0003* UEFI Misc Device	PciRoot(0x0)/Pci(0x3,0x0){auto_created_boot_option}
    bastille-installer.qemu.archlinux: Boot0004* UEFI PXEv4 (MAC:525400123456)	PciRoot(0x0)/Pci(0x2,0x0)/MAC(525400123456,1)/IPv4(0.0.0.00.0.0.0,0,0){auto_created_boot_option}
    bastille-installer.qemu.archlinux: Boot0005* UEFI PXEv6 (MAC:525400123456)	PciRoot(0x0)/Pci(0x2,0x0)/MAC(525400123456,1)/IPv6([::]:<->[::]:,0,0){auto_created_boot_option}
    bastille-installer.qemu.archlinux: Boot0006* EFI Internal Shell	FvVol(7cb8bdc9-f8eb-4f34-aaea-3ee4af6516a1)/FvFile(7c04a583-9e3e-4f1c-ad65-e05268d0b4d1)
    bastille-installer.qemu.archlinux: Boot0007* GRUB	HD(1,GPT,2034b5d2-828a-4491-8d23-fe9439932a12,0x800,0x7d000)/File(\EFI\GRUB\grubx64.efi)

I have the correct firmware added in the hcl file…

bastille-installer.pkr.hcl

packer {
  required_plugins {
    qemu = {
      version = ">= 1.0.9"
      source = "github.com/hashicorp/qemu"
    }
  }
}


variable "ssh_private_key_file" {
  type    = string
  default = "~/.ssh/id_bas"
}

variable "ssh_timeout" {
  type    = string
  default = "20m"

  validation {
      condition = can(regex("[0-9]+[smh]", var.ssh_timeout))
      error_message = "The ssh_timeout value must be a number followed by the letter s(econds), m(inutes), or h(ours)."
    }
}

variable "ssh_username" {
  description = "Unpriviledged user to create."
  type = string
  default = "bas"
}

locals {
  boot_command_qemu = [
    "<wait5><enter><wait90s>",
    "curl -O http://{{ .HTTPIP }}:{{ .HTTPPort }}/${local.kickstart_script} && chmod +x ${local.kickstart_script} && ./${local.kickstart_script} {{ .HTTPPort }}<enter>",
  ]
  boot_command_virtualbox = [
    "<enter><wait90s>",
    "curl -O http://{{ .HTTPIP }}:{{ .HTTPPort }}/${local.kickstart_script} && chmod +x ${local.kickstart_script} && ./${local.kickstart_script} {{ .HTTPPort }}<enter>",
  ]
  cpus              = 1
  disk_size         = "4G"
  efi_firmware_code = "/usr/share/edk2-ovmf/x64/OVMF_CODE.fd"
  efi_firmware_vars = "/usr/share/edk2-ovmf/x64/OVMF_VARS.fd"
  headless          = "false"
  iso_checksum      = "file:https://mirrors.edge.kernel.org/archlinux/iso/{{isotime \"2006.01\"}}.01/sha256sums.txt"
  iso_url           = "https://mirrors.edge.kernel.org/archlinux/iso/{{isotime \"2006.01\"}}.01/archlinux-{{isotime \"2006.01\"}}.01-x86_64.iso"
  kickstart_script  = "cfg_liveVM.sh"
  machine_type      = "q35"
  memory            = 4096
  http_directory    = "srv"
  vm_name           = "bastille-installer"
  write_zeros       = "true"
}

source "qemu" "archlinux" {
  accelerator             = "kvm"
  boot_command            = local.boot_command_qemu
  boot_wait               = "1s"
  cpus                    = local.cpus
  disk_interface          = "virtio"
  disk_size               = local.disk_size
  efi_boot                = true
  efi_firmware_code       = local.efi_firmware_code
  efi_firmware_vars       = local.efi_firmware_vars
  format                  = "qcow2"
  headless                = local.headless
  http_directory          = local.http_directory
  iso_url                 = local.iso_url
  iso_checksum            = local.iso_checksum
  machine_type            = local.machine_type
  memory                  = local.memory
  net_device              = "virtio-net" 
  shutdown_command        = "sudo systemctl start poweroff.timer"
  ssh_handshake_attempts  = 500
  ssh_port                = 22
  ssh_private_key_file    = var.ssh_private_key_file
  ssh_timeout             = var.ssh_timeout
  ssh_username            = var.ssh_username
  ssh_wait_timeout        = var.ssh_timeout
  vm_name                 = "${local.vm_name}.qcow2"
}

build {
  name = "bastille-installer"
  sources = ["source.qemu.archlinux"]
  
  provisioner "file" {
    destination = "/tmp/"
    source      = "./files"
  }

  provisioner "shell" {
    only = ["qemu.archlinux"]
    execute_command = "{{ .Vars }} sudo -E -S bash '{{ .Path }}'"
    expect_disconnect = true
    scripts           = [
    "scripts/configure-qemu.sh",
    "scripts/configure-shared.sh",
    "scripts/partition-table-gpt.sh",
    "scripts/partition-ext4-efi.sh",
    "scripts/setup.sh"
    ]
  }
      
  provisioner "shell" {
    execute_command = "{{ .Vars }} WRITE_ZEROS=${local.write_zeros} sudo -E -S bash '{{ .Path }}'"
    script = "scripts/cleanup.sh"
  }
    
  post-processor "vagrant" {
    output = "output/${local.vm_name}_${source.type}_${source.name}-${formatdate("YYYY-MM", timestamp())}.qcow2"
    vagrantfile_template = "templates/vagrantfile.tpl"
  }
}

…so what am I doing wrong?

[edit]

One of the things that I was doing wrong was that my qemu plugin was really old
as my packer config file did not contain a packer block.

bastille-installer.pkr.hcl

packer {
  required_plugins {
    qemu = {
      version = ">= 1.0.9"
      source = "github.com/hashicorp/qemu"
    }
  }
}

And then do packer init.

[/edit]

virt-manager as well as virt-install creates a completely new VM which does not know about the UEFI configuration of my existing VM.

The problem seemed to be --boot uefi. I need

--boot loader=/.../OVMF_CODE.fd,loader.readonly=yes,loader.type=pflash,nvram.template=/.../OVMF_VARS.fd,loader_secure=n

But that leaves me to the next issue → Packer-build VM does not start: Impossible to rename file '(null).new' to '(null)': Bad address

This issue has been solved in so far that I finally know where the issue lies and it’s with the vagrant post-processor that creates a box, which I then try to load into virt-manager. It works fine with qcow2 files.

Removing the post-processor or setting keep_input_artifact to true solves it for now.

[edit]

I don’t think virt-manager is meant to load boxes despite virtualbox doing so, so keep_input_artifact needs to be true. qcow2 files are only for testing purposes anyway.