From 7260bd3e255450a48ab2fd2ac2adac351209ee4a Mon Sep 17 00:00:00 2001 From: Kyriakos Oikonomakos Date: Tue, 20 Apr 2021 09:00:17 +0100 Subject: [PATCH 1/2] Change the way we set the timeout for maintenance mode --- .../cluster_compute_resource_helper.go | 9 ++++++--- .../helper/hostsystem/host_system_helper.go | 16 ++++++---------- vsphere/resource_vsphere_compute_cluster.go | 11 ++++++----- vsphere/resource_vsphere_host.go | 17 +++++++++-------- 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/vsphere/internal/helper/clustercomputeresource/cluster_compute_resource_helper.go b/vsphere/internal/helper/clustercomputeresource/cluster_compute_resource_helper.go index 0aec9aa60..9a41996b6 100644 --- a/vsphere/internal/helper/clustercomputeresource/cluster_compute_resource_helper.go +++ b/vsphere/internal/helper/clustercomputeresource/cluster_compute_resource_helper.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "strings" + "time" "github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/computeresource" "github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/folder" @@ -231,7 +232,8 @@ func MoveHostsInto(client *govmomi.Client, cluster *object.ClusterComputeResourc } } - err = hostsystem.EnterMaintenanceMode(hs, int(provider.DefaultAPITimeout.Seconds())+(int(provider.DefaultAPITimeout.Seconds())*len(hsProps.Vm)), evacuate) + totalVmTimeout := provider.DefaultAPITimeout * time.Duration(len(hsProps.Vm)+1) + err = hostsystem.EnterMaintenanceMode(hs, totalVmTimeout, evacuate) if err != nil { return fmt.Errorf("while putting host %q in maintenance mode: %s", hs.Reference().Value, err) } @@ -279,7 +281,8 @@ func MoveHostsOutOf(cluster *object.ClusterComputeResource, hosts []*object.Host func moveHostOutOf(cluster *object.ClusterComputeResource, host *object.HostSystem, timeout int) error { // Place the host into maintenance mode. This blocks until the host is ready. - if err := hostsystem.EnterMaintenanceMode(host, timeout, true); err != nil { + timeoutDuration := time.Duration(timeout) * time.Second + if err := hostsystem.EnterMaintenanceMode(host, timeoutDuration, true); err != nil { return fmt.Errorf("error putting host %q into maintenance mode: %s", host.Name(), err) } @@ -294,7 +297,7 @@ func moveHostOutOf(cluster *object.ClusterComputeResource, host *object.HostSyst } // Move the host out of maintenance mode now that it's out of the cluster. - if err := hostsystem.ExitMaintenanceMode(host, timeout); err != nil { + if err := hostsystem.ExitMaintenanceMode(host, timeoutDuration); err != nil { return fmt.Errorf("error taking host %q out of maintenance mode: %s", host.Name(), err) } diff --git a/vsphere/internal/helper/hostsystem/host_system_helper.go b/vsphere/internal/helper/hostsystem/host_system_helper.go index 7bcb5acba..ac8e7c45c 100644 --- a/vsphere/internal/helper/hostsystem/host_system_helper.go +++ b/vsphere/internal/helper/hostsystem/host_system_helper.go @@ -114,7 +114,7 @@ func HostInMaintenance(host *object.HostSystem) (bool, error) { // to true, all powered off VMs will be removed from the host, or the task will // block until this is the case, depending on whether or not DRS is on or off // for the host's cluster. This parameter is ignored on direct ESXi. -func EnterMaintenanceMode(host *object.HostSystem, timeout int, evacuate bool) error { +func EnterMaintenanceMode(host *object.HostSystem, timeout time.Duration, evacuate bool) error { if err := viapi.VimValidateVirtualCenter(host.Client()); err != nil { evacuate = false } @@ -127,9 +127,9 @@ func EnterMaintenanceMode(host *object.HostSystem, timeout int, evacuate bool) e log.Printf("[DEBUG] Host %q is entering maintenance mode (evacuate: %t)", host.Name(), evacuate) - ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(timeout)) + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - task, err := host.EnterMaintenanceMode(ctx, int32(timeout), evacuate, nil) + task, err := host.EnterMaintenanceMode(ctx, int32(timeout.Seconds()), evacuate, nil) if err != nil { return err } @@ -152,7 +152,7 @@ func EnterMaintenanceMode(host *object.HostSystem, timeout int, evacuate bool) e } // ExitMaintenanceMode takes a host out of maintenance mode. -func ExitMaintenanceMode(host *object.HostSystem, timeout int) error { +func ExitMaintenanceMode(host *object.HostSystem, timeout time.Duration) error { maintMode, err := HostInMaintenance(host) if !maintMode { log.Printf("[DEBUG] Host %q is already not in maintenance mode", host.Name()) @@ -161,13 +161,9 @@ func ExitMaintenanceMode(host *object.HostSystem, timeout int) error { log.Printf("[DEBUG] Host %q is exiting maintenance mode", host.Name()) - // Add 5 minutes to timeout for the context timeout to allow for any issues - // with the request after. - // TODO: Fix this so that it ultimately uses the provider context. - ctxTimeout := timeout + 300 - ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(ctxTimeout)) + ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - task, err := host.ExitMaintenanceMode(ctx, int32(timeout)) + task, err := host.ExitMaintenanceMode(ctx, int32(timeout.Seconds())) if err != nil { return err } diff --git a/vsphere/resource_vsphere_compute_cluster.go b/vsphere/resource_vsphere_compute_cluster.go index 9955e9055..e64ad6a5c 100644 --- a/vsphere/resource_vsphere_compute_cluster.go +++ b/vsphere/resource_vsphere_compute_cluster.go @@ -153,10 +153,11 @@ func resourceVSphereComputeCluster() *schema.Resource { StateFunc: folder.NormalizePath, }, "host_cluster_exit_timeout": { - Type: schema.TypeInt, - Optional: true, - Default: 3600, - Description: "The timeout for each host maintenance mode operation when removing hosts from a cluster.", + Type: schema.TypeInt, + Optional: true, + Default: 3600, + Description: "The timeout for each host maintenance mode operation when removing hosts from a cluster.", + ValidateFunc: validation.IntBetween(0, 604800), }, "force_evacuate_on_destroy": { Type: schema.TypeBool, @@ -806,7 +807,7 @@ func resourceVSphereComputeClusterProcessHostUpdate( return fmt.Errorf("while fetching properties for host %q: %s", hs.Reference().Value, err) } if hsProps.Runtime.InMaintenanceMode { - err := hostsystem.ExitMaintenanceMode(hs, int(provider.DefaultAPITimeout)) + err := hostsystem.ExitMaintenanceMode(hs, provider.DefaultAPITimeout) if err != nil { return fmt.Errorf("while getting host %q out of maintenance mode: %s", hs.Reference().Value, err) } diff --git a/vsphere/resource_vsphere_host.go b/vsphere/resource_vsphere_host.go index fc3eb11a0..d46aac6f9 100644 --- a/vsphere/resource_vsphere_host.go +++ b/vsphere/resource_vsphere_host.go @@ -4,7 +4,8 @@ import ( "context" "fmt" "log" - "time" + + "github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/provider" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" @@ -294,9 +295,9 @@ func resourceVsphereHostCreate(d *schema.ResourceData, meta interface{}) error { maintenanceMode := d.Get("maintenance").(bool) if maintenanceMode { - err = hostsystem.EnterMaintenanceMode(host, int(defaultAPITimeout/time.Minute), true) + err = hostsystem.EnterMaintenanceMode(host, provider.DefaultAPITimeout, true) } else { - err = hostsystem.ExitMaintenanceMode(host, int(defaultAPITimeout/time.Minute)) + err = hostsystem.ExitMaintenanceMode(host, provider.DefaultAPITimeout) } if err != nil { return fmt.Errorf("error while toggling maintenance mode for host %s. Error: %s", hostID, err) @@ -478,9 +479,9 @@ func resourceVSphereHostUpdateMaintenanceMode(d *schema.ResourceData, meta, old, maintenanceMode := newVal.(bool) if maintenanceMode { - err = hostsystem.EnterMaintenanceMode(host, int(defaultAPITimeout/time.Minute), true) + err = hostsystem.EnterMaintenanceMode(host, provider.DefaultAPITimeout, true) } else { - err = hostsystem.ExitMaintenanceMode(host, int(defaultAPITimeout/time.Minute)) + err = hostsystem.ExitMaintenanceMode(host, provider.DefaultAPITimeout) } if err != nil { return fmt.Errorf("error while toggling maintenance mode for host %s. Error: %s", host.Name(), err) @@ -517,7 +518,7 @@ func resourceVSphereHostUpdateCluster(d *schema.ResourceData, meta, old, newVal return fmt.Errorf("error while retrieving HostSystem object for host ID %s. Error: %s", hostID, err) } - err = hostsystem.EnterMaintenanceMode(hs, int(defaultAPITimeout/time.Minute), true) + err = hostsystem.EnterMaintenanceMode(hs, provider.DefaultAPITimeout, true) if err != nil { return fmt.Errorf("error while putting host to maintenance mode: %s", err.Error()) } @@ -532,7 +533,7 @@ func resourceVSphereHostUpdateCluster(d *schema.ResourceData, meta, old, newVal return fmt.Errorf("error while moving host to new cluster (%s): %s", newClusterID, err) } - err = hostsystem.ExitMaintenanceMode(hs, int(defaultAPITimeout/time.Minute)) + err = hostsystem.ExitMaintenanceMode(hs, provider.DefaultAPITimeout) if err != nil { return fmt.Errorf("error while taking host out of maintenance mode: %s", err.Error()) } @@ -568,7 +569,7 @@ func resourceVSphereHostReconnect(d *schema.ResourceData, meta interface{}) erro maintenanceConfig := d.Get("maintenance").(bool) if maintenanceState && !maintenanceConfig { - err := hostsystem.ExitMaintenanceMode(host, int(defaultAPITimeout/time.Minute)) + err := hostsystem.ExitMaintenanceMode(host, provider.DefaultAPITimeout) if err != nil { return fmt.Errorf("error while taking host %s out of maintenance mode. Error: %s", host.Name(), err) } From c656e2021c0d7aa2822f117eb98665b195947818 Mon Sep 17 00:00:00 2001 From: Kyriakos Oikonomakos Date: Tue, 20 Apr 2021 17:10:49 +0100 Subject: [PATCH 2/2] update changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 601dca805..bbfd453c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,11 @@ BUG FIXES: * Minor fixes of issues that came up during testing against vSphere 7.0 +* Change the way we set the timeout for maintenance mode ([#1392](https://github.com/hashicorp/terraform-provider-vsphere/pull/1392)) IMPROVEMENTS: -* `provider`: vSphere 7 compatibility validation ([1381](https://github.com/hashicorp/terraform-provider-vsphere/pull/1381)) -* `resource/vm`: Allow hardware version up to 19 ([1391](https://github.com/hashicorp/terraform-provider-vsphere/pull/1391)) +* `provider`: vSphere 7 compatibility validation ([#1381](https://github.com/hashicorp/terraform-provider-vsphere/pull/1381)) +* `resource/vm`: Allow hardware version up to 19 ([#1391](https://github.com/hashicorp/terraform-provider-vsphere/pull/1391)) ## 1.25.0 (March 17, 2021)