github.com/vmware/govmomi@v0.51.0/cli/vm/disk/change.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 disk 6 7 import ( 8 "context" 9 "errors" 10 "flag" 11 "fmt" 12 "strings" 13 14 "github.com/vmware/govmomi/cli" 15 "github.com/vmware/govmomi/cli/flags" 16 "github.com/vmware/govmomi/object" 17 "github.com/vmware/govmomi/units" 18 "github.com/vmware/govmomi/vim25/types" 19 ) 20 21 type change struct { 22 *flags.VirtualMachineFlag 23 24 name string 25 key int 26 label string 27 filePath string 28 sharing string 29 30 bytes units.ByteSize 31 mode string 32 33 // SIOC 34 limit *int64 35 } 36 37 func init() { 38 cli.Register("vm.disk.change", &change{}) 39 } 40 41 func (cmd *change) Description() string { 42 return `Change some properties of a VM's DISK 43 44 In particular, you can change the DISK mode, and the size (as long as it is bigger) 45 46 Examples: 47 govc vm.disk.change -vm VM -disk.key 2001 -size 10G 48 govc vm.disk.change -vm VM -disk.label "BDD disk" -size 10G 49 govc vm.disk.change -vm VM -disk.name "hard-1000-0" -size 12G 50 govc vm.disk.change -vm VM -disk.filePath "[DS] VM/VM-1.vmdk" -mode nonpersistent` 51 } 52 53 func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) { 54 cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx) 55 cmd.VirtualMachineFlag.Register(ctx, f) 56 err := (&cmd.bytes).Set("0G") 57 if err != nil { 58 panic(err) 59 } 60 f.Var(&cmd.bytes, "size", "New disk size") 61 f.StringVar(&cmd.name, "disk.name", "", "Disk name") 62 f.StringVar(&cmd.label, "disk.label", "", "Disk label") 63 f.StringVar(&cmd.filePath, "disk.filePath", "", "Disk file name") 64 f.IntVar(&cmd.key, "disk.key", 0, "Disk unique key") 65 f.StringVar(&cmd.mode, "mode", "", fmt.Sprintf("Disk mode (%s)", strings.Join(vdmTypes, "|"))) 66 f.StringVar(&cmd.sharing, "sharing", "", fmt.Sprintf("Sharing (%s)", strings.Join(sharing, "|"))) 67 f.Var(flags.NewOptionalInt64(&cmd.limit), "disk.io.limit", "Disk storage IO per seconds limit (-1 for unlimited)") 68 } 69 70 func (cmd *change) Process(ctx context.Context) error { 71 if err := cmd.VirtualMachineFlag.Process(ctx); err != nil { 72 return err 73 } 74 return nil 75 } 76 77 func (cmd *change) FindDisk(ctx context.Context, list object.VirtualDeviceList) (*types.VirtualDisk, error) { 78 var disks []*types.VirtualDisk 79 for _, device := range list { 80 switch md := device.(type) { 81 case *types.VirtualDisk: 82 if cmd.CheckDiskProperties(ctx, list.Name(device), md) { 83 disks = append(disks, md) 84 } 85 default: 86 continue 87 } 88 } 89 90 switch len(disks) { 91 case 0: 92 return nil, errors.New("no disk found using the given values") 93 case 1: 94 return disks[0], nil 95 } 96 return nil, errors.New("the given disk values match multiple disks") 97 } 98 99 func (cmd *change) CheckDiskProperties(ctx context.Context, name string, disk *types.VirtualDisk) bool { 100 switch { 101 case cmd.key != 0 && disk.Key != int32(cmd.key): 102 fallthrough 103 case cmd.name != "" && name != cmd.name: 104 fallthrough 105 case cmd.label != "" && disk.DeviceInfo.GetDescription().Label != cmd.label: 106 return false 107 case cmd.filePath != "": 108 if b, ok := disk.Backing.(types.BaseVirtualDeviceFileBackingInfo); ok { 109 if b.GetVirtualDeviceFileBackingInfo().FileName != cmd.filePath { 110 return false 111 } 112 } 113 } 114 return true 115 } 116 117 func (cmd *change) setMode(mode *string) { 118 if cmd.mode != "" { 119 *mode = cmd.mode 120 } 121 } 122 123 func (cmd *change) Run(ctx context.Context, f *flag.FlagSet) error { 124 vm, err := cmd.VirtualMachine() 125 if err != nil { 126 return err 127 } 128 129 if vm == nil { 130 return flag.ErrHelp 131 } 132 133 devices, err := vm.Device(ctx) 134 if err != nil { 135 return err 136 } 137 138 editdisk, err := cmd.FindDisk(ctx, devices) 139 if err != nil { 140 return err 141 } 142 143 if int64(cmd.bytes) != 0 { 144 editdisk.CapacityInBytes = int64(cmd.bytes) 145 } 146 147 if editdisk.StorageIOAllocation == nil { 148 editdisk.StorageIOAllocation = new(types.StorageIOAllocationInfo) 149 } 150 editdisk.StorageIOAllocation.Limit = cmd.limit 151 152 switch backing := editdisk.Backing.(type) { 153 case *types.VirtualDiskFlatVer2BackingInfo: 154 backing.Sharing = cmd.sharing 155 cmd.setMode(&backing.DiskMode) 156 case *types.VirtualDiskSeSparseBackingInfo: 157 cmd.setMode(&backing.DiskMode) 158 } 159 160 spec := types.VirtualMachineConfigSpec{} 161 162 config := &types.VirtualDeviceConfigSpec{ 163 Device: editdisk, 164 Operation: types.VirtualDeviceConfigSpecOperationEdit, 165 } 166 167 config.FileOperation = "" 168 169 spec.DeviceChange = append(spec.DeviceChange, config) 170 171 task, err := vm.Reconfigure(ctx, spec) 172 if err != nil { 173 return err 174 } 175 176 err = task.Wait(ctx) 177 if err != nil { 178 return fmt.Errorf("error resizing main disk\nLogged Item: %s", err) 179 } 180 return nil 181 }