Skip to content

Commit

Permalink
Merge pull request #1020 from terraform-providers/f-hw_version
Browse files Browse the repository at this point in the history
r/vm: Support hardware versions
  • Loading branch information
bill-rich authored Apr 3, 2020
2 parents ff95205 + cbe2a94 commit 1c52bb0
Show file tree
Hide file tree
Showing 6 changed files with 365 additions and 51 deletions.
51 changes: 0 additions & 51 deletions go.sum

Large diffs are not rendered by default.

58 changes: 58 additions & 0 deletions vsphere/internal/helper/virtualmachine/virtual_machine_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/vmware/govmomi/vapi/vcenter"
"log"
"net"
"strconv"
"strings"
"time"

Expand Down Expand Up @@ -865,3 +866,60 @@ func (r MOIDForUUIDResults) UUIDs() []string {
}
return uuids
}

// GetHardwareVersionID gets the hardware version string from integer
func GetHardwareVersionID(vint int) string {
// hardware_version isn't set, so return an empty string.
if vint == 0 {
return ""
}
return fmt.Sprintf("vmx-%d", vint)
}

// GetHardwareVersionNumber gets the hardware version number from string.
func GetHardwareVersionNumber(vstring string) int {
vstring = strings.TrimPrefix(vstring, "vmx-")
v, err := strconv.Atoi(vstring)
if err != nil {
log.Printf("[DEBUG] Unable to parse hardware version: %s", vstring)
}
return v
}

// SetHardwareVersion sets the virtual machine's hardware version. The virtual
// machine must be powered off, and the version can only be increased.
func SetHardwareVersion(vm *object.VirtualMachine, target int) error {
// First get current and target versions and validate
tv := GetHardwareVersionID(target)
vprops, err := Properties(vm)
if err != nil {
return err
}
cv := vprops.Config.Version
// Skip the rest if there is no version change.
if cv == tv {
return nil
}
if err := ValidateHardwareVersion(GetHardwareVersionNumber(cv), target); err != nil {
return err
}

ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout)
defer cancel()

task, err := vm.UpgradeVM(ctx, tv)
_, err = task.WaitForResult(ctx, nil)
return err
}

// ValidateHardwareVersion checks that the target hardware version is equal to
// or greater than the current hardware version.
func ValidateHardwareVersion(current, target int) error {
switch {
case target == 0:
return nil
case target < current:
return fmt.Errorf("Cannot downgrade virtual machine hardware version. current: %d, target: %d", current, target)
}
return nil
}
23 changes: 23 additions & 0 deletions vsphere/resource_vsphere_virtual_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,11 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{
return err
}
// Only carry out the reconfigure if we actually have a change to process.
cv := virtualmachine.GetHardwareVersionNumber(vprops.Config.Version)
tv := d.Get("hardware_version").(int)
if tv > cv {
d.Set("reboot_required", true)
}
if changed || len(spec.DeviceChange) > 0 {
//Check to see if we need to shutdown the VM for this process.
if d.Get("reboot_required").(bool) && vprops.Runtime.PowerState != types.VirtualMachinePowerStatePoweredOff {
Expand Down Expand Up @@ -668,6 +673,12 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{
err = virtualmachine.Reconfigure(vm, spec)
}

// Upgrade the VM's hardware version if needed.
err = virtualmachine.SetHardwareVersion(vm, d.Get("hardware_version").(int))
if err != nil {
return err
}

// Regardless of the result we no longer need to watch for pending questions.
gChan <- true

Expand Down Expand Up @@ -711,6 +722,7 @@ func resourceVSphereVirtualMachineUpdate(d *schema.ResourceData, meta interface{
}
}
}

// Now safe to turn off partial mode.
d.Partial(false)
d.Set("reboot_required", false)
Expand Down Expand Up @@ -886,6 +898,11 @@ func resourceVSphereVirtualMachineCustomizeDiff(d *schema.ResourceDiff, meta int
}
}
}

// Validate hardware version changes.
cv, tv := d.GetChange("hardware_version")
virtualmachine.ValidateHardwareVersion(cv.(int), tv.(int))

// Validate that the config has the necessary components for vApp support.
// Note that for clones the data is prepopulated in
// ValidateVirtualMachineClone.
Expand Down Expand Up @@ -1379,6 +1396,12 @@ func resourceVSphereVirtualMachineCreateClone(d *schema.ResourceData, meta inter
)
}

// Upgrade the VM's hardware version if needed.
err = virtualmachine.SetHardwareVersion(vm, d.Get("hardware_version").(int))
if err != nil {
return nil, err
}

var cw *virtualMachineCustomizationWaiter
// Send customization spec if any has been defined.
if len(d.Get("clone.0.customize").([]interface{})) > 0 {
Expand Down
Loading

0 comments on commit 1c52bb0

Please sign in to comment.