diff --git a/builtin/providers/vsphere/resource_vsphere_virtual_disk.go b/builtin/providers/vsphere/resource_vsphere_virtual_disk.go index 5505e17cd817..163321853cda 100644 --- a/builtin/providers/vsphere/resource_vsphere_virtual_disk.go +++ b/builtin/providers/vsphere/resource_vsphere_virtual_disk.go @@ -46,12 +46,12 @@ func resourceVSphereVirtualDisk() *schema.Resource { Type: schema.TypeString, Optional: true, ForceNew: true, - Default: "eagerZeroedThick", + Default: "eager_zeroed", ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { value := v.(string) - if value != "thin" && value != "eagerZeroedThick" { + if value != "thin" && value != "eager_zeroed" && value != "lazy" { errors = append(errors, fmt.Errorf( - "only 'thin' and 'eagerZeroedThick' are supported values for 'type'")) + "only 'thin', 'eager_zeroed', and 'lazy' are supported values for 'type'")) } return }, @@ -234,11 +234,21 @@ func resourceVSphereVirtualDiskDelete(d *schema.ResourceData, meta interface{}) // createHardDisk creates a new Hard Disk. func createHardDisk(client *govmomi.Client, size int, diskPath string, diskType string, adapterType string, dc string) error { + var vDiskType string + switch diskType { + case "thin": + vDiskType = "thin" + case "eager_zeroed": + vDiskType = "eagerZeroedThick" + case "lazy": + vDiskType = "preallocated" + } + virtualDiskManager := object.NewVirtualDiskManager(client.Client) spec := &types.FileBackedVirtualDiskSpec{ VirtualDiskSpec: types.VirtualDiskSpec{ AdapterType: adapterType, - DiskType: diskType, + DiskType: vDiskType, }, CapacityKb: int64(1024 * 1024 * size), } diff --git a/builtin/providers/vsphere/resource_vsphere_virtual_machine.go b/builtin/providers/vsphere/resource_vsphere_virtual_machine.go index d8e907212530..3de90d5029b6 100644 --- a/builtin/providers/vsphere/resource_vsphere_virtual_machine.go +++ b/builtin/providers/vsphere/resource_vsphere_virtual_machine.go @@ -380,9 +380,9 @@ func resourceVSphereVirtualMachine() *schema.Resource { Default: "eager_zeroed", ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) { value := v.(string) - if value != "thin" && value != "eager_zeroed" { + if value != "thin" && value != "eager_zeroed" && value != "lazy" { errors = append(errors, fmt.Errorf( - "only 'thin' and 'eager_zeroed' are supported values for 'type'")) + "only 'thin', 'eager_zeroed', and 'lazy' are supported values for 'type'")) } return }, @@ -580,8 +580,15 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{ return fmt.Errorf("[ERROR] resourceVSphereVirtualMachineUpdate - Neither vmdk path nor vmdk name was given") } + var initType string + if disk["type"] != "" { + initType = disk["type"].(string) + } else { + initType = "thin" + } + log.Printf("[INFO] Attaching disk: %v", diskPath) - err = addHardDisk(vm, size, iops, "thin", datastore, diskPath, controller_type) + err = addHardDisk(vm, size, iops, initType, datastore, diskPath, controller_type) if err != nil { log.Printf("[ERROR] Add Hard Disk Failed: %v", err) return err @@ -1298,6 +1305,10 @@ func addHardDisk(vm *object.VirtualMachine, size, iops int64, diskType string, d // eager zeroed thick virtual disk backing.ThinProvisioned = types.NewBool(false) backing.EagerlyScrub = types.NewBool(true) + } else if diskType == "lazy" { + // lazy zeroed thick virtual disk + backing.ThinProvisioned = types.NewBool(false) + backing.EagerlyScrub = types.NewBool(false) } else if diskType == "thin" { // thin provisioned virtual disk backing.ThinProvisioned = types.NewBool(true) @@ -1477,6 +1488,7 @@ func buildVMRelocateSpec(rp *object.ResourcePool, ds *object.Datastore, vm *obje } isThin := initType == "thin" + eagerScrub := initType == "eager_zeroed" rpr := rp.Reference() dsr := ds.Reference() return types.VirtualMachineRelocateSpec{ @@ -1489,7 +1501,7 @@ func buildVMRelocateSpec(rp *object.ResourcePool, ds *object.Datastore, vm *obje DiskBackingInfo: &types.VirtualDiskFlatVer2BackingInfo{ DiskMode: "persistent", ThinProvisioned: types.NewBool(isThin), - EagerlyScrub: types.NewBool(!isThin), + EagerlyScrub: types.NewBool(eagerScrub), }, DiskId: key, }, diff --git a/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go b/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go index 5a1dafe24a33..a8c4602ab980 100644 --- a/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go +++ b/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go @@ -398,36 +398,36 @@ func TestAccVSphereVirtualMachine_diskSCSICapacity(t *testing.T) { }) } -const testAccCheckVSphereVirtualMachineConfig_initType = ` -resource "vsphere_virtual_machine" "thin" { +const testAccCheckVSphereVirtualMachineConfig_initTypeEager = ` +resource "vsphere_virtual_machine" "thickEagerZero" { name = "terraform-test" ` + testAccTemplateBasicBody + ` disk { - size = 1 - iops = 500 - controller_type = "scsi" - name = "one" + size = 1 + iops = 500 + controller_type = "scsi" + name = "one" } disk { - size = 1 - controller_type = "ide" - type = "eager_zeroed" - name = "two" + size = 1 + controller_type = "ide" + type = "eager_zeroed" + name = "two" } } ` -func TestAccVSphereVirtualMachine_diskInitType(t *testing.T) { +func TestAccVSphereVirtualMachine_diskInitTypeEager(t *testing.T) { var vm virtualMachine basic_vars := setupTemplateBasicBodyVars() - config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_initType) + config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_initTypeEager) - vmName := "vsphere_virtual_machine.thin" + vmName := "vsphere_virtual_machine.thickEagerZero" test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "3"}.testCheckFuncBasic() - log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_initType) + log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_initTypeEager) log.Printf("[DEBUG] template config= %s", config) resource.Test(t, resource.TestCase{ @@ -449,6 +449,57 @@ func TestAccVSphereVirtualMachine_diskInitType(t *testing.T) { }) } +const testAccCheckVSphereVirtualMachineConfig_initTypeLazy = ` +resource "vsphere_virtual_machine" "lazy" { + name = "terraform-test" +` + testAccTemplateBasicBody + ` + disk { + size = 1 + iops = 500 + controller_type = "scsi" + name = "one" + } + disk { + size = 1 + controller_type = "ide" + type = "lazy" + name = "two" + } +} +` + +func TestAccVSphereVirtualMachine_diskInitTypeLazy(t *testing.T) { + var vm virtualMachine + basic_vars := setupTemplateBasicBodyVars() + config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_initTypeLazy) + + vmName := "vsphere_virtual_machine.lazy" + + test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label := + TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "3"}.testCheckFuncBasic() + + log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_initTypeLazy) + log.Printf("[DEBUG] template config= %s", config) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckVSphereVirtualMachineDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: config, + Check: resource.ComposeTestCheckFunc( + test_exists, test_name, test_cpu, test_uuid, test_mem, test_num_disk, test_num_of_nic, test_nic_label, + // FIXME dynmically calculate the hashes + resource.TestCheckResourceAttr(vmName, "disk.692719290.type", "lazy"), + resource.TestCheckResourceAttr(vmName, "disk.692719290.controller_type", "ide"), + resource.TestCheckResourceAttr(vmName, "disk.531766495.controller_type", "scsi"), + ), + }, + }, + }) +} + const testAccCheckVSphereVirtualMachineConfig_dhcp = ` resource "vsphere_virtual_machine" "bar" { name = "terraform-test" diff --git a/website/source/docs/providers/vsphere/r/virtual_machine.html.markdown b/website/source/docs/providers/vsphere/r/virtual_machine.html.markdown index 5015ac6c42d2..1ad81742a44a 100644 --- a/website/source/docs/providers/vsphere/r/virtual_machine.html.markdown +++ b/website/source/docs/providers/vsphere/r/virtual_machine.html.markdown @@ -117,7 +117,7 @@ The `disk` block supports: * `size` - (Required if template and bootable_vmdks_path not provided) Size of this disk (in GB). * `name` - (Required if size is provided when creating a new disk) This "name" is used for the disk file name in vSphere, when the new disk is created. * `iops` - (Optional) Number of virtual iops to allocate for this disk. -* `type` - (Optional) 'eager_zeroed' (the default), or 'thin' are supported options. +* `type` - (Optional) 'eager_zeroed' (the default), 'lazy', or 'thin' are supported options. * `vmdk` - (Required if template and size not provided) Path to a vmdk in a vSphere datastore. * `bootable` - (Optional) Set to 'true' if a vmdk was given and it should attempt to boot after creation. * `controller_type` = (Optional) Controller type to attach the disk to. 'scsi' (the default), or 'ide' are supported options.