From 784a1060e994d072c5b41e6bef6c1847813813ad Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Mon, 11 Jul 2016 15:48:34 +0100 Subject: [PATCH] Revert "Revert "Adding disk keep_on_remove support on delete case"" --- .../resource_vsphere_virtual_machine.go | 29 +++++- .../resource_vsphere_virtual_machine_test.go | 96 +++++++++++++++++++ 2 files changed, 123 insertions(+), 2 deletions(-) diff --git a/builtin/providers/vsphere/resource_vsphere_virtual_machine.go b/builtin/providers/vsphere/resource_vsphere_virtual_machine.go index 30bb8924d..4998d63a4 100644 --- a/builtin/providers/vsphere/resource_vsphere_virtual_machine.go +++ b/builtin/providers/vsphere/resource_vsphere_virtual_machine.go @@ -509,8 +509,8 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{ virtualDisk := devices.FindByKey(int32(disk["key"].(int))) keep := false - if v, ok := d.GetOk("keep_on_remove"); ok { - keep = v.(bool) + if v, ok := disk["keep_on_remove"].(bool); ok { + keep = v } err = vm.RemoveDevice(context.TODO(), keep, virtualDisk) @@ -1093,6 +1093,11 @@ func resourceVSphereVirtualMachineDelete(d *schema.ResourceData, meta interface{ if err != nil { return err } + devices, err := vm.Device(context.TODO()) + if err != nil { + log.Printf("[DEBUG] resourceVSphereVirtualMachineDelete - Failed to get device list: %v", err) + return err + } log.Printf("[INFO] Deleting virtual machine: %s", d.Id()) state, err := vm.PowerState(context.TODO()) @@ -1112,6 +1117,26 @@ func resourceVSphereVirtualMachineDelete(d *schema.ResourceData, meta interface{ } } + // Safely eject any disks the user marked as keep_on_remove + if vL, ok := d.GetOk("disk"); ok { + if diskSet, ok := vL.(*schema.Set); ok { + + for _, value := range diskSet.List() { + disk := value.(map[string]interface{}) + + if v, ok := disk["keep_on_remove"].(bool); ok && v == true { + log.Printf("[DEBUG] not destroying %v", disk["name"]) + virtualDisk := devices.FindByKey(int32(disk["key"].(int))) + err = vm.RemoveDevice(context.TODO(), true, virtualDisk) + if err != nil { + log.Printf("[ERROR] Update Remove Disk - Error removing disk: %v", err) + return err + } + } + } + } + } + task, err := vm.Destroy(context.TODO()) if err != nil { return err diff --git a/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go b/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go index a69c80567..4ebeab093 100644 --- a/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go +++ b/builtin/providers/vsphere/resource_vsphere_virtual_machine_test.go @@ -1154,3 +1154,99 @@ func testAccCheckVSphereVirtualMachineExists(n string, vm *virtualMachine) resou return nil } } + +const testAccCheckVSphereVirtualMachineConfig_keepOnRemove = ` +resource "vsphere_virtual_machine" "keep_disk" { + name = "terraform-test" +` + testAccTemplateBasicBody + ` + disk { + size = 1 + iops = 500 + controller_type = "scsi" + name = "one" + keep_on_remove = true + } +} +` + +func TestAccVSphereVirtualMachine_keepOnRemove(t *testing.T) { + var vm virtualMachine + basic_vars := setupTemplateBasicBodyVars() + config := basic_vars.testSprintfTemplateBody(testAccCheckVSphereVirtualMachineConfig_keepOnRemove) + var datastore string + if v := os.Getenv("VSPHERE_DATASTORE"); v != "" { + datastore = v + } + var datacenter string + if v := os.Getenv("VSPHERE_DATACENTER"); v != "" { + datacenter = v + } + + vmName := "vsphere_virtual_machine.keep_disk" + test_exists, test_name, test_cpu, test_mem, test_num_disk, test_num_of_nic, test_nic_label := + TestFuncData{vm: vm, label: basic_vars.label, vmName: vmName, numDisks: "2"}.testCheckFuncBasic() + + log.Printf("[DEBUG] template= %s", testAccCheckVSphereVirtualMachineConfig_keepOnRemove) + 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_mem, test_num_disk, test_num_of_nic, test_nic_label, + ), + }, + resource.TestStep{ + Config: " ", + Check: checkForDisk(datacenter, datastore, "terraform-test", "one.vmdk"), + }, + }, + }) +} + +func checkForDisk(datacenter string, datastore string, vmName string, path string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*govmomi.Client) + finder := find.NewFinder(client.Client, true) + + dc, err := getDatacenter(client, datacenter) + if err != nil { + return err + } + finder.SetDatacenter(dc) + + ds, err := finder.Datastore(context.TODO(), datastore) + if err != nil { + log.Printf("[ERROR] checkForDisk - Couldn't find Datastore '%v': %v", datastore, err) + return err + } + + diskPath := vmName + "/" + path + + _, err = ds.Stat(context.TODO(), diskPath) + if err != nil { + log.Printf("[ERROR] checkForDisk - Couldn't stat file '%v': %v", diskPath, err) + return err + } + + // Cleanup + fileManager := object.NewFileManager(client.Client) + task, err := fileManager.DeleteDatastoreFile(context.TODO(), ds.Path(vmName), dc) + if err != nil { + log.Printf("[ERROR] checkForDisk - Couldn't delete vm folder '%v': %v", vmName, err) + return err + } + + _, err = task.WaitForResult(context.TODO(), nil) + if err != nil { + log.Printf("[ERROR] checForDisk - Failed while deleting vm folder '%v': %v", vmName, err) + return err + } + + return nil + } +}