From eaba21bdb839a5b4ab82f247f2138340eb28ad75 Mon Sep 17 00:00:00 2001 From: Kyriakos Oikonomakos Date: Tue, 3 Dec 2019 15:57:00 +0000 Subject: [PATCH 1/2] Unmount ISO when switching CDROM backends for a VM If the guest OS mounts the virtual cdrom device then vsphere expects someone to confirm that it should be "unlocked" first. This is done via a VirtualMachineQuestionInfo object that we need to find and then respond to via the "AnswerVM" method. We start a goroutine right before we attempt any VM modifications and signal we're done right after we're done. If a known question appears in the mean time, we will send the appropriate answer. --- vsphere/resource_vsphere_virtual_machine.go | 50 +++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/vsphere/resource_vsphere_virtual_machine.go b/vsphere/resource_vsphere_virtual_machine.go index c28bcfaa9..01f239d70 100644 --- a/vsphere/resource_vsphere_virtual_machine.go +++ b/vsphere/resource_vsphere_virtual_machine.go @@ -1,10 +1,12 @@ package vsphere import ( + "context" "errors" "fmt" "log" "strings" + "time" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" @@ -59,6 +61,8 @@ again. For more information on how to do this, see the following page: https://www.terraform.io/docs/commands/taint.html ` +const questionCheckIntervalSecs = 5 + func resourceVSphereVirtualMachine() *schema.Resource { s := map[string]*schema.Schema{ "resource_pool_id": { @@ -553,12 +557,58 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{ return fmt.Errorf("error shutting down virtual machine: %s", err) } } + + // Start goroutine here that checks for qusestions + gChan := make(chan bool) + + questions := map[string]string{ + "msg.cdromdisconnect.locked": "0", + } + go func() { + // Sleep for a bit + time.Sleep(questionCheckIntervalSecs * time.Second) + for { + select { + case <-gChan: + // We're done + break + default: + vprops, err := virtualmachine.Properties(vm) + if err != nil { + log.Printf("[DEBUG] Error while retrieving VM properties. Error: %s", err) + continue + } + q := vprops.Runtime.Question + if q != nil { + log.Printf("[DEBUG] Question: %#v", q) + if len(q.Message) < 1 { + log.Printf("[DEBUG] No messages found") + continue + } + qMsg := q.Message[0].Id + if response, ok := questions[qMsg]; ok { + if err = vm.Answer(context.TODO(), q.Id, response); err != nil { + log.Printf("[DEBUG] Failed to answer question. Error: %s", err) + break + } + } + } else { + log.Printf("[DEBUG] No questions found") + } + } + } + }() + // Perform updates. if _, ok := d.GetOk("datastore_cluster_id"); ok { err = resourceVSphereVirtualMachineUpdateReconfigureWithSDRS(d, meta, vm, spec) } else { err = virtualmachine.Reconfigure(vm, spec) } + + // Regardless of the result we no longer need to watch for pending questions. + gChan <- true + if err != nil { return fmt.Errorf("error reconfiguring virtual machine: %s", err) } From 8ea7e8eda40539d679071117ead3a99c39867524 Mon Sep 17 00:00:00 2001 From: Kyriakos Oikonomakos Date: Tue, 3 Dec 2019 16:29:52 +0000 Subject: [PATCH 2/2] fix typo --- vsphere/resource_vsphere_virtual_machine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vsphere/resource_vsphere_virtual_machine.go b/vsphere/resource_vsphere_virtual_machine.go index 01f239d70..f50d24f72 100644 --- a/vsphere/resource_vsphere_virtual_machine.go +++ b/vsphere/resource_vsphere_virtual_machine.go @@ -558,7 +558,7 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{ } } - // Start goroutine here that checks for qusestions + // Start goroutine here that checks for questions gChan := make(chan bool) questions := map[string]string{