github.com/vmware/govmomi@v0.51.0/cli/gpu/vm/info.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  	"io"
    12  	"text/tabwriter"
    13  
    14  	"github.com/vmware/govmomi/cli"
    15  	"github.com/vmware/govmomi/cli/flags"
    16  	"github.com/vmware/govmomi/property"
    17  	"github.com/vmware/govmomi/vim25/mo"
    18  	"github.com/vmware/govmomi/vim25/types"
    19  )
    20  
    21  type info struct {
    22  	*flags.ClientFlag
    23  	*flags.VirtualMachineFlag
    24  }
    25  
    26  func init() {
    27  	cli.Register("gpu.vm.info", &info{})
    28  }
    29  
    30  func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) {
    31  	cmd.ClientFlag, ctx = flags.NewClientFlag(ctx)
    32  	cmd.ClientFlag.Register(ctx, f)
    33  
    34  	cmd.VirtualMachineFlag, ctx = flags.NewVirtualMachineFlag(ctx)
    35  	cmd.VirtualMachineFlag.Register(ctx, f)
    36  }
    37  
    38  func (cmd *info) Process(ctx context.Context) error {
    39  	if err := cmd.ClientFlag.Process(ctx); err != nil {
    40  		return err
    41  	}
    42  	if err := cmd.VirtualMachineFlag.Process(ctx); err != nil {
    43  		return err
    44  	}
    45  	return nil
    46  }
    47  
    48  func (cmd *info) Description() string {
    49  	return `Display GPU information for a VM.
    50  
    51  Examples:
    52    govc gpu.vm.info -vm $vm
    53    govc gpu.vm.info -vm $vm -json | jq -r '.gpus[].summary'
    54    govc gpu.vm.info -vm $vm -json | jq -r '.gpus[] | select(.summary | contains("nvidia_a40"))'`
    55  }
    56  
    57  type gpuInfo struct {
    58  	Index    int    `json:"index"`
    59  	Label    string `json:"label"`
    60  	Summary  string `json:"summary"`
    61  	NumaNode int32  `json:"numaNode"`
    62  	Key      int32  `json:"key"`
    63  }
    64  
    65  type infoResult struct {
    66  	GPUs []gpuInfo `json:"gpus"`
    67  }
    68  
    69  func (r *infoResult) Write(w io.Writer) error {
    70  	tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0)
    71  	for _, gpu := range r.GPUs {
    72  		fmt.Fprintf(tw, "GPU %d:\n", gpu.Index)
    73  		fmt.Fprintf(tw, "  Label: %s\n", gpu.Label)
    74  		fmt.Fprintf(tw, "  Summary: %s\n", gpu.Summary)
    75  		fmt.Fprintf(tw, "  Numa Node: %d\n", gpu.NumaNode)
    76  		fmt.Fprintf(tw, "  Key: %d\n", gpu.Key)
    77  	}
    78  	return tw.Flush()
    79  }
    80  
    81  func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error {
    82  	c, err := cmd.Client()
    83  	if err != nil {
    84  		return err
    85  	}
    86  
    87  	vm, err := cmd.VirtualMachine()
    88  	if err != nil {
    89  		return err
    90  	}
    91  
    92  	if vm == nil {
    93  		return flag.ErrHelp
    94  	}
    95  
    96  	var o mo.VirtualMachine
    97  	pc := property.DefaultCollector(c)
    98  	err = pc.RetrieveOne(ctx, vm.Reference(), []string{"name", "config.hardware", "runtime.powerState"}, &o)
    99  	if err != nil {
   100  		return err
   101  	}
   102  
   103  	if o.Config == nil {
   104  		return fmt.Errorf("VM configuration not available")
   105  	}
   106  
   107  	var res infoResult
   108  	gpuCount := 0
   109  	for _, device := range o.Config.Hardware.Device {
   110  		if pciDevice, ok := device.(*types.VirtualPCIPassthrough); ok {
   111  			gpu := gpuInfo{
   112  				Index:    gpuCount,
   113  				NumaNode: pciDevice.NumaNode,
   114  				Key:      pciDevice.Key,
   115  			}
   116  			if desc := pciDevice.DeviceInfo.GetDescription(); desc != nil {
   117  				gpu.Label = desc.Label
   118  				gpu.Summary = desc.Summary
   119  			}
   120  			res.GPUs = append(res.GPUs, gpu)
   121  			gpuCount++
   122  		}
   123  	}
   124  
   125  	return cmd.WriteResult(&res)
   126  }