github.com/vmware/govmomi@v0.37.1/govc/volume/ls.go (about) 1 /* 2 Copyright (c) 2020-2023 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 volume 18 19 import ( 20 "context" 21 "flag" 22 "fmt" 23 "io" 24 "log" 25 "text/tabwriter" 26 27 "github.com/vmware/govmomi/cns/types" 28 "github.com/vmware/govmomi/govc/cli" 29 "github.com/vmware/govmomi/govc/flags" 30 "github.com/vmware/govmomi/units" 31 vim "github.com/vmware/govmomi/vim25/types" 32 ) 33 34 type ls struct { 35 *flags.ClientFlag 36 *flags.DatastoreFlag 37 *flags.OutputFlag 38 39 types.CnsQueryFilter 40 41 long bool 42 id bool 43 disk bool 44 } 45 46 func init() { 47 cli.Register("volume.ls", &ls{}) 48 } 49 50 func (cmd *ls) Register(ctx context.Context, f *flag.FlagSet) { 51 cmd.ClientFlag, ctx = flags.NewClientFlag(ctx) 52 cmd.ClientFlag.Register(ctx, f) 53 54 cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) 55 cmd.DatastoreFlag.Register(ctx, f) 56 57 cmd.OutputFlag, ctx = flags.NewOutputFlag(ctx) 58 cmd.OutputFlag.Register(ctx, f) 59 60 f.BoolVar(&cmd.long, "l", false, "Long listing format") 61 f.BoolVar(&cmd.id, "i", false, "List volume ID only") 62 f.BoolVar(&cmd.disk, "L", false, "List volume disk or file backing ID only") 63 } 64 65 func (cmd *ls) Process(ctx context.Context) error { 66 if err := cmd.ClientFlag.Process(ctx); err != nil { 67 return err 68 } 69 if err := cmd.DatastoreFlag.Process(ctx); err != nil { 70 return err 71 } 72 return cmd.OutputFlag.Process(ctx) 73 } 74 75 func (cmd *ls) Usage() string { 76 return "[ID...]" 77 } 78 79 func (cmd *ls) Description() string { 80 return `List CNS volumes. 81 82 Examples: 83 govc volume.ls 84 govc volume.ls -l 85 govc volume.ls -ds vsanDatastore 86 govc volume.ls df86393b-5ae0-4fca-87d0-b692dbc67d45 87 govc disk.ls -l $(govc volume.ls -L pvc-9744a4ff-07f4-43c4-b8ed-48ea7a528734)` 88 } 89 90 type lsWriter struct { 91 Volume []types.CnsVolume `json:"volume"` 92 cmd *ls 93 } 94 95 func (r *lsWriter) Write(w io.Writer) error { 96 if r.cmd.id { 97 for _, volume := range r.Volume { 98 fmt.Fprintln(r.cmd.Out, volume.VolumeId.Id) 99 } 100 return nil 101 } 102 103 if r.cmd.disk { 104 for _, volume := range r.Volume { 105 var id string 106 switch backing := volume.BackingObjectDetails.(type) { 107 case *types.CnsBlockBackingDetails: 108 id = backing.BackingDiskId 109 case *types.CnsFileBackingDetails: 110 id = backing.BackingFileId 111 case *types.CnsVsanFileShareBackingDetails: 112 id = backing.Name 113 default: 114 log.Printf("%s unknown backing type: %T", volume.VolumeId.Id, backing) 115 } 116 fmt.Fprintln(r.cmd.Out, id) 117 118 } 119 return nil 120 } 121 122 tw := tabwriter.NewWriter(r.cmd.Out, 2, 0, 2, ' ', 0) 123 124 for _, volume := range r.Volume { 125 fmt.Printf("%s\t%s", volume.VolumeId.Id, volume.Name) 126 if r.cmd.long { 127 capacity := volume.BackingObjectDetails.GetCnsBackingObjectDetails().CapacityInMb 128 c := volume.Metadata.ContainerCluster 129 fmt.Printf("\t%s\t%s\t%s", units.ByteSize(capacity*1024*1024), c.ClusterType, c.ClusterId) 130 } 131 fmt.Println() 132 } 133 134 return tw.Flush() 135 } 136 137 func (cmd *ls) Run(ctx context.Context, f *flag.FlagSet) error { 138 ds, err := cmd.DatastoreIfSpecified() 139 if err != nil { 140 return err 141 } 142 143 if ds != nil { 144 cmd.Datastores = []vim.ManagedObjectReference{ds.Reference()} 145 } 146 147 c, err := cmd.CnsClient() 148 if err != nil { 149 return err 150 } 151 152 for _, arg := range f.Args() { 153 cmd.VolumeIds = append(cmd.VolumeIds, types.CnsVolumeId{Id: arg}) 154 } 155 156 var volumes []types.CnsVolume 157 158 for { 159 res, err := c.QueryVolume(ctx, cmd.CnsQueryFilter) 160 if err != nil { 161 return err 162 } 163 164 volumes = append(volumes, res.Volumes...) 165 166 if res.Cursor.Offset == res.Cursor.TotalRecords || len(res.Volumes) == 0 { 167 break 168 } 169 170 cmd.Cursor = &res.Cursor 171 } 172 173 return cmd.WriteResult(&lsWriter{volumes, cmd}) 174 }