From 78e99493c33bf25037e1e79b76b334bcdb566a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Bory=C5=9B?= Date: Wed, 30 Aug 2023 19:23:31 +0200 Subject: [PATCH 1/2] Parametrize bus type for cloud-init disk --- libvirt/domain.go | 9 ++++++--- libvirt/resource_libvirt_domain.go | 11 ++++++++++- website/docs/r/domain.html.markdown | 2 ++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/libvirt/domain.go b/libvirt/domain.go index d63504384..a2adb835a 100644 --- a/libvirt/domain.go +++ b/libvirt/domain.go @@ -179,7 +179,7 @@ func domainGetIfacesInfo(virConn *libvirt.Libvirt, domain libvirt.Domain, rd *sc return interfaces, nil } -func newDiskForCloudInit(virConn *libvirt.Libvirt, volumeKey string) (libvirtxml.DomainDisk, error) { +func newDiskForCloudInit(virConn *libvirt.Libvirt, volumeKey string, bus string) (libvirtxml.DomainDisk, error) { disk := libvirtxml.DomainDisk{ // HACK mark the disk as belonging to the cloudinit // resource so we can ignore it @@ -188,7 +188,7 @@ func newDiskForCloudInit(virConn *libvirt.Libvirt, volumeKey string) (libvirtxml Target: &libvirtxml.DomainDiskTarget{ // Last device letter possible with a single IDE controller on i440FX Dev: "hdd", - Bus: "ide", + Bus: bus, }, Driver: &libvirtxml.DomainDiskDriver{ Name: "qemu", @@ -648,7 +648,10 @@ func setCloudinit(d *schema.ResourceData, domainDef *libvirtxml.Domain, virConn if err != nil { return err } - disk, err := newDiskForCloudInit(virConn, cloudinitID) + + cloudinitBus := d.Get("cloudinit_bus").(string) + + disk, err := newDiskForCloudInit(virConn, cloudinitID, cloudinitBus) if err != nil { return err } diff --git a/libvirt/resource_libvirt_domain.go b/libvirt/resource_libvirt_domain.go index 5565d8542..e3fbb11e9 100644 --- a/libvirt/resource_libvirt_domain.go +++ b/libvirt/resource_libvirt_domain.go @@ -106,6 +106,13 @@ func resourceLibvirtDomain() *schema.Resource { Optional: true, ForceNew: false, }, + "cloudinit_bus": { + Type: schema.TypeString, + Optional: true, + Default: "ide", + ForceNew: true, + Required: false, + }, "coreos_ignition": { Type: schema.TypeString, Optional: true, @@ -688,7 +695,9 @@ func resourceLibvirtDomainUpdate(ctx context.Context, d *schema.ResourceData, me return diag.FromErr(err) } - disk, err := newDiskForCloudInit(virConn, cloudinitID) + cloudinitBus := d.Get("cloudinit_bus").(string) + + disk, err := newDiskForCloudInit(virConn, cloudinitID, cloudinitBus) if err != nil { return diag.FromErr(err) } diff --git a/website/docs/r/domain.html.markdown b/website/docs/r/domain.html.markdown index 319134c62..57972d58d 100644 --- a/website/docs/r/domain.html.markdown +++ b/website/docs/r/domain.html.markdown @@ -45,6 +45,8 @@ The following arguments are supported: the domain. This is going to be attached as a CDROM ISO. Changing the cloud-init won't cause the domain to be recreated, however the change will have effect on the next reboot. +* `cloudinit_bus` - (Optional, default: `ide`) The bus type which will be used for + the cloud-init disk. This is mainly to allow the use of cloud-init with Q35 machines. * `autostart` - (Optional) Set to `true` to start the domain on host boot up. If not specified `false` is assumed. * `filesystem` - (Optional) An array of one or more host filesystems to attach to From 035fde05462113042c03d2c303776fc8dd6b3962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Artur=20Bory=C5=9B?= Date: Thu, 31 Aug 2023 17:01:02 +0200 Subject: [PATCH 2/2] Add basic acceptance tests for cloudinit_bus Those are very "dumb" tests, which basically check: * if a default value is used * if the value can be changed I wanted to test if changing the value makes the domain to be recreated, but it seems like this provider is not using the new(er) terraform-plugin-testing package which has that feature. --- libvirt/resource_libvirt_domain_test.go | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/libvirt/resource_libvirt_domain_test.go b/libvirt/resource_libvirt_domain_test.go index ff1d8a73a..d13e1380a 100644 --- a/libvirt/resource_libvirt_domain_test.go +++ b/libvirt/resource_libvirt_domain_test.go @@ -40,6 +40,8 @@ func TestAccLibvirtDomain_Basic(t *testing.T) { "libvirt_domain."+randomResourceName, "memory", "512"), resource.TestCheckResourceAttr( "libvirt_domain."+randomResourceName, "vcpu", "1"), + resource.TestCheckResourceAttr( + "libvirt_domain."+randomResourceName, "cloudinit_bus", "ide"), ), }, }, @@ -988,6 +990,46 @@ func TestAccLibvirtDomain_Filesystems(t *testing.T) { }) } +func TestAccLibvirtDomain_CloudinitBus(t *testing.T) { + var domain libvirt.Domain + randomDomainName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + + var initialConfig = fmt.Sprintf(` + resource "libvirt_domain" "%s" { + name = "%s" + + cloudinit_bus = "ide" + }`, randomDomainName, randomDomainName) + + var updatedConfig = fmt.Sprintf(` + resource "libvirt_domain" "%s" { + name = "%s" + + cloudinit_bus = "sata" + }`, randomDomainName, randomDomainName) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLibvirtDomainDestroy, + Steps: []resource.TestStep{ + { + Config: initialConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckLibvirtDomainExists("libvirt_domain."+randomDomainName, &domain), + resource.TestCheckResourceAttr( + "libvirt_domain." + randomDomainName, "cloudinit_bus", "ide"), + ), + }, + { + Config: updatedConfig, + Check: resource.TestCheckResourceAttr( + "libvirt_domain." + randomDomainName, "cloudinit_bus", "sata"), + }, + }, + }) +} + func testAccCheckLibvirtDomainExists(name string, domain *libvirt.Domain) resource.TestCheckFunc { return func(state *terraform.State) error { rs, err := getResourceFromTerraformState(name, state)