Signed up to say thanks and share the fix. Exact same problem when I build with packer on laptop and deploy to KVM on another server including the device IDs. @trodemaster has the right idea for a fix. I managed to get an enp1s0
ethernet card like this:
Step 1: Change bus
machine_type = "pc-q35-7.2"
Gives me an enp
device instead of ens
but wrong slot and bus ID
Step 2: Tweak the qemu args to “install” some PCI-e slots
["-device", <<-EOT
{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x7"}
EOT
],
Step 3: “Install” the network card into the PCI-e slot
["-netdev", <<-EOT
{"type":"user","id":"hostnet0"}
EOT
],
["-device", <<-EOT
{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"de:ad:be:ef:ca:fe","bus":"pci.1","addr":"0x0"}
EOT
]
Step 4: (if required) adjust the bus addr
value
You may get an ID clash on the bus with other random devices, like this:
2025/02/02 12:00:12 packer-plugin-qemu_v1.1.0_x5.0_linux_amd64 plugin: 2025/02/02 12:00:12 Qemu stderr: : PCI: slot 0 function 0 not available for pcie-root-port, in use by mch,id=(null)
In this case, I got things working by just trying new addr
values at random until I found a free one at 0x7
, just like setting IRQ 7 for soundblaster in the good old days.
After spending way too long on this, I was rewarded with enp1s0
in my packer VM, the correct interface definition in Debian’s /etc/network/interfaces
and an IP address when booting the image on the KVM server. The other way to do this would have been cloud-init.
Complete example (UEFI + secure boot)
net_device
comes directly from qemuargs
so don’t also try to set it with plugin.
source "qemu" "debian12" {
qemuargs = [
["-bios", "/usr/share/OVMF/OVMF_CODE.fd"],
["-chardev", "stdio,id=char0,logfile=serial.log,signal=off"],
["-serial", "chardev:char0"],
["-device", <<-EOT
{"driver":"pcie-root-port","port":8,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x7"}
EOT
],
["-netdev", <<-EOT
{"type":"user","id":"hostnet0"}
EOT
],
["-device", <<-EOT
{"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"de:ad:be:ef:ca:fe","bus":"pci.1","addr":"0x0"}
EOT
]
]
communicator = "none"
cpus = "2"
memory = "2048"
iso_url = "..."
iso_checksum = "sha512:..."
output_directory = "..."
shutdown_timeout = "1h"
disk_size = "20G"
format = "qcow2"
accelerator = "kvm"
http_directory = "http"
vm_name = "debian12"
#net_device = "virtio-net-pci"
disk_interface = "virtio"
boot_wait = "2s"
machine_type = "pc-q35-7.2"
boot_command = [ ... ]
}
Cheers,
Geoff