From 17dca987eb240454dbd980ed8f0c4a939e327ff0 Mon Sep 17 00:00:00 2001 From: Pavel Boldyrev <627562+bpg@users.noreply.github.com> Date: Sat, 25 Mar 2023 10:18:42 -0400 Subject: [PATCH] fix(vm): Prevent `file_format` override with default `qcow2` in TF state (#275) * fix(vm): Fix for `raw` file format for new empty disks * make file_format computed * apply default file_format for disc cloning as well --- proxmoxtf/resource_virtual_environment_vm.go | 34 ++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/proxmoxtf/resource_virtual_environment_vm.go b/proxmoxtf/resource_virtual_environment_vm.go index 3da07410..564ea4e8 100644 --- a/proxmoxtf/resource_virtual_environment_vm.go +++ b/proxmoxtf/resource_virtual_environment_vm.go @@ -516,7 +516,6 @@ func resourceVirtualEnvironmentVM() *schema.Resource { return []interface{}{ map[string]interface{}{ mkResourceVirtualEnvironmentVMDiskDatastoreID: dvResourceVirtualEnvironmentVMDiskDatastoreID, - mkResourceVirtualEnvironmentVMDiskFileFormat: dvResourceVirtualEnvironmentVMDiskFileFormat, mkResourceVirtualEnvironmentVMDiskFileID: dvResourceVirtualEnvironmentVMDiskFileID, mkResourceVirtualEnvironmentVMDiskInterface: dvResourceVirtualEnvironmentVMDiskInterface, mkResourceVirtualEnvironmentVMDiskSize: dvResourceVirtualEnvironmentVMDiskSize, @@ -544,7 +543,7 @@ func resourceVirtualEnvironmentVM() *schema.Resource { Description: "The file format", Optional: true, ForceNew: true, - Default: dvResourceVirtualEnvironmentVMDiskFileFormat, + Computed: true, ValidateDiagFunc: getFileFormatValidator(), }, mkResourceVirtualEnvironmentVMDiskFileID: { @@ -2044,6 +2043,14 @@ func resourceVirtualEnvironmentVMCreateCustom( d.SetId(strconv.Itoa(vmID)) + // TODO: The VM creation is not atomic, and not synchronous. This means that the VM might not be + // available immediately after the creation, or its state reported by the API might not be + // up to date. This is a problem for the following operations, which rely on the VM information + // returned by API calls, particularly read-back to populate the Terraform state. + // Would it be possible to wait for the VM to be fully available, or to wait for the API to report + // the correct state? + // time.Sleep(5 * time.Second) + return resourceVirtualEnvironmentVMCreateCustomDisks(ctx, d, m) } @@ -2106,6 +2113,10 @@ func resourceVirtualEnvironmentVMCreateCustomDisks( ssd := proxmox.CustomBool(block[mkResourceVirtualEnvironmentVMDiskSSD].(bool)) discard, _ := block[mkResourceVirtualEnvironmentVMDiskDiscard].(string) + if fileFormat == "" { + fileFormat = dvResourceVirtualEnvironmentVMDiskFileFormat + } + if len(speed) == 0 { diskSpeedDefault, err := diskSpeedResource.DefaultValue() if err != nil { @@ -2461,6 +2472,9 @@ func resourceVirtualEnvironmentVMGetDiskDeviceObjects( return diskDeviceObjects, err } + if fileFormat == "" { + fileFormat = dvResourceVirtualEnvironmentVMDiskFileFormat + } if fileID != "" { diskDevice.Enabled = false } else { @@ -2776,6 +2790,7 @@ func resourceVirtualEnvironmentVMReadCustom( return diags } + nodeName := d.Get(mkResourceVirtualEnvironmentVMNodeName).(string) clone := d.Get(mkResourceVirtualEnvironmentVMClone).([]interface{}) // Compare the agent configuration to the one stored in the state. @@ -3012,7 +3027,20 @@ func resourceVirtualEnvironmentVMReadCustom( disk[mkResourceVirtualEnvironmentVMDiskDatastoreID] = fileIDParts[0] if dd.Format == nil { - disk[mkResourceVirtualEnvironmentVMDiskFileFormat] = "qcow2" + disk[mkResourceVirtualEnvironmentVMDiskFileFormat] = dvResourceVirtualEnvironmentVMDiskFileFormat + // disk format may not be returned by config API if it is default for the storage, and that may be different + // from the default qcow2, so we need to read it from the storage API to make sure we have the correct value + files, err := veClient.ListDatastoreFiles(ctx, nodeName, fileIDParts[0]) + if err != nil { + diags = append(diags, diag.FromErr(err)...) + continue + } + for _, v := range files { + if v.VolumeID == dd.FileVolume { + disk[mkResourceVirtualEnvironmentVMDiskFileFormat] = v.FileFormat + break + } + } } else { disk[mkResourceVirtualEnvironmentVMDiskFileFormat] = dd.Format }