Adding disk keep_on_remove support on delete case (#7169)

This both fixes the keep_on_remove reference in the disk update case
as well as adds logic to safely eject disks in the destroy case.
This commit is contained in:
dkalleg 2016-07-10 14:36:59 -07:00 committed by Paul Stack
parent 0e07a27768
commit 95c0a74df7
2 changed files with 123 additions and 2 deletions

View File

@ -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

View File

@ -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
}
}