github.com/vmware/govmomi@v0.43.0/govc/vm/disk/create.go (about)

     1  /*
     2  Copyright (c) 2014-2024 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package disk
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"flag"
    23  	"fmt"
    24  	"strings"
    25  
    26  	"github.com/vmware/govmomi/govc/cli"
    27  	"github.com/vmware/govmomi/govc/flags"
    28  	"github.com/vmware/govmomi/units"
    29  	"github.com/vmware/govmomi/vim25/types"
    30  )
    31  
    32  type create struct {
    33  	*flags.DatastoreFlag
    34  	*flags.OutputFlag
    35  	*flags.VirtualMachineFlag
    36  	*flags.StorageProfileFlag
    37  
    38  	controller string
    39  	Name       string
    40  	Bytes      units.ByteSize
    41  	Thick      bool
    42  	Eager      bool
    43  	DiskMode   string
    44  	Sharing    string
    45  }
    46  
    47  var vdmTypes = types.VirtualDiskMode("").Strings()
    48  
    49  var sharing = types.VirtualDiskSharing("").Strings()
    50  
    51  func init() {
    52  	cli.Register("vm.disk.create", &create{})
    53  }
    54  
    55  func (cmd *create) Register(ctx context.Context, f *flag.FlagSet) {
    56  	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
    57  	cmd.DatastoreFlag.Register(ctx, f)
    58  	cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx)
    59  	cmd.OutputFlag.Register(ctx, f)
    60  	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
    61  	cmd.VirtualMachineFlag.Register(ctx, f)
    62  	cmd.StorageProfileFlag, ctx = flags.NewStorageProfileFlag(ctx)
    63  	cmd.StorageProfileFlag.Register(ctx, f)
    64  
    65  	err := (&cmd.Bytes).Set("10G")
    66  	if err != nil {
    67  		panic(err)
    68  	}
    69  
    70  	f.StringVar(&cmd.controller, "controller", "", "Disk controller")
    71  	f.StringVar(&cmd.Name, "name", "", "Name for new disk")
    72  	f.Var(&cmd.Bytes, "size", "Size of new disk")
    73  	f.BoolVar(&cmd.Thick, "thick", false, "Thick provision new disk")
    74  	f.BoolVar(&cmd.Eager, "eager", false, "Eagerly scrub new disk")
    75  	f.StringVar(&cmd.DiskMode, "mode", vdmTypes[0], fmt.Sprintf("Disk mode (%s)", strings.Join(vdmTypes, "|")))
    76  	f.StringVar(&cmd.Sharing, "sharing", "", fmt.Sprintf("Sharing (%s)", strings.Join(sharing, "|")))
    77  }
    78  
    79  func (cmd *create) Process(ctx context.Context) error {
    80  	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
    81  		return err
    82  	}
    83  	if err := cmd.OutputFlag.Process(ctx); err != nil {
    84  		return err
    85  	}
    86  	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
    87  		return err
    88  	}
    89  	if err := cmd.StorageProfileFlag.Process(ctx); err != nil {
    90  		return err
    91  	}
    92  	return nil
    93  }
    94  
    95  func (cmd *create) Description() string {
    96  	return `Create disk and attach to VM.
    97  
    98  Examples:
    99    govc vm.disk.create -vm $name -name $name/disk1 -size 10G
   100    govc vm.disk.create -vm $name -name $name/disk2 -size 10G -eager -thick -sharing sharingMultiWriter`
   101  }
   102  
   103  func (cmd *create) Run(ctx context.Context, f *flag.FlagSet) error {
   104  	if len(cmd.Name) == 0 {
   105  		return errors.New("please specify a disk name")
   106  	}
   107  
   108  	vm, err := cmd.VirtualMachine()
   109  	if err != nil {
   110  		return err
   111  	}
   112  	if vm == nil {
   113  		return errors.New("please specify a vm")
   114  	}
   115  
   116  	ds, err := cmd.Datastore()
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	profile, err := cmd.StorageProfileSpec(ctx)
   122  	if err != nil {
   123  		return err
   124  	}
   125  
   126  	devices, err := vm.Device(ctx)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	controller, err := devices.FindDiskController(cmd.controller)
   132  	if err != nil {
   133  		return err
   134  	}
   135  
   136  	vdmMatch := false
   137  	for _, vdm := range vdmTypes {
   138  		if cmd.DiskMode == vdm {
   139  			vdmMatch = true
   140  		}
   141  	}
   142  
   143  	if !vdmMatch {
   144  		return errors.New("please specify a valid disk mode")
   145  	}
   146  
   147  	disk := devices.CreateDisk(controller, ds.Reference(), ds.Path(cmd.Name))
   148  
   149  	existing := devices.SelectByBackingInfo(disk.Backing)
   150  
   151  	if len(existing) > 0 {
   152  		_, _ = cmd.Log("Disk already present\n")
   153  		return nil
   154  	}
   155  
   156  	backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo)
   157  
   158  	if cmd.Thick {
   159  		backing.ThinProvisioned = types.NewBool(false)
   160  		backing.EagerlyScrub = types.NewBool(cmd.Eager)
   161  	}
   162  
   163  	backing.DiskMode = cmd.DiskMode
   164  	backing.Sharing = cmd.Sharing
   165  
   166  	_, _ = cmd.Log("Creating disk\n")
   167  	disk.CapacityInKB = int64(cmd.Bytes) / 1024
   168  	return vm.AddDeviceWithProfile(ctx, profile, disk)
   169  }