dmacvicar / terraform-provider-libvirt

Terraform provider to provision infrastructure with Linux's KVM using libvirt
Apache License 2.0
1.54k stars 457 forks source link

new domain errors with "unsupported configuration: IDE controllers are unsupported for this QEMU binary or machine type" #885

Open wsidl opened 2 years ago

wsidl commented 2 years ago

System Information

Linux distribution

Manjaro Linux x86/64 kernel 5.10.63

Terraform version

v1.0.6

Provider and libvirt versions

Provider v.0.6.11 libvirt 7.7.0


Checklist

Description of Issue/Question

Not able to create a single VM using this provider due to the generated domain contains incorrect/invalid values for defining the disks on the instance.

When comparing the results of the generated domain (via TF_LOG=DEBUG terraform apply), I get the error "unsupported configuration: IDE controllers are unsupported for this QEMU binary or machine type". After trying various changes by modifying the Domain XML from the verbose log, was able to discover the issue was in the CDROM disk block.

This domain uses a cloudinit ISO which is loaded as a CDROM. The block generated looks like:

        <disk type="file" device="cdrom">
            <driver name="qemu" type="raw"></driver>
            <source file="/var/lib/libvirt/images/commoninit.iso"></source>
            <target dev="hdd" bus="ide"></target>
        </disk>

When modifying the line <target dev="hdd" bus="ide"></target> to use the attribute bus="sata", the virsh create generated.xml command was able to successfully create the domain.

Setup

main.tf contents ```hcl terraform { required_version = ">= 1.0" required_providers { libvirt = { source = "dmacvicar/libvirt" } } } provider "libvirt" { uri = "qemu:///system" } # Prep requirements resource "libvirt_pool" "default" { name = var.disk_pool_name type = "dir" path = var.disk_pool_path } resource "libvirt_volume" "ubuntu_iso" { name = "ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img" pool = "os_img" format = "qcow2" source = "https://cloud-images.ubuntu.com/releases/focal/release/ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img" } # Create App Host VM resource "libvirt_volume" "root" { name = "root1.qcow2" pool = "os_img" size = 107374182400 # 100GB base_volume_id = libvirt_volume.ubuntu_iso.id } resource "libvirt_volume" "extra" { name = "disk1.qcow2" pool = "os_img" size = 53687091200 # 50GB } data "cloudinit_config" "init" { part { content_type = "cloud-config" content = templatefile( "${path.module}/cloud_init.yml", {ssh_key = var.ssh_public_key} ) } part { content_type = "text/x-shellscript" content = file("${path.module}/setup_app.sh") filename = "setup_app.sh" } } resource "libvirt_cloudinit_disk" "init" { name = "commoninit.iso" user_data = data.cloudinit_config.init.rendered } resource "libvirt_domain" "vm" { name = "app_vm" memory = "8192" vcpu = "8" arch = "x86_64" fw_cfg_name = "" machine = "q35" cloudinit = libvirt_cloudinit_disk.init.id autostart = true network_interface { addresses = [ "192.168.0.5" ] network_name = "default" mac = "bb:bb:bb:bb:bb:bb" wait_for_lease = false } network_interface { addresses = [ "192.168.0.6" ] network_name = "default" mac = "aa:aa:aa:aa:aa:aa" wait_for_lease = false } timeouts {} disk { volume_id = libvirt_volume.root.id } disk { volume_id = libvirt_volume.extra.id } } ```

Steps to Reproduce Issue

Run configuration with variables set for disk_pool_name, disk_pool_path, ssh_public_key: terraform plan && terraform apply


Additional information:

Do you have SELinux or Apparmor/Firewall enabled? Some special configuration? Have you tried to reproduce the issue without them enabled?

wsidl commented 2 years ago

Was finally able to determine the issue is with libvirt_cloudinit_disk. When this is assigned to the domain, it creates a disk block attached to the IDE bus. This machine does not accept an IDE bus:

<disk type="file" device="cdrom">
  <driver name="qemu" type="raw"></driver>
  <source file="/var/lib/libvirt/images/commoninit.iso"></source>
  <target dev="hdd" bus="ide"></target>
</disk>

Changing the bus type to "sata" and running it against virsh define generated.xml creates the machine successfully.

Will update issue description accordingly

cbricart commented 2 years ago

I think @wsidl created a domain of machine = "q35" which does not have IDE but SATA bus.

As a workaround, I have been able to live-patch the resulting XML with XSLT:

cdrom-model.xsl

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
  </xsl:template>

  <xsl:template match="/domain/devices/disk[@device='cdrom']/target/@bus">
    <xsl:attribute name="bus">
      <xsl:value-of select="'sata'"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

and in main.tf:

resource "libvirt_domain" "q35-host" {
...
  machine = "q35"
  xml {
    xslt = file("cdrom-model.xsl")
  }
...
aabor commented 1 year ago

Great solution! It helped me much.

DimitriDokuchaev commented 10 months ago

Sorry to dig this issue, however i would love for someone to assist me getting this to work.

I am trying to get a q35 machine to boot and use cloudinit on it, but i haven't been successful, everything works correctly if i use the default i440FX.

this is my Domain.tf

esource "libvirt_domain" "ubuntu2204vm" {
  name = "${var.hostname}"

  memory = "${var.memory}"
  vcpu = "${var.vcpu}"
  machine = "${var.machine}"

  xml{
    xslt = file("cdrom-model.xsl")
  }

  cloudinit = libvirt_cloudinit_disk.cloud-init.id

  disk{
    volume_id = libvirt_volume.ubuntu-2204-vol.id
  }

  network_interface {
    network_name = "default"
    wait_for_lease = true
  }

  console {
    target_type = "serial"
    type        = "pty"
    target_port = "0"
  }

  console {
    target_type = "virtio"
    type        = "pty"
    target_port = "1"
  }
}

and this is my xslt:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
  </xsl:template>

  <xsl:template match="/domain/devices/disk[@device='cdrom']/target/@bus">
    <xsl:attribute name="bus">
      <xsl:value-of select="'sata'"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

it is what @cbricart posted above ( i also found another xslt that attempts to do the same, change the bus type from ide to sata, but it doesn't seem to work)

Whenever I try to run domain.tf with xslt i am never able to launch cloudinit, if i check virt manager, the machine is the q35 type and the cdrom has the bus as sata as requeired however cloudinit never starts.

Does anyone know what the issue may be?

Best regards,