github.com/vmware/govmomi@v0.51.0/cli/vm/disk/create.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/units"
    17  	"github.com/vmware/govmomi/vim25/types"
    18  )
    19  
    20  type create struct {
    21  	*flags.DatastoreFlag
    22  	*flags.OutputFlag
    23  	*flags.VirtualMachineFlag
    24  	*flags.StorageProfileFlag
    25  
    26  	controller string
    27  	Name       string
    28  	Bytes      units.ByteSize
    29  	Thick      bool
    30  	Eager      bool
    31  	DiskMode   string
    32  	Sharing    string
    33  }
    34  
    35  var vdmTypes = types.VirtualDiskMode("").Strings()
    36  
    37  var sharing = types.VirtualDiskSharing("").Strings()
    38  
    39  func init() {
    40  	cli.Register("vm.disk.create", &create{})
    41  }
    42  
    43  func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
    44  	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
    45  	cmd.DatastoreFlag.Register(ctx, f)
    46  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    47  	cmd.OutputFlag.Register(ctx, f)
    48  	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
    49  	cmd.VirtualMachineFlag.Register(ctx, f)
    50  	cmd.StorageProfileFlag, ctx = flags.NewStorageProfileFlag(ctx)
    51  	cmd.StorageProfileFlag.Register(ctx, f)
    52  
    53  	err := (&cmd.Bytes).Set("10G")
    54  	if err != nil {
    55  		panic(err)
    56  	}
    57  
    58  	f.StringVar(&cmd.controller, "controller", "", "Disk controller")
    59  	f.StringVar(&cmd.Name, "name", "", "Name for new disk")
    60  	f.Var(&cmd.Bytes, "size", "Size of new disk")
    61  	f.BoolVar(&cmd.Thick, "thick", false, "Thick provision new disk")
    62  	f.BoolVar(&cmd.Eager, "eager", false, "Eagerly scrub new disk")
    63  	f.StringVar(&cmd.DiskMode, "mode", vdmTypes[0], fmt.Sprintf("Disk mode (%s)", strings.Join(vdmTypes, "|")))
    64  	f.StringVar(&cmd.Sharing, "sharing", "", fmt.Sprintf("Sharing (%s)", strings.Join(sharing, "|")))
    65  }
    66  
    67  func (cmd *create) Process(ctx context.Context) error {
    68  	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
    69  		return err
    70  	}
    71  	if err := cmd.OutputFlag.Process(ctx); err != nil {
    72  		return err
    73  	}
    74  	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
    75  		return err
    76  	}
    77  	if err := cmd.StorageProfileFlag.Process(ctx); err != nil {
    78  		return err
    79  	}
    80  	return nil
    81  }
    82  
    83  func (cmd *create) Description() string {
    84  	return `Create disk and attach to VM.
    85  
    86  Examples:
    87    govc vm.disk.create -vm $name -name $name/disk1 -size 10G
    88    govc vm.disk.create -vm $name -name $name/disk2 -size 10G -eager -thick -sharing sharingMultiWriter`
    89  }
    90  
    91  func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
    92  	if len(cmd.Name) == 0 {
    93  		return errors.New("please specify a disk name")
    94  	}
    95  
    96  	vm, err := cmd.VirtualMachine()
    97  	if err != nil {
    98  		return err
    99  	}
   100  	if vm == nil {
   101  		return errors.New("please specify a vm")
   102  	}
   103  
   104  	ds, err := cmd.Datastore()
   105  	if err != nil {
   106  		return err
   107  	}
   108  
   109  	profile, err := cmd.StorageProfileSpec(ctx)
   110  	if err != nil {
   111  		return err
   112  	}
   113  
   114  	devices, err := vm.Device(ctx)
   115  	if err != nil {
   116  		return err
   117  	}
   118  
   119  	controller, err := devices.FindDiskController(cmd.controller)
   120  	if err != nil {
   121  		return err
   122  	}
   123  
   124  	vdmMatch := false
   125  	for _, vdm := range vdmTypes {
   126  		if cmd.DiskMode == vdm {
   127  			vdmMatch = true
   128  		}
   129  	}
   130  
   131  	if !vdmMatch {
   132  		return errors.New("please specify a valid disk mode")
   133  	}
   134  
   135  	disk := devices.CreateDisk(controller, ds.Reference(), ds.Path(cmd.Name))
   136  
   137  	existing := devices.SelectByBackingInfo(disk.Backing)
   138  
   139  	if len(existing) > 0 {
   140  		_, _ = cmd.Log("Disk already present\n")
   141  		return nil
   142  	}
   143  
   144  	backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo)
   145  
   146  	if cmd.Thick {
   147  		backing.ThinProvisioned = types.NewBool(false)
   148  		backing.EagerlyScrub = types.NewBool(cmd.Eager)
   149  	}
   150  
   151  	backing.DiskMode = cmd.DiskMode
   152  	backing.Sharing = cmd.Sharing
   153  
   154  	_, _ = cmd.Log("Creating disk\n")
   155  	disk.CapacityInKB = int64(cmd.Bytes) / 1024
   156  	return vm.AddDeviceWithProfile(ctx, profile, disk)
   157  }