1package vm
2
3import (
4	"context"
5	"flag"
6
7	"fmt"
8
9	"github.com/vmware/govmomi/govc/cli"
10	"github.com/vmware/govmomi/govc/flags"
11	"github.com/vmware/govmomi/task"
12	"github.com/vmware/govmomi/vim25/types"
13)
14
15type upgrade struct {
16	*flags.VirtualMachineFlag
17	version int
18}
19
20func init() {
21	cli.Register("vm.upgrade", &upgrade{})
22}
23
24func isAlreadyUpgraded(err error) bool {
25	if fault, ok := err.(task.Error); ok {
26		_, ok = fault.Fault().(*types.AlreadyUpgraded)
27		return ok
28	}
29
30	return false
31}
32
33func (cmd *upgrade) Register(ctx context.Context, f *flag.FlagSet) {
34	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
35	cmd.VirtualMachineFlag.Register(ctx, f)
36
37	f.IntVar(&cmd.version, "version", 0, "Target vm hardware version, by default -- latest available")
38}
39
40func (cmd *upgrade) Process(ctx context.Context) error {
41	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
42		return err
43	}
44	return nil
45}
46
47func (cmd *upgrade) Description() string {
48	return `Upgrade VMs to latest hardware version
49
50Examples:
51  govc vm.upgrade -vm $vm_name
52  govc vm.upgrade -version=$version -vm $vm_name
53  govc vm.upgrade -version=$version -vm.uuid $vm_uuid`
54}
55
56func (cmd *upgrade) Run(ctx context.Context, f *flag.FlagSet) error {
57	vm, err := cmd.VirtualMachine()
58	if err != nil {
59		return err
60	}
61
62	var version = ""
63	if cmd.version != 0 {
64		version = fmt.Sprintf("vmx-%02d", cmd.version)
65	}
66
67	task, err := vm.UpgradeVM(ctx, version)
68	if err != nil {
69		return err
70	}
71	err = task.Wait(ctx)
72	if err != nil {
73		if isAlreadyUpgraded(err) {
74			fmt.Println(err.Error())
75		} else {
76			return err
77		}
78	}
79
80	return nil
81}
82