diff --git a/libvirt/helper/suppress/volumes.go b/libvirt/helper/suppress/volumes.go new file mode 100644 index 000000000..018bb0165 --- /dev/null +++ b/libvirt/helper/suppress/volumes.go @@ -0,0 +1,29 @@ +package suppress + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "strconv" +) + +const qcow2SectorSize = 512 + +// Suppress the diff if the specified volume size is qemu-img round up to sector size +func Qcow2SizeDiffSuppressFunc(_, oldSizeStr, newSizeStr string, k *schema.ResourceData) bool { + if format := k.Get("format"); format != "qcow2" { + return false + } + + // On first apply these are nil strings, so there's always a diff + if oldSizeStr == "" { + return false + } + + oldSize, _ := strconv.ParseUint(oldSizeStr, 10, 64) + newSize, _ := strconv.ParseUint(newSizeStr, 10, 64) + + if oldSize-newSize < qcow2SectorSize { + return true + } + + return false +} diff --git a/libvirt/resource_libvirt_volume.go b/libvirt/resource_libvirt_volume.go index cfb07cbea..9c6fd8410 100644 --- a/libvirt/resource_libvirt_volume.go +++ b/libvirt/resource_libvirt_volume.go @@ -9,6 +9,8 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/dmacvicar/terraform-provider-libvirt/libvirt/helper/suppress" ) func resourceLibvirtVolume() *schema.Resource { @@ -38,6 +40,7 @@ func resourceLibvirtVolume() *schema.Resource { Optional: true, Computed: true, ForceNew: true, + DiffSuppressFunc: suppress.Qcow2SizeDiffSuppressFunc, }, "format": { Type: schema.TypeString, diff --git a/libvirt/resource_libvirt_volume_test.go b/libvirt/resource_libvirt_volume_test.go index 4b198721a..1ead9090e 100644 --- a/libvirt/resource_libvirt_volume_test.go +++ b/libvirt/resource_libvirt_volume_test.go @@ -125,6 +125,43 @@ func TestAccLibvirtVolume_Basic(t *testing.T) { }) } +func TestAccLibvirtVolume_SizeRound(t *testing.T) { + var volume libvirt.StorageVol + randomVolumeResource := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + randomVolumeName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + randomPoolName := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha) + randomPoolPath := "/tmp/terraform-provider-libvirt-pool-" + randomPoolName + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckLibvirtVolumeDestroy, + Steps: []resource.TestStep{ + { + Config: fmt.Sprintf(` + resource "libvirt_pool" "%s" { + name = "%s" + type = "dir" + path = "%s" + } + + resource "libvirt_volume" "%s" { + name = "%s" + size = 1073741823 + pool = "${libvirt_pool.%s.name}" + }`, randomPoolName, randomPoolName, randomPoolPath, randomVolumeResource, randomVolumeName, randomPoolName), + Check: resource.ComposeTestCheckFunc( + testAccCheckLibvirtVolumeExists("libvirt_volume."+randomVolumeResource, &volume), + resource.TestCheckResourceAttr( + "libvirt_volume."+randomVolumeResource, "name", randomVolumeName), + resource.TestCheckResourceAttr( + "libvirt_volume."+randomVolumeResource, "size", "1073741824"), + ), + }, + }, + }) +} + + func TestAccLibvirtVolume_BackingStoreTestByID(t *testing.T) { var volume libvirt.StorageVol random := acctest.RandStringFromCharSet(10, acctest.CharSetAlpha)