github.com/vmware/govmomi@v0.43.0/govc/vm/disk/attach.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  	"flag"
    22  	"fmt"
    23  	"strings"
    24  
    25  	"github.com/vmware/govmomi/govc/cli"
    26  	"github.com/vmware/govmomi/govc/flags"
    27  	"github.com/vmware/govmomi/vim25/types"
    28  )
    29  
    30  type attach struct {
    31  	*flags.DatastoreFlag
    32  	*flags.VirtualMachineFlag
    33  	*flags.StorageProfileFlag
    34  
    35  	persist    bool
    36  	link       bool
    37  	disk       string
    38  	controller string
    39  	mode       string
    40  	sharing    string
    41  }
    42  
    43  func init() {
    44  	cli.Register("vm.disk.attach", &attach{})
    45  }
    46  
    47  func (cmd *attach) Register(ctx context.Context, f *flag.FlagSet) {
    48  	cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx)
    49  	cmd.DatastoreFlag.Register(ctx, f)
    50  	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
    51  	cmd.VirtualMachineFlag.Register(ctx, f)
    52  	cmd.StorageProfileFlag, ctx = flags.NewStorageProfileFlag(ctx)
    53  	cmd.StorageProfileFlag.Register(ctx, f)
    54  
    55  	f.BoolVar(&cmd.persist, "persist", true, "Persist attached disk")
    56  	f.BoolVar(&cmd.link, "link", true, "Link specified disk")
    57  	f.StringVar(&cmd.controller, "controller", "", "Disk controller")
    58  	f.StringVar(&cmd.disk, "disk", "", "Disk path name")
    59  	f.StringVar(&cmd.mode, "mode", "", fmt.Sprintf("Disk mode (%s)", strings.Join(vdmTypes, "|")))
    60  	f.StringVar(&cmd.sharing, "sharing", "", fmt.Sprintf("Sharing (%s)", strings.Join(sharing, "|")))
    61  }
    62  
    63  func (cmd *attach) Process(ctx context.Context) error {
    64  	if err := cmd.DatastoreFlag.Process(ctx); err != nil {
    65  		return err
    66  	}
    67  	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
    68  		return err
    69  	}
    70  	if err := cmd.StorageProfileFlag.Process(ctx); err != nil {
    71  		return err
    72  	}
    73  	return nil
    74  }
    75  
    76  func (cmd *attach) Description() string {
    77  	return `Attach existing disk to VM.
    78  
    79  A delta disk is created by default, where changes are persisted. Specifying '-link=false' will persist to the same disk.
    80  
    81  Examples:
    82    govc vm.disk.attach -vm $name -disk $name/disk1.vmdk
    83    govc device.info -vm $name disk-* # 'File' field is where changes are persisted. 'Parent' field is set when '-link=true'
    84    govc vm.disk.attach -vm $name -disk $name/shared.vmdk -link=false -sharing sharingMultiWriter
    85    govc device.remove -vm $name -keep disk-* # detach disk(s)`
    86  }
    87  
    88  func (cmd *attach) Run(ctx context.Context, f *flag.FlagSet) error {
    89  	vm, err := cmd.VirtualMachine()
    90  	if err != nil {
    91  		return err
    92  	}
    93  
    94  	if vm == nil {
    95  		return flag.ErrHelp
    96  	}
    97  
    98  	ds, err := cmd.Datastore()
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	devices, err := vm.Device(ctx)
   104  	if err != nil {
   105  		return err
   106  	}
   107  
   108  	controller, err := devices.FindDiskController(cmd.controller)
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	disk := devices.CreateDisk(controller, ds.Reference(), ds.Path(cmd.disk))
   114  	backing := disk.Backing.(*types.VirtualDiskFlatVer2BackingInfo)
   115  	backing.Sharing = cmd.sharing
   116  
   117  	if cmd.link {
   118  		if cmd.persist {
   119  			backing.DiskMode = string(types.VirtualDiskModeIndependent_persistent)
   120  		} else {
   121  			backing.DiskMode = string(types.VirtualDiskModeIndependent_nonpersistent)
   122  		}
   123  
   124  		disk = devices.ChildDisk(disk)
   125  		return vm.AddDevice(ctx, disk)
   126  	} else {
   127  		if cmd.persist {
   128  			backing.DiskMode = string(types.VirtualDiskModePersistent)
   129  		} else {
   130  			backing.DiskMode = string(types.VirtualDiskModeNonpersistent)
   131  		}
   132  	}
   133  
   134  	if len(cmd.mode) != 0 {
   135  		backing.DiskMode = cmd.mode
   136  	}
   137  
   138  	profile, err := cmd.StorageProfileSpec(ctx)
   139  	if err != nil {
   140  		return err
   141  	}
   142  
   143  	return vm.AddDeviceWithProfile(ctx, profile, disk)
   144  }