github.com/vmware/govmomi@v0.51.0/cli/gpu/vm/add.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/property"
    15  	"github.com/vmware/govmomi/vim25/mo"
    16  	"github.com/vmware/govmomi/vim25/types"
    17  )
    18  
    19  type add struct {
    20  	*flags.ClientFlag
    21  	*flags.VirtualMachineFlag
    22  	profile string
    23  }
    24  
    25  func init() {
    26  	cli.Register("gpu.vm.add", &add{})
    27  }
    28  
    29  func (cmd *add) Register(ctx context.Context, f *flag.FlagSet) {
    30  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    31  	cmd.ClientFlag.Register(ctx, f)
    32  
    33  	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
    34  	cmd.VirtualMachineFlag.Register(ctx, f)
    35  
    36  	f.StringVar(&cmd.profile, "profile", "", "vGPU profile")
    37  }
    38  
    39  func (cmd *add) Description() string {
    40  	return `Add vGPU to VM.
    41  
    42  Examples:
    43    govc gpu.vm.add -vm $vm -profile nvidia_a40-1b`
    44  }
    45  
    46  func (cmd *add) Process(ctx context.Context) error {
    47  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    48  		return err
    49  	}
    50  	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
    51  		return err
    52  	}
    53  	return nil
    54  }
    55  
    56  func (cmd *add) Run(ctx context.Context, f *flag.FlagSet) error {
    57  	vm, err := cmd.VirtualMachineFlag.VirtualMachine()
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	if vm == nil {
    63  		return flag.ErrHelp
    64  	}
    65  
    66  	if cmd.profile == "" {
    67  		return fmt.Errorf("profile argument must be specified")
    68  	}
    69  
    70  	// Check power state
    71  	var o mo.VirtualMachine
    72  	pc := property.DefaultCollector(vm.Client())
    73  	err = pc.RetrieveOne(ctx, vm.Reference(), []string{"runtime.powerState"}, &o)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	if o.Runtime.PowerState == types.VirtualMachinePowerStatePoweredOn {
    79  		return fmt.Errorf("VM must be powered off to add vGPU")
    80  	}
    81  
    82  	device := &types.VirtualPCIPassthrough{
    83  		VirtualDevice: types.VirtualDevice{
    84  			Key: -100,
    85  			Backing: &types.VirtualPCIPassthroughVmiopBackingInfo{
    86  				Vgpu: cmd.profile,
    87  			},
    88  		},
    89  	}
    90  
    91  	vmConfigSpec := types.VirtualMachineConfigSpec{
    92  		DeviceChange: []types.BaseVirtualDeviceConfigSpec{
    93  			&types.VirtualDeviceConfigSpec{
    94  				Operation: types.VirtualDeviceConfigSpecOperationAdd,
    95  				Device:    device,
    96  			},
    97  		},
    98  	}
    99  
   100  	task, err := vm.Reconfigure(ctx, vmConfigSpec)
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	return task.Wait(ctx)
   106  }