github.com/vmware/govmomi@v0.51.0/cli/vm/migrate.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package vm 6 7 import ( 8 "context" 9 "flag" 10 "fmt" 11 12 "github.com/vmware/govmomi/cli" 13 "github.com/vmware/govmomi/cli/flags" 14 "github.com/vmware/govmomi/object" 15 "github.com/vmware/govmomi/vim25/types" 16 ) 17 18 type migrate struct { 19 *flags.FolderFlag 20 *flags.ResourcePoolFlag 21 *flags.HostSystemFlag 22 *flags.DatastoreFlag 23 *flags.NetworkFlag 24 *flags.VirtualMachineFlag 25 26 priority types.VirtualMachineMovePriority 27 spec types.VirtualMachineRelocateSpec 28 } 29 30 func init() { 31 cli.Register("vm.migrate", &migrate{}) 32 } 33 34 func (cmd *migrate) Register(ctx context.Context, f *flag.FlagSet) { 35 cmd.FolderFlag, ctx = flags.NewFolderFlag(ctx) 36 cmd.FolderFlag.Register(ctx, f) 37 38 cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) 39 cmd.VirtualMachineFlag.Register(ctx, f) 40 41 cmd.ResourcePoolFlag, ctx = flags.NewResourcePoolFlag(ctx) 42 cmd.ResourcePoolFlag.Register(ctx, f) 43 44 cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) 45 cmd.HostSystemFlag.Register(ctx, f) 46 47 cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) 48 cmd.DatastoreFlag.Register(ctx, f) 49 50 cmd.NetworkFlag, ctx = flags.NewNetworkFlag(ctx) 51 cmd.NetworkFlag.Register(ctx, f) 52 53 f.StringVar((*string)(&cmd.priority), "priority", string(types.VirtualMachineMovePriorityDefaultPriority), "The task priority") 54 } 55 56 func (cmd *migrate) Process(ctx context.Context) error { 57 if err := cmd.FolderFlag.Process(ctx); err != nil { 58 return err 59 } 60 if err := cmd.VirtualMachineFlag.Process(ctx); err != nil { 61 return err 62 } 63 if err := cmd.ResourcePoolFlag.Process(ctx); err != nil { 64 return err 65 } 66 if err := cmd.HostSystemFlag.Process(ctx); err != nil { 67 return err 68 } 69 if err := cmd.DatastoreFlag.Process(ctx); err != nil { 70 return err 71 } 72 if err := cmd.NetworkFlag.Process(ctx); err != nil { 73 return err 74 } 75 76 return nil 77 } 78 79 func (cmd *migrate) Usage() string { 80 return "VM..." 81 } 82 83 func (cmd *migrate) Description() string { 84 return `Migrates VM to a specific resource pool, host or datastore. 85 86 Examples: 87 govc vm.migrate -host another-host vm-1 vm-2 vm-3 88 govc vm.migrate -pool another-pool vm-1 vm-2 vm-3 89 govc vm.migrate -ds another-ds vm-1 vm-2 vm-3` 90 } 91 92 func (cmd *migrate) relocate(ctx context.Context, vm *object.VirtualMachine) error { 93 spec := cmd.spec 94 95 if cmd.NetworkFlag.IsSet() { 96 dev, err := cmd.NetworkFlag.Device() 97 if err != nil { 98 return err 99 } 100 101 devices, err := vm.Device(ctx) 102 if err != nil { 103 return err 104 } 105 106 net := devices.SelectByType((*types.VirtualEthernetCard)(nil)) 107 if len(net) != 1 { 108 return fmt.Errorf("-net specified, but %s has %d nics", vm.Name(), len(net)) 109 } 110 cmd.NetworkFlag.Change(net[0], dev) 111 112 spec.DeviceChange = append(spec.DeviceChange, &types.VirtualDeviceConfigSpec{ 113 Device: net[0], 114 Operation: types.VirtualDeviceConfigSpecOperationEdit, 115 }) 116 } 117 118 if cmd.VirtualMachineFlag.Spec { 119 return cmd.VirtualMachineFlag.WriteAny(spec) 120 } 121 122 task, err := vm.Relocate(ctx, spec, cmd.priority) 123 if err != nil { 124 return err 125 } 126 127 logger := cmd.DatastoreFlag.ProgressLogger(fmt.Sprintf("migrating %s... ", vm.Reference())) 128 _, err = task.WaitForResult(ctx, logger) 129 if err != nil { 130 return err 131 } 132 133 logger.Wait() 134 135 return nil 136 } 137 138 func (cmd *migrate) Run(ctx context.Context, f *flag.FlagSet) error { 139 vms, err := cmd.VirtualMachineFlag.VirtualMachines(f.Args()) 140 if err != nil { 141 return err 142 } 143 144 folder, err := cmd.FolderIfSpecified() 145 if err != nil { 146 return err 147 } 148 149 if folder != nil { 150 ref := folder.Reference() 151 cmd.spec.Folder = &ref 152 } 153 154 host, err := cmd.HostSystemFlag.HostSystemIfSpecified() 155 if err != nil { 156 return err 157 } 158 159 if host != nil { 160 ref := host.Reference() 161 cmd.spec.Host = &ref 162 } 163 164 pool, err := cmd.ResourcePoolFlag.ResourcePoolIfSpecified() 165 if err != nil { 166 return err 167 } 168 169 if pool == nil && host != nil { 170 pool, err = host.ResourcePool(ctx) 171 if err != nil { 172 return err 173 } 174 } 175 176 if pool != nil { 177 ref := pool.Reference() 178 cmd.spec.Pool = &ref 179 } 180 181 ds, err := cmd.DatastoreFlag.DatastoreIfSpecified() 182 if err != nil { 183 return err 184 } 185 186 if ds != nil { 187 ref := ds.Reference() 188 cmd.spec.Datastore = &ref 189 } 190 191 for _, vm := range vms { 192 err = cmd.relocate(ctx, vm) 193 if err != nil { 194 return err 195 } 196 } 197 198 return nil 199 }