github.com/vmware/govmomi@v0.51.0/cli/datastore/download.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 datastore 6 7 import ( 8 "context" 9 "errors" 10 "flag" 11 "fmt" 12 "io" 13 "os" 14 "path" 15 16 "github.com/vmware/govmomi/cli" 17 "github.com/vmware/govmomi/cli/flags" 18 "github.com/vmware/govmomi/object" 19 "github.com/vmware/govmomi/ovf" 20 "github.com/vmware/govmomi/vim25/soap" 21 "github.com/vmware/govmomi/vmdk" 22 ) 23 24 type download struct { 25 *flags.DatastoreFlag 26 *flags.HostSystemFlag 27 } 28 29 func init() { 30 cli.Register("datastore.download", &download{}) 31 } 32 33 func (cmd *download) Register(ctx context.Context, f *flag.FlagSet) { 34 cmd.DatastoreFlag, ctx = flags.NewDatastoreFlag(ctx) 35 cmd.DatastoreFlag.Register(ctx, f) 36 37 cmd.HostSystemFlag, ctx = flags.NewHostSystemFlag(ctx) 38 cmd.HostSystemFlag.Register(ctx, f) 39 } 40 41 func (cmd *download) Process(ctx context.Context) error { 42 if err := cmd.DatastoreFlag.Process(ctx); err != nil { 43 return err 44 } 45 if err := cmd.HostSystemFlag.Process(ctx); err != nil { 46 return err 47 } 48 return nil 49 } 50 51 func (cmd *download) Usage() string { 52 return "SOURCE DEST" 53 } 54 55 func (cmd *download) Description() string { 56 return `Copy SOURCE from DS to DEST on the local system. 57 58 If DEST name is "-", source is written to stdout. 59 60 Examples: 61 govc datastore.download vm-name/vmware.log ./local.log 62 govc datastore.download vm-name/vmware.log - | grep -i error 63 govc datastore.download -json vm-name/vm-name.vmdk - | jq .ddb 64 ovf=$(govc library.info -l -L vmservice/photon-5.0/*.ovf) 65 govc datastore.download -json "$ovf" - | jq -r .diskSection.disk[].capacity` 66 } 67 68 func (cmd *download) Run(ctx context.Context, f *flag.FlagSet) error { 69 args := f.Args() 70 if len(args) != 2 { 71 return errors.New("invalid arguments") 72 } 73 74 src := args[0] 75 dst := args[1] 76 77 var dp object.DatastorePath 78 if dp.FromString(src) { 79 // e.g. `govc library.info -l -L ...` 80 cmd.DatastoreFlag.Name = dp.Datastore 81 src = dp.Path 82 } 83 84 ds, err := cmd.Datastore() 85 if err != nil { 86 return err 87 } 88 89 h, err := cmd.HostSystemIfSpecified() 90 if err != nil { 91 return err 92 } 93 94 var via string 95 96 if h != nil { 97 via = fmt.Sprintf(" via %s", h.InventoryPath) 98 ctx = ds.HostContext(ctx, h) 99 } 100 101 p := soap.DefaultDownload 102 103 if dst == "-" { 104 f, _, err := ds.Download(ctx, src, &p) 105 if err != nil { 106 return err 107 } 108 109 if cmd.DatastoreFlag.All() { 110 switch path.Ext(src) { 111 case ".vmdk": 112 data, err := vmdk.ParseDescriptor(f) 113 if err != nil { 114 return err 115 } 116 return cmd.DatastoreFlag.WriteResult(data) 117 case ".ovf": 118 data, err := ovf.Unmarshal(f) 119 if err != nil { 120 return err 121 } 122 return cmd.DatastoreFlag.WriteResult(data) 123 } 124 } 125 126 _, err = io.Copy(os.Stdout, f) 127 return err 128 } 129 130 if cmd.DatastoreFlag.OutputFlag.TTY { 131 logger := cmd.DatastoreFlag.ProgressLogger(fmt.Sprintf("Downloading%s... ", via)) 132 p.Progress = logger 133 defer logger.Wait() 134 } 135 136 return ds.DownloadFile(ctx, src, dst, &p) 137 }