github.com/vmware/govmomi@v0.43.0/govc/host/storage/info.go (about) 1 /* 2 Copyright (c) 2015 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 storage 18 19 import ( 20 "context" 21 "flag" 22 "fmt" 23 "io" 24 "strings" 25 "text/tabwriter" 26 27 "github.com/vmware/govmomi/govc/cli" 28 "github.com/vmware/govmomi/govc/flags" 29 "github.com/vmware/govmomi/units" 30 "github.com/vmware/govmomi/vim25/mo" 31 "github.com/vmware/govmomi/vim25/types" 32 ) 33 34 var infoTypes = []string{"hba", "lun"} 35 36 type infoType string 37 38 func (t *infoType) Set(s string) error { 39 s = strings.ToLower(s) 40 41 for _, e := range infoTypes { 42 if s == e { 43 *t = infoType(s) 44 return nil 45 } 46 } 47 48 return fmt.Errorf("invalid type") 49 } 50 51 func (t *infoType) String() string { 52 return string(*t) 53 } 54 55 func (t *infoType) Result(hss mo.HostStorageSystem) flags.OutputWriter { 56 switch string(*t) { 57 case "hba": 58 return hbaResult(hss) 59 case "lun": 60 return lunResult(hss) 61 default: 62 panic("unsupported") 63 } 64 } 65 66 type info struct { 67 *flags.HostSystemFlag 68 *flags.OutputFlag 69 70 typ infoType 71 rescan bool 72 refresh bool 73 rescanvmfs bool 74 unclaimed bool 75 } 76 77 func init() { 78 cli.Register("host.storage.info", &info{}) 79 } 80 81 func (cmd *info) Register(ctx context.Context, f *flag.FlagSet) { 82 cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) 83 cmd.HostSystemFlag.Register(ctx, f) 84 cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) 85 cmd.OutputFlag.Register(ctx, f) 86 87 err := cmd.typ.Set("lun") 88 if err != nil { 89 panic(err) 90 } 91 92 f.Var(&cmd.typ, "t", fmt.Sprintf("Type (%s)", strings.Join(infoTypes, ","))) 93 94 f.BoolVar(&cmd.rescan, "rescan", false, "Rescan all host bus adapters") 95 f.BoolVar(&cmd.refresh, "refresh", false, "Refresh the storage system provider") 96 f.BoolVar(&cmd.rescanvmfs, "rescan-vmfs", false, "Rescan for new VMFSs") 97 f.BoolVar(&cmd.unclaimed, "unclaimed", false, "Only show disks that can be used as new VMFS datastores") 98 } 99 100 func (cmd *info) Description() string { 101 return `Show HOST storage system information. 102 103 Examples: 104 govc find / -type h | xargs -n1 govc host.storage.info -unclaimed -host` 105 } 106 107 func (cmd *info) Process(ctx context.Context) error { 108 if err := cmd.HostSystemFlag.Process(ctx); err != nil { 109 return err 110 } 111 if err := cmd.OutputFlag.Process(ctx); err != nil { 112 return err 113 } 114 return nil 115 } 116 117 func (cmd *info) Run(ctx context.Context, f *flag.FlagSet) error { 118 host, err := cmd.HostSystem() 119 if err != nil { 120 return err 121 } 122 123 ss, err := host.ConfigManager().StorageSystem(ctx) 124 if err != nil { 125 return err 126 } 127 128 if cmd.rescan { 129 err = ss.RescanAllHba(ctx) 130 if err != nil { 131 return err 132 } 133 } 134 135 if cmd.refresh { 136 err = ss.Refresh(ctx) 137 if err != nil { 138 return err 139 } 140 } 141 142 if cmd.rescanvmfs { 143 err = ss.RescanVmfs(ctx) 144 if err != nil { 145 return err 146 } 147 } 148 149 var hss mo.HostStorageSystem 150 err = ss.Properties(ctx, ss.Reference(), nil, &hss) 151 if err != nil { 152 return nil 153 } 154 155 if cmd.unclaimed { 156 ds, err := host.ConfigManager().DatastoreSystem(ctx) 157 if err != nil { 158 return err 159 } 160 161 disks, err := ds.QueryAvailableDisksForVmfs(ctx) 162 if err != nil { 163 return err 164 } 165 166 var luns []types.BaseScsiLun 167 for i := range disks { 168 luns = append(luns, &disks[i]) 169 } 170 hss.StorageDeviceInfo.ScsiLun = luns 171 } 172 173 return cmd.WriteResult(cmd.typ.Result(hss)) 174 } 175 176 type hbaResult mo.HostStorageSystem 177 178 func (r hbaResult) Write(w io.Writer) error { 179 tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) 180 181 fmt.Fprintf(tw, "Device\t") 182 fmt.Fprintf(tw, "PCI\t") 183 fmt.Fprintf(tw, "Driver\t") 184 fmt.Fprintf(tw, "Status\t") 185 fmt.Fprintf(tw, "Model\t") 186 fmt.Fprintf(tw, "\n") 187 188 for _, e := range r.StorageDeviceInfo.HostBusAdapter { 189 hba := e.GetHostHostBusAdapter() 190 191 fmt.Fprintf(tw, "%s\t", hba.Device) 192 fmt.Fprintf(tw, "%s\t", hba.Pci) 193 fmt.Fprintf(tw, "%s\t", hba.Driver) 194 fmt.Fprintf(tw, "%s\t", hba.Status) 195 fmt.Fprintf(tw, "%s\t", hba.Model) 196 fmt.Fprintf(tw, "\n") 197 } 198 199 return tw.Flush() 200 } 201 202 type lunResult mo.HostStorageSystem 203 204 func (r lunResult) Write(w io.Writer) error { 205 tw := tabwriter.NewWriter(w, 2, 0, 2, ' ', 0) 206 207 fmt.Fprintf(tw, "Name\t") 208 fmt.Fprintf(tw, "Type\t") 209 fmt.Fprintf(tw, "Capacity\t") 210 fmt.Fprintf(tw, "Model\t") 211 fmt.Fprintf(tw, "\n") 212 213 for _, e := range r.StorageDeviceInfo.ScsiLun { 214 var tags []string 215 var capacity int64 216 217 lun := e.GetScsiLun() 218 if disk, ok := e.(*types.HostScsiDisk); ok { 219 capacity = int64(disk.Capacity.Block) * int64(disk.Capacity.BlockSize) 220 if disk.LocalDisk != nil && *disk.LocalDisk { 221 tags = append(tags, "local") 222 } 223 if disk.Ssd != nil && *disk.Ssd { 224 tags = append(tags, "ssd") 225 } 226 } 227 228 fmt.Fprintf(tw, "%s\t", lun.DeviceName) 229 fmt.Fprintf(tw, "%s\t", lun.DeviceType) 230 231 if capacity == 0 { 232 fmt.Fprintf(tw, "-\t") 233 } else { 234 fmt.Fprintf(tw, "%s\t", units.ByteSize(capacity)) 235 } 236 237 fmt.Fprintf(tw, "%s", lun.Model) 238 if len(tags) > 0 { 239 fmt.Fprintf(tw, " (%s)", strings.Join(tags, ",")) 240 } 241 fmt.Fprintf(tw, "\n") 242 } 243 244 return tw.Flush() 245 }