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 }