github.com/vmware/govmomi@v0.51.0/cli/host/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 host 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/object" 17 "github.com/vmware/govmomi/property" 18 "github.com/vmware/govmomi/vim25/mo" 19 "github.com/vmware/govmomi/vim25/types" 20 ) 21 22 type info struct { 23 *flags.ClientFlag 24 *flags.OutputFlag 25 *flags.HostSystemFlag 26 } 27 28 func init() { 29 cli.Register("host.info", &info{}) 30 } 31 32 func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) { 33 cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) 34 cmd.ClientFlag.Register(ctx, f) 35 36 cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) 37 cmd.OutputFlag.Register(ctx, f) 38 39 cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) 40 cmd.HostSystemFlag.Register(ctx, f) 41 } 42 43 func (cmd *info) Process(ctx context.Context) error { 44 if err := cmd.ClientFlag.Process(ctx); err != nil { 45 return err 46 } 47 if err := cmd.OutputFlag.Process(ctx); err != nil { 48 return err 49 } 50 if err := cmd.HostSystemFlag.Process(ctx); err != nil { 51 return err 52 } 53 return nil 54 } 55 56 func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { 57 c, err := cmd.Client() 58 if err != nil { 59 return err 60 } 61 62 var res infoResult 63 var props []string 64 65 if cmd.OutputFlag.All() { 66 props = nil // Load everything 67 } else { 68 props = []string{"summary"} // Load summary 69 } 70 71 // We could do without the -host flag, leaving it for compat 72 host, err := cmd.HostSystemIfSpecified() 73 if err != nil { 74 return err 75 } 76 77 // Default only if there is a single host 78 if host == nil && f.NArg() == 0 { 79 host, err = cmd.HostSystem() 80 if err != nil { 81 return err 82 } 83 } 84 85 if host != nil { 86 res.objects = append(res.objects, host) 87 } else { 88 res.objects, err = cmd.HostSystems(f.Args()) 89 if err != nil { 90 return err 91 } 92 } 93 94 if len(res.objects) != 0 { 95 refs := make([]types.ManagedObjectReference, 0, len(res.objects)) 96 for _, o := range res.objects { 97 refs = append(refs, o.Reference()) 98 } 99 100 pc := property.DefaultCollector(c) 101 err = pc.Retrieve(ctx, refs, props, &res.HostSystems) 102 if err != nil { 103 return err 104 } 105 } 106 107 return cmd.WriteResult(&res) 108 } 109 110 type infoResult struct { 111 HostSystems []mo.HostSystem `json:"hostSystems"` 112 objects []*object.HostSystem 113 } 114 115 func (r *infoResult) Write(w io.Writer) error { 116 // Maintain order via r.objects as Property collector does not always return results in order. 117 objects := make(map[types.ManagedObjectReference]mo.HostSystem, len(r.HostSystems)) 118 for _, o := range r.HostSystems { 119 objects[o.Reference()] = o 120 } 121 122 tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) 123 124 for _, o := range r.objects { 125 host := objects[o.Reference()] 126 s := host.Summary 127 h := s.Hardware 128 z := s.QuickStats 129 ncpu := int32(h.NumCpuCores) 130 cpuUsage := 100 * float64(z.OverallCpuUsage) / float64(ncpu*h.CpuMhz) 131 memUsage := 100 * float64(z.OverallMemoryUsage) / float64(h.MemorySize>>20) 132 133 fmt.Fprintf(tw, "Name:\t%s\n", s.Config.Name) 134 fmt.Fprintf(tw, " Path:\t%s\n", o.InventoryPath) 135 fmt.Fprintf(tw, " Manufacturer:\t%s\n", h.Vendor) 136 fmt.Fprintf(tw, " Logical CPUs:\t%d CPUs @ %dMHz\n", ncpu, h.CpuMhz) 137 fmt.Fprintf(tw, " Processor type:\t%s\n", h.CpuModel) 138 fmt.Fprintf(tw, " CPU usage:\t%d MHz (%.1f%%)\n", z.OverallCpuUsage, cpuUsage) 139 fmt.Fprintf(tw, " Memory:\t%dMB\n", h.MemorySize/(1024*1024)) 140 fmt.Fprintf(tw, " Memory usage:\t%d MB (%.1f%%)\n", z.OverallMemoryUsage, memUsage) 141 fmt.Fprintf(tw, " Boot time:\t%s\n", s.Runtime.BootTime) 142 if s.Runtime.InMaintenanceMode { 143 fmt.Fprint(tw, " State:\tMaintenance Mode\n") 144 } else { 145 fmt.Fprintf(tw, " State:\t%s\n", s.Runtime.ConnectionState) 146 } 147 } 148 149 return tw.Flush() 150 }