From 9cbdc809378750097a77a70953fd5e6163361c2e Mon Sep 17 00:00:00 2001 From: dkalleg Date: Tue, 12 Jul 2016 01:05:02 -0700 Subject: [PATCH] vSphere Provider - Fix destroy when vm is powered off or has networks (#7206) This patch adds a wait when powering on a vm so setupVirtualMachine does not return until the vm is actually powered on. This allows other functions to work off the assumption that the current state of the vm is not in flux. During resourceVSphereVirtualMachineRead(), the wait for IP would cause a hang for any VM with no network interfaces or for vms that had been powered off for any reason. This also means that the user could not delete a vm with no network interfaces or that is powered off. Checking power state before trying to check for network interfaces. Resolves https://github.com/hashicorp/terraform/issues/7168 --- .../resource_vsphere_virtual_machine.go | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/builtin/providers/vsphere/resource_vsphere_virtual_machine.go b/builtin/providers/vsphere/resource_vsphere_virtual_machine.go index cf480eaa01..a946517d7f 100644 --- a/builtin/providers/vsphere/resource_vsphere_virtual_machine.go +++ b/builtin/providers/vsphere/resource_vsphere_virtual_machine.go @@ -638,12 +638,6 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{ } } - ip, err := vm.WaitForIP(context.TODO()) - if err != nil { - return err - } - log.Printf("[DEBUG] ip address: %v", ip) - return resourceVSphereVirtualMachineRead(d, meta) } @@ -916,14 +910,20 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{}) return nil } - var mvm mo.VirtualMachine - - // wait for interfaces to appear - _, err = vm.WaitForNetIP(context.TODO(), true) + state, err := vm.PowerState(context.TODO()) if err != nil { return err } + if state == types.VirtualMachinePowerStatePoweredOn { + // wait for interfaces to appear + _, err = vm.WaitForNetIP(context.TODO(), true) + if err != nil { + return err + } + } + + var mvm mo.VirtualMachine collector := property.DefaultCollector(client.Client) if err := collector.RetrieveOne(context.TODO(), vm.Reference(), []string{"guest", "summary", "datastore", "config"}, &mvm); err != nil { return err @@ -1059,11 +1059,15 @@ func resourceVSphereVirtualMachineRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Invalid network interfaces to set: %#v", networkInterfaces) } - log.Printf("[DEBUG] ip address: %v", networkInterfaces[0]["ipv4_address"].(string)) - d.SetConnInfo(map[string]string{ - "type": "ssh", - "host": networkInterfaces[0]["ipv4_address"].(string), - }) + if len(networkInterfaces) > 0 { + if _, ok := networkInterfaces[0]["ipv4_address"]; ok { + log.Printf("[DEBUG] ip address: %v", networkInterfaces[0]["ipv4_address"].(string)) + d.SetConnInfo(map[string]string{ + "type": "ssh", + "host": networkInterfaces[0]["ipv4_address"].(string), + }) + } + } var rootDatastore string for _, v := range mvm.Datastore { @@ -1989,6 +1993,10 @@ func (vm *virtualMachine) setupVirtualMachine(c *govmomi.Client) error { if vm.hasBootableVmdk || vm.template != "" { newVM.PowerOn(context.TODO()) + err = newVM.WaitForPowerState(context.TODO(), types.VirtualMachinePowerStatePoweredOn) + if err != nil { + return err + } } return nil }